首页 > 代码库 > 机器学习实战笔记--k近邻算法

机器学习实战笔记--k近邻算法

  1 #encoding:utf-8
  2 from numpy import *
  3 import operator
  4 import matplotlib
  5 import matplotlib.pyplot as plt
  6 
  7 from os import listdir
  8 
  9 def makePhoto(returnMat,classLabelVector):     #创建散点图
 10     fig = plt.figure()
 11     ax = fig.add_subplot(111)         #例如参数为349时,参数349的意思是:将画布分割成3行4列,图像画在从左到右从上到下的第9块
 12     ax.scatter(returnMat[:,1],returnMat[:,2],15.0*array(classLabelVector),15.0*array(classLabelVector))    #前两个函数参数的意义是横坐标和纵坐标
 13     plt.show()
 14 
 15 def classify0(inX, dataSet, labels, k):    #k近邻算法  inX为分类向量   dataSet为训练数据集   labels为标签列表   k:选择距离最小的k个点
 16     dataSetSize = dataSet.shape[0]         #获得dataSet的第一维长度
 17     diffMat = tile(inX, (dataSetSize, 1)) - dataSet    #将向量inX重复1次,共dataSetSize行。然后减去dataSet
 18     sqDiffMat = diffMat ** 2           #diffMat矩阵的每个元素平方
 19     sqDistances = sqDiffMat.sum(axis=1)   #按行求和,即求每一行的和,得到一个list
 20     distances = sqDistances ** 0.5     #对sqDistances的每个元素开方
 21     sortedDistIndicies = distances.argsort()   #返回distances从小到大的索引
 22                                                #例如,x=np.array([3.2.1])  np.argsort(x)  得到的结果为array([1.2.0])
 23     classCount = {}         #python花括号代表代表dict字典数据类型,[]代表list,()代表元组,(55,)一个值的元组
 24     for i in range(k):
 25         voteIlabel = labels[sortedDistIndicies[i]]   #依次取出最小的元素
 26         classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1   #如果存在加1,不存在默认为0
 27     sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)  #第一个参数为比较的list,第二个参数为比较的对象(这里指的是键值对的value),第三个参数是升序或降序(默认为false(升序排列))
 28     return sortedClassCount[0][0]   #取得次数最多的key
 29 
 30 
 31 def createDataSet():    #创建数据集
 32     group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
 33     labels = [A, A, B, B]
 34     return group, labels
 35 
 36 
 37 def file2matrix(filename):   #解析文本
 38     fr = open(filename)
 39     numberOfLines = len(fr.readlines())  #得到文本的行数
 40     returnMat = zeros((numberOfLines, 3))  #构造一个行数为文本行数,列数为3的0矩阵
 41     classLabelVector = []  #标签列表
 42     fr = open(filename)
 43     index = 0
 44     for line in fr.readlines():  #读取文件的每一行
 45         line = line.strip()      #删除符号,此处参数为空,表示删除空白符
 46         listFromLine = line.split(\t)   #以\t符号为分隔符
 47         returnMat[index, :] = listFromLine[0:3]   #将listFromLine的0到3赋值给returnMat的index行
 48         classLabelVector.append(int(listFromLine[-1]))   #将listFromLine的最后一个元素添加到classLabelVector
 49         index += 1    #下标加1
 50     return returnMat, classLabelVector
 51 
 52 
 53 def autoNorm(dataSet):          #归一化特征值
 54     minVals = dataSet.min(0)        #取每列的最小值赋值给minVals,是一个list
 55     maxVals = dataSet.max(0)         #取每列的最大值赋值给maxVals
 56     ranges = maxVals - minVals
 57     normDataSet = zeros(shape(dataSet))
 58     m = dataSet.shape[0]
 59     normDataSet = dataSet - tile(minVals, (m, 1))    #取到与最小值的差
 60     normDataSet = normDataSet / tile(ranges, (m, 1))  #除以范围
 61     return normDataSet, ranges, minVals
 62 
 63 
 64 def datingClassTest():
 65     hoRatio = 0.50   # 测试用例占用比例
 66     datingDataMat, datingLabels = file2matrix(datingTestSet2.txt)  # 读取数据
 67     normMat, ranges, minVals = autoNorm(datingDataMat)   #特征值归一化
 68     m = normMat.shape[0]
 69     numTestVecs = int(m * hoRatio)
 70     errorCount = 0.0
 71     for i in range(numTestVecs):
 72         classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)    #第numTestVecs到m是样本数据,前m个是测试数据
 73         print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])   #打印预测值和标签值
 74         if (classifierResult != datingLabels[i]): errorCount += 1.0
 75     print "the total error rate is: %f" % (errorCount / float(numTestVecs))
 76     print errorCount
 77 
 78 #输入某人的信息,便得出对对方喜欢程度的预测值
 79 def classifyPerson():
 80     resultList = [一点也不喜欢, 有点喜欢, 非常喜欢]
 81     percentTats = float(raw_input("玩视频游戏所耗时间百分比是:"))#输入
 82     ffMiles = float(raw_input("飞行里程数是:"))
 83     iceCream = float(raw_input("每周消费的冰淇淋公升数是:"))
 84     datingDataMat, datingLabels = file2matrix(datingTestSet2.txt) #读入样本文件,其实不算是样本,是一个标准文件
 85     normMat, ranges, minVals = autoNorm(datingDataMat)#归一化
 86     inArr = array([ffMiles, percentTats, iceCream])#组成测试向量
 87     classifierResult = classify0((inArr-minVals)/ranges, normMat, datingLabels,3)#进行分类
 88     print 你对这种人的看法可能是:, resultList[classifierResult - 1]#打印结果
 89 
 90 def img2vector(filename):    #将图片转化成向量
 91     returnVect = zeros((1, 1024))
 92     fr = open(filename)
 93     for i in range(32):
 94         lineStr = fr.readline()
 95         for j in range(32):
 96             returnVect[0, 32 * i + j] = int(lineStr[j])
 97     return returnVect
 98 
 99 
100 def handwritingClassTest():
101     hwLabels = []
102     trainingFileList = listdir(trainingDigits)  # 加载文件夹trainingDigits目录下文件列表
103     m = len(trainingFileList)
104     trainingMat = zeros((m, 1024))
105     for i in range(m):
106         fileNameStr = trainingFileList[i]
107         fileStr = fileNameStr.split(.)[0]
108         classNumStr = int(fileStr.split(_)[0])  #得到标签
109         hwLabels.append(classNumStr)    #加入标签列表
110         trainingMat[i, :] = img2vector(trainingDigits/%s % fileNameStr)  #解析文件得到向量
111     testFileList = listdir(testDigits)  # 测试数据
112     errorCount = 0.0
113     mTest = len(testFileList)
114     for i in range(mTest):
115         fileNameStr = testFileList[i]
116         fileStr = fileNameStr.split(.)[0]
117         classNumStr = int(fileStr.split(_)[0])
118         vectorUnderTest = img2vector(testDigits/%s % fileNameStr)
119         classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
120         print "分类器返回的结果: %d, 真实结果: %d" % (classifierResult, classNumStr)
121         if (classifierResult != classNumStr): errorCount += 1.0   #计算得到结果与标签比较
122     print "\n错误总数为: %d" % errorCount
123     print "\n错误率为: %f" % (errorCount / float(mTest))
124 
125 if __name__ == __main__:
126     # print("main")
127     # returnMat, classLabelVector = file2matrix(‘datingTestSet2.txt‘)
128     # #makePhoto(returnMat,classLabelVector)
129     # normDataSet, ranges, minVals = autoNorm(returnMat)
130     # print(normDataSet)
131     # print(ranges)
132     # print(minVals)
133     #classifyPerson()
134     # textVector = img2vector("testDigits/0_13.txt")
135     # print textVector[0,0:31]
136     handwritingClassTest()

 

机器学习实战笔记--k近邻算法