机器学习实战-改进约会网站的配对(knn算法)
(0)knn算法
from numpy import * import operator def classify0(intx,dataset,labels,k): dataSetSize=dataset.shape[0] #ndarray.shape 数组的维度,对于矩阵,n行m列 diffMat=tile(intx,(dataSetSize,1))-dataset #tile(A,(a,b))对于矩阵A在行方向上重复a次,列方向上重复b次 sqDiffMat=diffMat**2 #对每一个维度进行平方 sqDistances=sqDiffMat.sum(axis=1) #np.sum(a, axis=0)的含义是a[0][j],a[1][j],a[2][j](j=0,1,2,3)对应行项相加的结果 distances=sqDistances**0.5 #np.sum(a, axis=1)的含义是a[i][0],a[i][1],a[i][2],a[i][3](i=0,1,2)对应列项相加的结果 sortedDistIndicies=distances.argsort() #numpy.argsort() 函数返回的是数组值从小到大的索引值,索引值从0开始 classCount = {} #print(type(classCount)) for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 排序 #如果items()替换为iteritems()则会报错 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]
(1)收集数据:收集文本信息
(2)准备数据:解析文本文件内容,将其信息矩阵化、向量化
from numpy import * import operator def file2matrix(filename): labels = {'didntLike': 1, 'smallDoses': 2, 'largeDoses': 3} fr=open(filename) #打开文件 arrayOLines=fr.readlines() #读取文件所有行 numberOfLines=len(arrayOLines) #计算文件行数 returnMat=zeros((numberOfLines,3)) #为numberoflines行,3列的矩阵填充0元素 classLabelVector=[] #创建标记向量 index=0 for line in arrayOLines: #获取每一行的文本信息 line=line.strip() #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。 listFromLine=line.split('\t')#以\t对字符串进行切片 returnMat[index,:]=listFromLine[0:3] #取每一行的前三个元素放到列表(矩阵)内 classLabelVector.append(labels[listFromLine[-1]])#向classlabel内添加标记,并用自字典返回键值对的值,标记在每一行最后一个 index+=1 #取下一行 return returnMat,classLabelVector
(3)分析数据:使用matplotlib画二维扩散图
import knn from numpy import * import matplotlib import matplotlib.pyplot as plt datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt') fig=plt.figure() #创建自定义图像 ax=fig.add_subplot(111) #add_subplot可以为figure新增111个划分子图 #print(datingLabels) #print(type(datingLabels)) #print(type(datingDataMat)) ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels)) #标记数据点的属性类别 plt.show()
(4)数据处理:使用归一化,处理不同取值范围的特征值,将取值范围处理到0到1或-1到1
import knn from numpy import * def autoNorm(dataset): # print(a.min()) # 无参,所有中的最小值 # print(a.min(0)) # axis=0; 每列的最小值 # print(a.min(1)) # axis=1;每行的最小值 minvals=dataset.min(0) #每一属性下的最小值元素,共3列,3*1 maxvals=dataset.max(0) #每一属性下的最大值元素 tmprange=maxvals-minvals normDataSet=zeros(shape(dataset))#shape()计算数组的维度n行m列,以0元素填充n行m列的矩阵 m=dataset.shape[0] #计算行数;nuarray.shape[0]代表行数,nuarray.shape[1]代表列数 normDataSet=dataset-tile(minvals,(m,1)) #复制minvals向量m行1列 normDataSet=normDataSet/tile(tmprange,(m,1))#复制tmprange向量m行1列,归一化 return normDataSet,tmprange,minvals
(5)测试算法:根据测试样本计算算法性能
import knn import dataProcessing import knnAlgorithm from numpy import * datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt') normalMat,tmprange,minvals=dataProcessing.autoNorm(datingDataMat) def datingClassTest(): ratio=0.10 #测试样本占整体样本的比例 m=normalMat.shape[0]#计算整体样本的行数 numTestVecs=int(m*ratio)#计算测试样本 print(numTestVecs) errorcount=0 for i in range(numTestVecs): classifierResult=knnAlgorithm.classify0(normalMat[i,:],normalMat[numTestVecs:m,:],datingLabels[numTestVecs:m],4) #print("xx") str='the classifier came back with: '+repr(classifierResult)+",the real answer is :"+repr(datingLabels[i]) print(str) if(classifierResult!=datingLabels[i]): #获取算法性能 errorcount+=1.0 errorRate=errorcount/numTestVecs print(errorRate) datingClassTest()
(6)预测样本
import knn import dataProcessing import knnAlgorithm from numpy import * import operator datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt') normalMat,tmprange,minvals=dataProcessing.autoNorm(datingDataMat) def classifyPerson(): resultList=["不感兴趣","有一点兴趣","有极大兴趣"] percentFilms=float(input("玩游戏的时间占比")) ffmiles=float(input("你每年飞多少里程")) icecream=float(input("吃冰淇淋的数量")) inarray=array([ffmiles,percentFilms,icecream]) inarray=(inarray-minvals)/tmprange classifierResult=knnAlgorithm.classify0(inarray,datingDataMat,datingLabels,4) print(classifierResult) print("对你"+resultList[classifierResult-1]) classifyPerson()
浙公网安备 33010602011771号