参考教程:https://github.com/apachecn/AiLearning/ 讲解的很详细。
下面只是我本人在学习期间学习的代码(参考了部分上述教程)
KNN
原理用一句话总结就是:当预测一个样本其label时,根据距离它最近的K个点的label来决定,如何决定呢:这K个点属于哪一个label最多,那这个被预测的样本就属于哪一类。
所以其实就两个要素:1.K值 2.距离度量
- K值的选择:可以用交叉验证的方法确定
- 距离度量的选择:欧式距离、曼哈顿距离等等
KNN是很简单的一种方法,但需要和K-means算法区分:
前者是分类算法(有监督),后者是聚类算法(无监督),但都是基于距离的度量方式。
下面是python实现的knn代码:
(数据集在上面的参考教程中提供了)
import os
import numpy as np
import operator
def to1024(str):
fr=open(str,'r')
vector=np.zeros((1,1024))
for i in range(32):
linstr=fr.readline()
for j in range(32):
vector[0,32*i+j]=int(linstr[j])
return vector
def prepareData(str):
trainingFileList=os.listdir(str+'trainingDigits')
#训练集数据介绍:
#是由一个个0 1组成的txt文件,可以看成是像素,文件名包含由_连接,_前面的表示
#文件对应的label,后面的表示序号
# 现在,需要处理训练集数据得到两个矩阵:trainData,trainLabel
total_train_num=len(trainingFileList)
trainData=np.zeros((total_train_num,1024))
trainLabel=[]
inx=0
for i in trainingFileList:
name, _ = i.split('.')
label, index = name.split('_')
trainLabel.append(label)
trainData[inx]=to1024(str+'trainingDigits/'+i)
inx=inx+1
#print(np.array(trainLabel))
########以上得到了trainData和trainLabel
#接下来读取测试集
testFileList=os.listdir(str+'testDigits')
total_test_num=len(testFileList)
testData=np.zeros((total_test_num,1024))
#print(total_test_num)
testLabel=[]
inx=0
for i in testFileList:
name, _ = i.split('.')
label, index = name.split('_')
testLabel.append(label)
testData[inx]=to1024(str+'testDigits/'+i)
inx=inx+1
return trainData,trainLabel,testData,testLabel
def distance(v1,v2):
res=0
dis=v1-v2
dis=dis**2
dis_=np.sum(dis)
return dis_**0.5
def knn_classifaction(trainData,trainLabel,testData,k):
result=np.zeros((1,1024))
##计算测试样本和训练样本的距离,选取其K个最近的样本的标签的最多的作为其标签
test_num=testData.shape[0]
dis=np.zeros((test_num,trainData.shape[0]))
#dis的(i,j)位置记录的是test_data的第i个样本与trainData的第j个样本的距离
#即第i行记录了第i个测试样本与其他训练样本的距离
predictions=np.zeros(test_num)
for i in range(test_num):
#1.计算距离矩阵
for j in range(trainData.shape[0]):
dis[i,j]=distance(trainData[j],testData[i])
s=np.argsort(dis[i])#s中存放按距离排序的索引
#2.选取k个最近的样本
classcount={}
for j in range(k):
#找到最近的k个样本的类别
nlabel=trainLabel[s[j]]
classcount[nlabel]=classcount.get(nlabel,0)+1
sortedClassCount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)
predictions[i]=sortedClassCount[0][0]
# s=np.sort(dis,axis=1)
return predictions
if __name__=='__main__':
trainData,trainLabel,testData,testLabel=prepareData('data/机器学习/2.KNN/')
result=knn_classifaction(trainData,trainLabel,testData,3)
testLabel_=np.array(testLabel)
testLabel_=testLabel_.astype(np.int)
curr=(testLabel_==result).sum()
acc=curr/testLabel_.shape[0]*100
print("{}%".format(acc))