自定义实现
from numpy import * def createDataSet(): # 构造训练集 group = array([[90, 100], [88, 90], [85, 95], [10, 20], [30, 40], [50, 30]]) # 样本点数据 labels = ['A', 'A', 'A', 'D', 'D', 'D'] return group, labels def KNNClassify(newInput, dataSet, labels, k): # 记录训练集个数 nums = dataSet.shape[0] # 计算欧氏距离 diff = tile(newInput, (nums, 1)) - dataSet # 计算元素属性值得差 squaredDiff = diff ** 2 # 对差值取平方 squaredDist = sum(squaredDiff, axis=1) # 按行求和 distance = squaredDist ** 0.5 # 计算距离 # 对距离进行排序(升序) sortedDistIndices = argsort(distance) classCount = {} for i in range(k): # 选择k个最短距离 voteLabel = labels[sortedDistIndices[i]] # 记录累计的出现次数 classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 投票数最多的分类 maxCount = 0 maxIndex = 0 for key, value in classCount.items(): if value > maxCount: maxCount = value maxIndex = key return maxIndex # 创建训练集和样本点 dataSet, labels = createDataSet() # 测试集1 testX = array([15, 50]) k = 3 outputLabel = KNNClassify(testX, dataSet, labels, k) print("第一组测试数据为:", testX, ",分类结果为:", outputLabel) # 测试集2 testX = array([80, 70]) k = 3 outputLabel = KNNClassify(testX, dataSet, labels, k) print("第二组测试数据为:", testX, ",分类结果为:", outputLabel)
利用Sklearn库实现
from sklearn import neighbors, datasets # 初始化K近邻分类器 knn = neighbors.KNeighborsClassifier() # 加载数据集 iris = datasets.load_iris() print(iris) # 讲训练数据集和标签种类进行归类学习 knn.fit(iris.data, iris.target) # 测试样本预测 predictedLabel = knn.predict([[0.1, 0.2, 0.3, 0.4]]) print(predictedLabel)
引入邻居权值
为了优化KNN的分类效果,可以在其中引入权值机制作为对样本距离机制的补充。
基本思想是:为与测试样本距离更小的邻居设置更大的权值,衡量权值累积以及训练样本集中各种分类的样本数目,来对算法中的K值进行调整,进而达到更合理或者平滑的分类效果。
特征降维与模式融合
KNN算法的主要缺点是,当训练样本数量很大时将导致很高的计算开销。
为了对KNN的分类效率进行优化,可以在数据预处理阶段利用一些降维算法或者使用特征融合算法,对KNN训练样本集的维度进行简化,排除对分类结果影响较小的属性。通过优化训练样本集的分类,提高得出待分类样本类别的效率。该改进经常在类域的样本容量比较大时使用。