-小白入坑笔记
---恢复内容开始---
1.
k-近邻算法+注释
1 # -*- coding: utf-8 -*- 2 ''' 3 Created on April 22, 2018 4 kNN: k Nearest Neighbors 5 6 Input: inX: vector to compare to existing dataset (1xN) 7 dataSet: size m data set of known vectors (NxM) 8 labels: data set labels (1xM vector) 9 k: number of neighbors to use for comparison (should be an odd number) 10 11 Output: the most popular class label 12 13 @author: louis.zb 14 ''' 15 16 from numpy import * 17 import operator 18 19 def createDataSet(): 20 """ 21 函数作用:构建一组训练数据(训练样本),共4个样本 22 同时给出了这4个样本的标签,及labels(标签向量) 23 """ 24 group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) 25 labels = ['A','A','B','B'] 26 return group, labels 27 28 def classify0(inX, dataSet, labels, k): 29 """ 30 inX 是出入的测试样本,是一个[x,y]样式的 31 dataset 是训练样本集 32 lebels 是训练样本标签 33 k 是top K最相近的参数 34 """ 35 # shape(dataSet) <<(4,2),即返回二位数组(行数,列数),4行2列 36 # dataset.shape[0]=4,dataSet.shape[1]=2; 37 # https://blog.csdn.net/qq_28618765/article/details/78081959 38 #行数也就是样本的数量 39 40 dataSetSize = dataSet.shape[0] 41 """ 42 tile(x,2) << [x,x,x] 横向复制,最后变为x的2倍 43 tile(x,(1,2)) (1,2)复制后,行为1倍,列为2倍 44 tile(x,(3,2,4)) (3,2,4) 先按照(2,4)变为行2倍,列4倍作整体矩阵,横向复制为3倍。 45 >>> a=array([[2,1]]) 46 >>> tile(a,2) 47 array([[2, 1, 2, 1]]) 48 49 >>> tile(a,4) 50 array([[2, 1, 2, 1, 2, 1, 2, 1]]) 51 >>> tile(a,(2,4)) 52 array([[2, 1, 2, 1, 2, 1, 2, 1], 53 [2, 1, 2, 1, 2, 1, 2, 1]]) 54 55 >>> tile(a,(1,4)) 56 array([[2, 1, 2, 1, 2, 1, 2, 1]]) 57 >>> tile(a,(1,2,4)) 58 array([[[2, 1, 2, 1, 2, 1, 2, 1], 59 [2, 1, 2, 1, 2, 1, 2, 1]]]) 60 >>> tile(a,(3,2,4)) 61 array([[[2, 1, 2, 1, 2, 1, 2, 1], 62 [2, 1, 2, 1, 2, 1, 2, 1]], 63 64 [[2, 1, 2, 1, 2, 1, 2, 1], 65 [2, 1, 2, 1, 2, 1, 2, 1]], 66 67 [[2, 1, 2, 1, 2, 1, 2, 1], 68 [2, 1, 2, 1, 2, 1, 2, 1]]]) 69 >>> shape(tile(a,(3,2,4))) #??????纬度??如何解释?,2*8的数组构成的大数组。 70 (3, 2, 8) 71 >>> s=tile(a,(3,2,4)) 72 >>> s[0][0][0] 73 2 74 >>> s[2][0][0] 75 2 76 """ 77 78 # inX行数复制为(样本数量)倍,方便相减 79 diffMat = tile(inX, (dataSetSize,1))-dataSet 80 sqDiffMat = diffMat**2 81 sqDistances = sqDiffMat.sum(axis=1) 82 83 #现在对于数据的处理更多的还是numpy。没有axis参数表示全部相加,axis=0表示按列相加,axis=1表示按照行的方向相加.即针对每个点,求平方和,得到的数组纬度为(dataSetSize)*1列 84 85 """ 86 >>> b 87 array([[2, 1], 88 [2, 1], 89 [2, 1], 90 [2, 1]]) 91 >>> c=b.sum(axis=1) 92 >>> c 93 array([3, 3, 3, 3]) 94 >>> shape(b) 95 (4, 2) 96 >>> shape(c) #可看到纬度 97 (4,) 98 99 """ 100 distances = sqDistances**0.5 #开方 101 102 # 按照升序进行快速排序,返回的是原数组的下标。 103 # 比如,x = [30, 10, 20, 40] 104 # 升序排序后应该是[10,20,30,40],他们的原下标是[1,2,0,3] 105 # 那么,numpy.argsort(x) = [1, 2, 0, 3] 106 sortedDistIndicies = distances.argsort() 107 # classCount{},字典:存放无序键值映射(key/value)类型数据的容器。键值(key)可以是数字和字符串。其他语言中一般成为关联数组(associative array)或者映射(map) 108 classCount={} 109 110 ## 投票过程,就是统计前k个最近的样本所属类别包含的样本个数 111 for i in range(k): 112 #index = sortedDistIndicies[i]是第i个最相近的样本下标 113 # voteIlabel = labels[index]是样本index对应的分类结果('A' or 'B') 114 voteIlabel = labels[sortedDistIndicies[i]] 115 # classCount是字典,classCount.get(voteIlabel, 0)返回voteIlabel的值(value),如果不存在,则返回0 116 # classCount[voteIlabel]指的是键(vatelabel)对应的value值。value值加1 117 ''' 118 >>> a={'A':10,'B':5} 119 >>> a['A'] 120 10 121 >>> b=a.get('B',0) 122 >>> b 123 5 124 ''' 125 classCount[voteIlabel] = classCount.get(voteIlabel,0)+1 126 127 # 把分类结果进行排序,然后返回得票数最多的分类结果 128 #sorted()排序,不会覆盖原值,默认从小到大。 https://blog.csdn.net/vivian_ll/article/details/78647979 129 #sort()覆盖原值,也是从小到大,速度快,占内存小。class 130 #字典的items()方法和iteritems()方法,是python字典的内建函数,分别会返回Python列表和迭代器。 131 """python字典的items方法作用:是可以将字典中的所有项,以列表方式返回。如果对字典项的概念不理解,可以查看Python映射类型字典基础知识一文。因为字典是无序的,所以用items方法返回字典的所有项,也是没有顺序的。python字典的iteritems方法作用:与items方法相比作用大致相同,只是它的返回值不是列表,而是一个迭代器。 132 operator.itemgetter函数:operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),下面看例子。 133 """ 134 135 #将classCount分裂为元组列表???,然后使用程序第二行导入运算符模块的itemetter方法,按照第二个元素(value)的次序对元素列表进行排序。此处排序为逆序(是否逆转reverse=True) 136 sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True) 137 return sortedClassCount[0][0] #返回最大值 138 139 140 def file2matrix(filename): 141 ''' 142 从文件读入训练数据,并存储为矩阵 143 ''' 144 fr=open(filename) 145 arrayOLines = fr.readlines() #读取全部内容 ,并以列表方式返回 https://blog.csdn.net/zhengxiangwen/article/details/55148287 (python以行读取文件的3种用法) 146 numberOfLines = len(arrayOLines) ##取列表长度,即为行数 147 returnMat = zeros((numberOfLines,3)) #returnMat实际上是2纬数组 148 classLabelVector=[] 149 index=0 150 for line in arrayOLines: 151 #https://www.cnblogs.com/angelatian/p/5832457.html strip()与split()的理解 152 #strip(rm),rmm默认为空时,删除开头和结尾处的回车字符’(包括'\n','\r','\t','') 153 line = line.strip('\n') 154 155 ## 把每一行数据依据taba字符'\t'把上一步得到的整行元素分割成列表。 156 #split()\r回车 , \n 换行, \f 走纸换页, \t 横向跳格, \b 退格. \t就是横向跳8格 https://blog.csdn.net/linwh8/article/details/50363241 157 ''' 158 >>> a='adfafasdfa/nsd' 159 >>> a 160 'adfafasdfa/nsd' 161 >>> a.split('/n') 162 ['adfafasdfa', 'sd'] 163 164 ''' 165 listFromLine = line.split('\t') 166 167 ## 把分割好的数据放至数据集,其中index是该样本数据的下标,就是放到第几行 168 ##returnmat[index,:]表示取该矩阵第index行的所有元素。listFromLine[0:3]下标为0到2的元素 169 returnMat[index,:] = listFromLine[0:3] 170 # 把该样本对应的标签放至标签集,顺序与样本集对应。索引'-1'表示最后一列,下标为3 171 classLabelVector.append(int (listFromLine[-1])) 172 index += 1 173 return returnMat, classLabelVector 174
问题1:运行时,提示group未定义
>>> import kNN >>> kNN.classify0([0,0], group, labels,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'group' is not defined
解决办法:https://bbs.csdn.net/topics/391822656

问题2:
.py文件内中文标注,提示错误
解决办法:代码最前面增加
# -*- coding: utf-8 -*-
问题3:字典类型,sorted()中items()和iteritems()
1 >>> a={'A':10,'B':5} 2 >>> a['A'] 3 10 4 >>> b=a.get('B',0) 5 >>> b 6 5 7 >>> b=a.get('B',0)+10 8 >>> b 9 15 10 >>> a.items() 11 [('A', 10), ('B', 5)] 12 >>> a.iteritems() 13 <dictionary-itemiterator object at 0x7f22d171c4c8> 14 >>> b=a.iteritems() 15 >>> list(b) 16 [('A', 10), ('B', 5)]
答:itermitems()返回的是一个能遍历所有键值对的生成器
items()返回的是整个列表中的键值对的拷贝,在你的dict比较大的情况下会消耗大量内存
性能没比较过,你自己试试?
(我猜生成器性能更好)
python3里面的items()改成了iteritems()的行为然后删除了iteritems()
1 a = {'math':98, 'english':100, 'PE':77} 2 3 b = sorted(a.iteritems(), key=operator.itemgetter(1), reverse=True) 4 5 c = sorted(a.items(), key=operator.itemgetter(1), reverse=True)
python: line=f.readlines() 后如何消除line中的'\n'
问题4: <python>strip() 函数和 split() 函数的理解
下面句子代表什么意思?
classLabelVector.append(int(listFromLine[-1])) //以整型把listFromLine最后一列的数据以整型的形式,推入向量classLabelVector最后
问题5:问题:该行未缩进!重新缩进即可解决
>>> import kNN Traceback (most recent call last): File "<stdin>", line 1, in <module> File "kNN.py", line 145 arrayOLines = fr.readlines() ^ IndentationError: unindent does not match any outer indentation level
问题6:
按行读文件,arrayOlines是行字符串列表,每个行作为一个字符串,存到整个列表里。再对列表内容进行遍历。
fr=open(filename) arrayOLines = fr.readlines() for line in arrayOLines: do(...)
使用Matplotlib创建散点图分析数据:daingDataMat矩阵第2,3列的属性来展示数据。

换成第1,2列属性来展示。
使用Matplotlib创建散点图分析数据:
import kNN import numpy from numpy import array group, labels=kNN.createDataSet() datingDataMat, datingLabels = kNN .file2matrix('datingTestSet2.txt') import matplotlib import matplotlib.pyplot as plt fig = plt.figure()
ax = fig.add_subplot(111) ##add_subplot(mnp)添加子轴、图。subplot(m,n,p)或者subplot(mnp)此函数最常用:subplot是将多个图画到一个平面上的工具。其中,m表示是图排成m行,n表示图排成n列,也就是整个figure中有n个图是排成一行的,一共m行,如果第一个数字是2就是表示2行图。p是指你现在要把曲线画到figure中哪个图上,最后一个如果是1表示是从左到右第一个位置。 ax.scatter(datingDataMat[:,0],datingDataMat[:,1], 15.0*array(datingLabels),15.0*array(datingLabels))#以第二列和第三列为x,y轴画出散列点,给予不同的颜色和大小 #scatter(x,y,s=1,c="g",marker="s",linewidths=0) #s:散列点的大小,c:散列点的颜色,marker:形状,linewidths:边框宽度 plt.show()

分类器针对约会网站的测试代码
当测试比例hoRatio=0.1, 10%的数据用于测试,90%的数据用于分类器的训练样本
def datingClassTest(): hoRatio = 0.10 datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') normMat, ranges, minVals = autoNorm(datingDataMat) m = normMat.shape[0] #normMat矩阵行数 numTestVecs = int (m*hoRatio) #测试行数 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 answers is %d" %(classifierResult ,datingLabels[i]) if(classifierResult != datingLabels[i]):errorCount += 1.0 print "the total error rate is : %f" %(errorCount/float(numTestVecs))
kNN.datingClassTest() the classifier came back with : 3, the real answers is 3 ... the classifier came back with : 2, the real answers is 2 the classifier came back with : 1, the real answers is 1 the classifier came back with : 3, the real answers is 1 the total error rate is : 0.050000
错误率为5%
调整函数datingClassTest中hoRatio和k的值
- hoRatio=0.1, k=3, total error rate=0,05
- hoRatio=0.1, k=4, total error rate=0,03
- hoRatio=0.1, k=5, total error rate=0,04
- hoRatio=0.1, k=6, total error rate=0,06
- hoRatio=0.1, k=3, total error rate=0,05
- hoRatio=0.01, k=4, total error rate=0
- hoRatio=0.02, k=4, total error rate=0
- hoRatio=0.03, k=4, total error ra te=0
- hoRatio=0.05, k=4, total error rate=0
- hoRatio=0.07, k=4, total error rate=0
- hoRatio=0.08, k=4, total error rate=0.125
- hoRatio=0.09, k=4, total error rate=0.011111
---恢复内容结束---
浙公网安备 33010602011771号