KNN算法
knn算法的原生实现
knn算法的一般步骤:
其中测试分类classfy0()函数是算法的核心,需默背下来,并且能够运用到其他的数据集上。
classify0函数流程图
注意classfy0()函数中一些语句的用法:
distance.argsort() : 将distance元素从大到小顺序的下标返回
classcount.get(votelabel, 0) + 1 :classcount字典中如果没有votelabel则字典classCount中生成voteIlabel元素,并使其对应的数字为0,然后加1;如果有votelabe,取出值对应值,然后加1(0不起作用)
sorted(classcount.items(), key=operator.itemgetter(1), reverse=True): 其中.items将字典分解为元祖列表;operator.itemgetter(1)按位置为1的元素进行排序;reverse=True从大到小排序
classfy0()代码如下:(knn完整算法请见前期的博客)
def classify0(inx, dataset, labels, k): # inX是你要输入的要分类的“坐标”,dataSet是上面createDataSet的array,
# 就是已经有的,分类过的坐标,label是相应分类的标签,k是KNN,k近邻里面的k
datasetsize = dataset.shape[0] # dataSetSize是dataSet的行数,用上面的举例就是4行
# .min(0) 读取每行最小值.max(0) .shape[0]计算行数 .min(1) 读取每列最小值.max(1) .shape[1]计算列数
diffmat = tile(inx, (datasetsize, 1)) - dataset # 前面用tile,把一行inX变成4行一模一样的(tile有重复的功能,
# dataSetSize是重复4遍,后面的1保证重复完了是4行,而不是一行里有四个一样的),
# 然后再减去dataSet,是为了求两点的距离,先要坐标相减,这个就是坐标相减
sqdiffmat = diffmat ** 2
sqdistances = sqdiffmat.sum(axis=1) # axis=1是行相加,这样得到了(x1-x2)^2+(y1-y2)^2
distance = sqdistances ** 0.5 # 这样求出来就是欧式距离
sorteddistanceindicies = distance.argsort() # argsort是排序,将元素按照由小到大的顺序返回下标,比如([3,1,2]),它返回的就是([1,2,0])
classcount = {
}
for i in range(k):
votelabel = labels[sorteddistanceindicies[i]]
classcount[votelabel] = classcount.get(votelabel, 0) + 1 # 求每个类别的个数,有‘A’就让'A'的计数加1
sortclass = sorted(classcount.items(), key=operator.itemgetter(1),
reverse=True) # classCount.items()将classCount字典分解为元组列表 ,operator.itemgetter(1)按照第二个元素的次序对元组进行排序,reverse=True是逆序,即按照从大到小的顺序排列
return sortclass[0][0] # 第一个就是最大的,返回最大的类别就是预测的类别
Knn算法的sklearn实现:
默背模块导入函数:
from sklearn.neighbors import KNeighborsClassifier as KNN:导入KNN模块;KNN.fit(train_x,train_y)训练数据、标签学习,KNN.predict(数据):进行预测
from sklearn.preprocessing import Label