《机器学习实战》第二章k-近邻算法代码分析
2018-07-26 20:41
197 查看
本文对《机器学习实战》中k-近邻算法的实现代码进行分析。k-近邻算法在此不再做过多的说明,可以参考下面这篇文章https://blog.csdn.net/lzalgorithm/article/details/81081418
接下来,我们就正式开始对代码进行分析解读。
首先,导入科学计算包Numpy和运算符模块,并定义creatDataSet()函数来创建数据集和标签
[code]from numpy import * import operator def creatDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) #训练集数据 labels = ['A','A','B','B'] #对应的标签 return group,labels
接下来我们实现kNN算法,这里先给出kNN算法实现的伪代码,便于大家理解
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定前k个点所在类别的出现频率 ;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
[code]def classify0(inX,dataSet,labels,k): #inX是用于分类的输入向量,dataSet是输入的训练样本集, #labels为标签,k为选择最近邻居的数目 dataSetSize = dataSet.shape[0] #获得训练样本集的行数 '''计算距离''' diffMat = tile(inX,(dataSetSize,1))-dataSet #使用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]] #返回距离最近前k个点的标签 classCount[voteIlabel] = classCount.get(voteIlabel,0)+1 #对这k个最近的点的类别进行统计,这里判断classCount里有没有voteIlabel,如果有则get()返回1,没有则get()返回0 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #将所统计的类别进行降序排序 return sortedClassCount[0][0] #返回发生频率最高的元组标签
接下来,使用kNN算法来改进约会网站的配对效果,在我们将所给的特征数据输入到分类器之前,必须先将数据的格式处理为分类器可以接受的格式,创建file2matrix函数来处理此问题,该函数输入为文件名字符串,输出为训练样本矩阵和类标签向量。
[code]'''将文本记录到转换Numpy的解析程序''' def file2matrix(filename): fr = open(filename) #打开文件 arrayOLines = fr.readlines() #读取文件每一行的内容 numberOfLines = len(arrayOLines) #得到文件的行数 returnMat = zeros((numberOfLines,3)) #创建一个行数为文件行数numberOfLines,列数为3的全零矩阵 classLabelVector = [] index = 0 for line in arrayOLines: line = line.strip() #截取掉所有回车符 listFromLine = line.split('\t') #使用tab字符\t将上一步得到的整行数据分割成一个元素列表 returnMat[index,:] = listFromLine[0:3] #将列表中前3个元素存入矩阵中 classLabelVector.append(int(listFromLine[-1])) #将列表最后一个元素,即标签存入标签向量里 index += 1 return returnMat,classLabelVector
至此,我们已经导入了数据并将数据转化为我们想要的格式。接下来我们对特征值进行归一化。
[code]def autoNorm(dataSet): minVals = dataSet.min(0) #取最小值 maxVals = dataSet.max(0) #取最大值 ranges = maxVals-minVals #最大最小值之前的差 normDataSet = zeros(shape(dataSet)) #生成一个和dataSet形状一样的零矩阵 m = dataSet.shape[0] #获取dataSet第一维的值,因为dataSet有1000x3个值,所以为1000 normDataSet = dataSet-tile(minVals,(m,1)) #用tile()函数将minVals转化为何dataSet相同的大小的矩阵,然后相减 normDataSet = normDataSet/tile(ranges,(m,1)) #用tile()函数将ranges转化为何dataSet相同的大小的矩阵,然后用上一步得到的normDataSet除以它 return normDataSet,ranges,minVals
接下来我们对分类器的效果进行测试,创建datingClassTest()函数。
[code]def datingClassTest(): hoRatio = 0.10 #数据集中用作测试数据的比率 datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #转化数据格式 normMat,ranges,minVals = autoNorm(datingDataMat) #归一化数据 m = normMat.shape[0] #得到样本的数量 numTestVecs = int(m*hoRatio) #选取10%的样本用来测试分类器 errorCount = 0.0 #错误数统计 for i in range(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 #如果分类与实际标签不一样,errorCount加1 print("the total error rate is: %f" % (errorCount/float(numTestVecs))) #打印总出错误率
对分类器测试完毕之后,就可以用这个分类器来对人们分类,只要输入某个人的信息,程序就会给出喜欢这个人程度的预测值。
[code]def classifyPerson(): resultList = ['not at all','in small doses','in large doses'] #结果列表 percentTats = float(input("percentage of time spent playing video games?")) #输入玩游戏时间的比重 ffMiles = float(input("frequent flier miles earned per year?")) #输入每年飞行里程数 iceCream = float(input("liters of ice cream consumed per year?")) #输入每年所吃冰激凌的量 datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #转化数据格式 normMat,ranges,minVals = autoNorm(datingDataMat) #归一化 inArr = array([percentTats,ffMiles,iceCream]) #创建一个数组用来存放之前输入的信息 classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3) #用kNN算法预测 print("You will probably like this person: ",resultList[classifierResult - 1]) #打印出预测结果
再举一个kNN算法应用的例子——手写识别系统。首先我们要把图像转化为测试向量。
[code]def img2vector(filename): returnVect = zeros((1,1024)) #创建一个1x1024的零向量 fr = open(filename) #打开文件 for i in range(32): lineStr = fr.readline() #读取文件的每一行 for j in range(32): returnVect[0,32*i+j] = int(lineStr[j]) #将每行的头32个字符存储在向量中 return returnVect
接下来,将数据输入到分类器,检测分类器的执行效果。
[code]def handwritingClassTest(): hwLabels = [] trainingFileList = listdir('trainingDigits') #获取目录内容并存储在列表里 m = len(trainingFileList) #获得列表长度,即目录中有多少文件 trainingMat = zeros((m,1024)) #创建一个mx1024的矩阵 for i in range(m): fileNameStr = trainingFileList[i] #得到文件名和扩展名 fileStr = fileNameStr.split('.')[0] #得到文件名 classNumStr = int(fileStr.split('_')[0]) #得到该文件所存储的数字 hwLabels.append(classNumStr) #将所存储的数字添加到列表里 trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr) #图像转向量,创建训练集 testFileList = listdir('testDigits') #获取测试集内容并存储在列表里 errorCount = 0.0 错误统计 mTest = len(testFileList) #获得列表长度,即目录中有多少文件 for i in range(mTest): fileNameStr = testFileLis 4000 t[i] #得到文件名和扩展名 fileStr = fileNameStr.split('.')[0] #得到文件名 classNumStr = int(fileStr.split('_')[0]) #得到该文件所存储的数字 vectorUnderTest = img2vector('trainingDigits/%s' % fileNameStr) #图像转向量,创建测试集 classifierResult = classify0(vectorUnderTest,trainingMat,hwLabels,3) #使用kNN算法进行分类 print("the classifier came back with: %d, the real answer is: %d" % (classifierResult,classNumStr)) #打印出分类结果和真实结果 if (classifierResult != classNumStr): errorCount +=1.0 #如果分类结果与实际结果不一样,错误数加1 print("\nthe total number of errors is: %d" % errorCount) #打印总错误数 print("\nthe total error rate is: %f" % (errorCount/float(mTest))) #打印总错误率
本文用Python对kNN算法进行了实现,并通过两个例子来讲述如何使用kNN算法,希望能给大家带来一些帮助。
阅读更多相关文章推荐
- 《机器学习实战》第二章:k-近邻算法(3)手写数字识别
- 读懂《机器学习实战》代码—K-近邻算法改进约会网站配对效果
- 《机器学习实战》读书笔记:第二章 k-近邻算法
- [完]机器学习实战 第二章 k-近邻算法(k Nearest Neighbor)
- 《机器学习实战》2.K-近邻算法分析与源码实现(文末附官方勘误表)
- 机器学习之K-近邻算法代码分析
- 《机器学习实战》 第二章 k-近邻算法概述 学习过程中遇到的问题总结
- 机器学习实战+第二章_k-近邻算法
- 读懂《机器学习实战》代码—K-近邻算法
- 《机器学习实战》第二章:k-近邻算法(2)约会对象分类
- 《机器学习实战》第二章——K-近邻算法
- 《机器学习实战》第二章 k-近邻算法
- k-近邻算法(详细代码注释与调参性能分析)
- 《机器学习实战》第二章 2.2用k-近邻算法改进约会网站的配对效果
- 第一篇:K-近邻分类算法原理分析与代码实现
- 《机器学习实战》第二章:k-近邻算法(1)简单KNN
- 《机器学习实战》K-近邻算法代码解析(1)
- 《机器学习实战》读书笔记2:K-近邻(kNN)算法 & 源码分析
- 快排 和 堆排序算法的细节代码分析
- 区块链教程Fabric1.0源代码分析流言算法Gossip服务端二