机器学习-分类算法-kNN
机器学习-分类算法-kNN
kNN(k-Nearest Neighbor)算法:一种基于向量间相似度的分类算法。
kNN原理
k最近邻(k-Nearest Neighbor)算法是比较简单的机器学习算法。它采用测量不同特征之间的距离方法进行分类。
如果一个样本在特征空间中的k个最近邻(最相似)的样本中的大多数都属于一个类别,则该样本也属于这个类别。k表示外部定义的近邻数量。
实现步骤
第一阶段:确定k值(就是指最近邻居的个数)。一般是奇数个
第二阶段:确定距离度量公式。文本分类一般使用夹角余弦,得出待分类数据点和所有已知类别的样本点,从中选择距离最近的k个样本。
夹角余弦:cos = AB/|A||B|
第三阶段:统计这k个样本点中各个类别的数量。根据k个样本中数量最多的样本是什么类别,我们就把这个数据点定为什么类别。
实现代码1(训练集为一组事件发生概率,测试集为事件发生概率,求类型)
from numpy import * import operator # 夹角余弦距离公式 def consdist(vector1, vector2): print("vecotr1:",vector1) print("vector2:",vector2) result = dot(vector1, vector2) / (linalg.norm(vector1) * linalg.norm(vector2)) print("result:", result) return result # KNN分类器 # testData:测试集 trainSet:训练集 listClasses:类别标签 k:k个邻居 def classify(testData, trainSet, listClasses, k): dataSetSize = trainSet.shape[0] # 返回样本的行数 distances = array(zeros(dataSetSize)) print("dataSetSize:", dataSetSize) for indx in range(dataSetSize): # 计算测试集和训练集之间的距离:余弦夹角 distances[indx] = consdist(testData, trainSet[indx]) # 根据生成的余弦夹角按从大到小排序,结果为索引号 sortedDistIndics = argsort(-distances) classCount = {} for i in range(k): # 获得角度最小的前K项作为参考项 # 按排序顺序返回样本集对应的类别标签 voteIlabel = listClasses[sortedDistIndics[i]] # 为字典classCount赋值,相同key,其中value加1 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 获得voteIlabel的value值,没有则默认为0 # 对分类字典classCount按value重新排序 # sorted(data.items(), key = operator.itemgetter(1), reverse = True) # 该句是按字典排序的固定用法 # classCount.items() # 字典迭代器函数 # key:排序参数 operator.itemgetter(1):多级排序 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] # 返回序最高的一项 dataArr = np.array([[0.238, 0, 0.1905, 0.1905, 0.1905, 0.1905], [0, 0.177, 0, 0.294, 0.235, 0.294], [0.2, 0.16, 0.12, 0.12, 0.2, 0.2]]) dataMat = mat(dataArr) print("dataMat:", dataMat.shape) print("dataMat type:", type(dataMat)) testSet = [0.2174, 0.2174, 0.1304, 0, 0.2174, 0.2174] testMat = mat(testSet) classLabel = [0, 1, 2] k = 3 print("result:",classify(testSet, dataArr, classLabel, k))
实现代码2(文本测试)
# K近邻分类 from numpy import * import numpy as np import operator from com.machineLearning.Bayes.NBayes import NBayes def loadDataSet(): # 训练集文本 postingList = [ ['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'], ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him', 'my'], ['stop', 'posting', 'stupid', 'worthless', 'garbage'], ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'], ['quit', 'buying', 'worthless', 'dog', 'food', 'stopid'] ] # 每个文本对应的分类 classVec = [0, 1, 0, 1, 0, 1] return postingList, classVec # 夹角余弦距离公式 def consdist(vector1, vector2): return dot(vector1, vector2) / (linalg.norm(vector1) * linalg.norm(vector2)) # KNN分类器 # testData:测试集 trainSet:训练集 listClasses:类别标签 k:k个邻居 def classify(testData, trainSet, listClasses, k): dataSetSize = trainSet.shape[0] # 返回样本的行数 distances = array(zeros(dataSetSize)) for indx in range(dataSetSize): # 计算测试集和训练集之间的距离:余弦夹角 distances[indx] = consdist(testData, trainSet[indx]) # 根据生成的余弦夹角按从大到小排序,结果为索引号 sortedDistIndics = argsort(-distances) classCount = {} for i in range(k): # 获得角度最小的前K项作为参考项 # 按排序顺序返回样本集对应的类别标签 voteIlabel = listClasses[sortedDistIndics[i]] # 为字典classCount赋值,相同key,其中value加1 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 获得voteIlabel的value值,没有则默认为0 # 对分类字典classCount按value重新排序 # sorted(data.items(), key = operator.itemgetter(1), reverse = True) # 该句是按字典排序的固定用法 # classCount.items() # 字典迭代器函数 # key:排序参数 operator.itemgetter(1):多级排序 sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] # 返回序最高的一项 # 使用KNN算法实现文本分类 k = 3 dataSet, lisClasses = loadDataSet() nb = NBayes() nb.train_set(dataSet, lisClasses) # 使用之前的贝叶斯分类阶段的数据集及生成的TF向量进行分类 print(classify(nb.tf[3], nb.tf, lisClasses, k))
NBayes看上一篇。