#coding=utf-8 from numpy import * import operator from os import listdir import matplotlib import matplotlib.pyplot as plt #从文件当中读取内容,保存到矩阵当中 #因为文件当中有两部分内容,一部分是三个原因,另一部分是结果 def file2matrix(filename): fr=open(filename) numberOfLines=len(fr.readlines())#计算文件的行数 returnMat=zeros((numberOfLines,3))#生成一个零矩阵 classLabelVector=[]#生成一个序列,主要操作是切片 fr=open(filename) index=0 for line in fr.readlines(): line=line.strip()#读取一行的内容 listFromLine=line.split(' ')#将line分割成3个列 returnMat[index,:]=listFromLine[0:3]#取前三个到切片放到第index行 classLabelVector.append(int(listFromLine[-1]))#取最后一个追加到classLabelVector index+=1#index自加 return returnMat,classLabelVector #归一化数据 def autoNorm(dataSet): #获取每一列的最小值,也就是说结果是一个3维的数组,数组的元素 #是每一列到最小值 #如果0改为1,那么获取到的是每一行的最小值,也就是一个数组 minVals=dataSet.min(0) maxVals=dataSet.max(0)#获取每一列的最大值 ranges=maxVals-minVals normDataSet=zeros(shape(dataSet))#生成一个零矩阵 #shape,显示一个矩阵的行列,如果没有[0],那么输出 #(1000,3)也就是1000行,3列, # [0]表示第一个元素(行),[1]表示第二个元素(列) m=dataSet.shape[0]#获取行的行的数然后复制给m #tile是一个复制函数,将minVals复制 #行的方向上复制m次你,列的方向上复制1次 normDataSet=dataSet-tile(minVals,(m,1)) normDataSet=normDataSet/tile(ranges,(m,1)) return normDataSet,ranges,minVals #绘图 def draw(): fig=plt.figure() ax=fig.add_subplot(111) datingDataMat,datingLabels= file2matrix('datingTestSet.txt') ax.scatter(datingDataMat[:,0],datingDataMat[:,1], 15.0*array(datingLabels),15.0*array(datingLabels)) plt.show() #分类 def classify0(inX, dataSet, labels, k): #获取到dataSet的行数量 dataSetSize = dataSet.shape[0] diffMat = tile(inX, (dataSetSize,1)) - dataSet sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances**0.5 #排序,但是矩阵并不修改,只是获取到修改后的下标 sortedDistIndicies = distances.argsort() classCount={} for i in range(k): #获取到分类 voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] #识别过程 def datingClassTest(): hoRatio=0.10 #从文件当中读取txt文件,转化为矩阵 datingDataMat,datingLabels=file2matrix('datingTestSet.txt') normMat,ranges,minVals=autoNorm(datingDataMat) m=normMat.shape[0] numTestVecs=int(m*hoRatio) errorCount=0.0 #从1到100 for i in range(numTestVecs): #第一个参数是待分类到矩阵 #normMat[i,:]代表一个行,也就是矩阵的第i行的一位矩阵 #normMat[numTestVecs:m,:]使用从100到1000行的矩阵去分类 #datingLabels[numTestVecs:m]使用从100到1000行的结果去分类 #3代表kNN当中的k classfierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:], datingLabels[numTestVecs:m],3) print "机器人认为的结果是%d,正确的答案是:%d"%(classfierResult,datingLabels[i]) if(classfierResult!=datingLabels[i]): errorCount+=1.0 print "错误律是:%f" %(errorCount/float(numTestVecs)) datingClassTest() """ 最初错误原因 dataSet=file2matrix('datingTestSet.txt') print dataSet#有两个返回值,会把后一个返回值追加到dataSet上面,构成元祖 print "*****************************" datingDataMat,datingLabels=file2matrix('datingTestSet.txt') print datingDataMat print "*****************************" print datingLabels """