():::1.对Knn原理的理解:
存在一组已知标签的数据集(训练集),将没有标签的数据输入,将新数据的每个特征与训练集中的数据进行比较,比较的原则是使用简单的欧氏距离。然后选出距离最短的前K个数据(K一般不大于20),在这K个数据中,出现频次最多的标签就是该输入数据的分类。
2.实际操作
a.在操作数据之前首先把数据中的特征进行归一化,否则特征之前数据值差异太大会影响最终的欧氏距离,从而最终影响分类结果。
特征归一化的值:newValue=(oldValue-min)/(max-min)
其中:oldValue是这个特征值原来的数值,max和min分别对应这个特征在数据集中的最大值和最小值。
b.算法具体过程:
归一化特征;
计算距离;
距离排序;
选出距离最小的前K个;
计算这K个特征中每个标签出现的频次;
返回频次最高的标签;
3.可以复用的代码
a).Knn分类器:
def classify0(inX,dataSet,labels,k):
dataSetSize=dataSet.shape[0]
diffMat=np.tile(inX,(dataSetSize,1))-dataSet
sqDiffMat=diffMat**2
print sqDiffMat
sqDistances=sqDiffMat.sum(axis=1)
print sqDistances
distances=sqDistances**0.5
sortedDistIndicies=distances.argsort()
classCount={}
for i in range(k):
voteIlabel=labels[sortedDistIndicies[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#read the value of the key in dict
sortedClassCount=sorted(classCount.iteritems(),
key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]#return the most frequenst one
b).解析文本数据(读取文件中的数据到矩阵中)
def file2matrix(filename):
fr=open(filename)
arrayOfLines=fr.readlines()#read the context of each line
numberOfLines=len(arrayOfLines)
returnMat=np.zeros((numberOfLines,3))
classLabelVector=[]
index=0
for line in arrayOfLines:
line=line.strip()#remove the space at the start(end) of each line
listFromLine=line.split('\t')#remove th '\t',make it to []
returnMat[index,:]=listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index +=1
return returnMat,classLabelVector
c).归一化特征
def autoNorm(dataSet):
minVals=dataSet.min(0)
maxVals=dataSet.max(0)
ranges=maxVals-minVals
normDataSet=np.zeros(np.shape(dataSet))
m=dataSet.shape[0]#row
normDataSet=dataSet-np.tile(minVals,(m,1))
normDataSet=normDataSet/np.tile(ranges,(m,1))
return normDataSet,ranges,minVals
总结:千里之行,始于足下