k近邻算法思想:根据测量不同特征值之间的距离来进行分类。即存在一组带有标签的数据,我们叫做训练数据,输入没有标签的数据之后,将新数据的每个特征与训练数据中相对应的特征进行比较,最终提取样本集中特征最相似数据的分类标签,一般情况下,我们只选择样本集中前k个最相似的数据标签。
下面依次解读书中的kNN源码:
1、
numpy 科学计算包,可用来存储和处理大型矩阵
operator这个模块提供了一系列的函数操作。比如,operator.add(x, y)等于x+yos模块包含普遍的操作系统功能,主要是指文件目录的操作,而与之相似的sys主要是针对系统环境的交互
2、
创建数据集和标签
3、
k-近邻算法的核心程序
intX代表待分类的新数据,dataSet代表训练数据group,labels代表训练数据labels,k代表选择前k个最相似数据的标签
shape函数的功能是读取矩阵的长度。shape[0]就是行数,shape[1]就是列数。
tile函数的数字从后往前分别对应A的第N个维度的重复次数。如tile(A,2)表示A的第一个维度重复2遍,tile(A,(2,3))表示A的第一个维度重复3遍,然后第二个维度重复2遍,
tile(A,(2,2,3))表示A的第一个维度重复3遍,第二个维度重复2遍,第三个维度重复2遍,看如下例子就应该懂了。
sum函数中,没有axis参数表示全部相加,axis=0表示按列相加,axis=1表示按照行的方向相加。
sorted函数是Python内置的排序函数,它可以对list或者iterator进行排序。它的第一个参数就是待排序的数据,如下图举例,classCount.iteritems()代表的就是这个字典本身。
第二个参数key=operator.itemgetter(1),operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号)。
第三个参数,reverse是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。
接下来,作者使用k-近邻算法改进约会网站的效果。
核心算法如下:
1、从文本中导入数据
这个函数中主要就是列表切片的使用,切片一般都是包头不包尾。
2、使用Matplotlib制作原始数据的散点图。
这里主要注意子图的画法,函数subplot(numRows, numCols, plotNum),图表的整个绘图区域被分成 numRows 行和 numCols 列,然后按照从左到右,从上到下的顺序对每
个子区域进行编号,左上的子区域的编号为1,plotNum 参数指定创建的 Axes 对象所在的区域。规则的子图划分很好理解,当不规则划分时,看下面的例子理解:
另外,array的切片与列表的切片要注意区分。
上图由于没有使用样本分类的特征值,很难看到任何有用的数据模式信息。为了更好理解数据信息,Matplotlib库提供的scatter函数支持个性化标记散点图上的点。调用scatter
函数使用下列参数:
上图利用datingLabels存储的类标签属性,在散点图上绘制了色彩不等、尺寸不同的点。因而基本上可以从图中看到数据点所属三个样本分类的区域轮廓。
这里主要注意散点图scatter的用法:
这里令x作为数据50*30的大小,我们仅可视化前两维。label为其类别(假设有三类),label设定为[1:20]->1, [21:35]->2, [36:50]->3,(python中数组连接方法:先强制转为
list,用+,再转回array),结果如下:
为避免某一特征对计算结果的影响过大,需要对数据记性归一化处理。
这里.min(0)/max(0)都是按列来查询,.min(1)/max(1)都是按行来查询。
验证分类器的正确率:
接下来,使用k近邻算法的手写识别系统,这时要将图片格式化为一个向量,这样就可以使用前文的分类器来进行识别。
实际上,k近邻算法必须保存全部的数据,如果数据量比较大,就必定会占用大量的存储空间,此外,还必须要依次对数据集中的每个数据进行距离测算,可能会非常耗时!