from numpy import *
import operator
def classify0(inX,dataSet,labels,k):#inX是输入向量,dataSet为训练样本集,labels为标签向量,k为最近邻的数目.假设dataSet为4*2,inX为1*2
#距离计算
dataSetSize=dataSet.shape[0]#行数4
diffMat=tile(inX,(dataSetSize,1))-dataSet#tile扩展后为4*2,坐标相减
sqDiffMat=diffMat**2#平方
sqDistances=sqDiffMat.sum(axis=1)#对于2维数组,axis=1为轴1(行方向),即将每行相加求和,把列数变为1.得到4*1数组,每个代表两点间距离的平方
distances=sqDistances**0.5#将距离的平方开方得到距离
#选择距离最小的k个点
sortedDistIndicies=distances.argsort()#将距离从小到大排序
classCount={ }
for i in range(k):#选取前k个,计算标签类别频率
voteIlabel=labels[sortedDistIndicies[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#计算频次
#类别排序,降序排列,返回最高频次对应的类别
sortedClassCount=sorted(classCount.items( ),key=operator.itemgetter(1),reverse=True)#对频次排序
return sortedClassCount[0][0]
#将文本记录转化为NumPy的解析程序
def file2matrix(filename):
fr = open(filename)#打开文件,获得文件对象
arrayOLines=fr.readlines()
numberOfLines = len(arrayOLines) #获得行数,假设为1000行
returnMat = zeros((numberOfLines,3)) #零填充矩阵,二维数组,1000*3
classLabelVector = []#存储标签(3,2,1)。代表喜欢,一般,不喜欢.结果为1000个元素的一维数组
index = 0
for line in arrayOLines:#遍历每一行
line = line.strip()#去除每一行的回车键
listFromLine = line.split('\t')#以制表格分割本行的数据,转化为列表
returnMat[index, :] = listFromLine[0:3]#选取前三个元素存储到特征矩阵中,index代表特征矩阵行数
classLabelVector.append(int(listFromLine[-1]))#每行最后一个转化为整数类型作为标签存储到列表
index += 1#行数递增
return returnMat,classLabelVector
#归一化数值
def autoNorm(dataSet):#假设为1000*3
minVals = dataSet.min(0)#0代表找每一列最小值组成数组,1代表找每一行最小值.结果为1*3
maxVals = dataSet.max(0)
ranges = maxVals - minVals#范围数组,1*3
normDataSet = zeros(shape(dataSet))#零填充的1000*3数组
m = dataSet.shape[0]#shape[0]返回行数,即第一维度的长度1000
normDataSet = dataSet - tile(minVals, (m,1))#特征值相减。tile进行扩展或者叫复制,行数变为1000,列数为1
normDataSet = normDataSet/tile(ranges, (m,1))#特征值相除。tile形成1000*3数组
return normDataSet, ranges, minVals
#进行分类器测试
def datingClassTest():
hoRatio = 0.10 #测试率
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)#要测试的行数
errorCount = 0.0
for i in range(numTestVecs):#进行测试
#前numTestVecs个用于测试,后面的用作样本集
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
print ("the classifier came back with: %d, the real answer is: %d" %(classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]):
errorCount += 1.0#预测不一致则错误数加1
print ("the total error rate is: %.2f" %(errorCount/float(numTestVecs)))
注释很清晰,不再赘述