从零开始实战机器学习(1)—K近邻算法

来源:互联网 发布:天刀捏脸数据女 2016 编辑:程序博客网 时间:2024/05/21 10:13

最近开始学习机器学习算法,大致了解了一些基础知识后,准备真正编程实现一些机器算法,于是选择了Peter Harrington的机器学习实战这本书,打算将其中的算法实现一下。由于本书算法采用Python语言编写,而且我之前没有接触Python语言,所以正好趁着这个机会从零开始学习Python语言。
K近邻算法的基本原理在这就不再赘述了,就是一组带标签数据,对于一个未分类样本,选择距其最近的K个带标签样本,哪个标签的样本多,就给新样本贴上该标签。
优点:精度高,对异常值不敏感,无数据输入假定
缺点:计算复杂度高,空间复杂度高
适用范围:数值型和标称型
下面就直接上代码

from numpy import *import operatordef createDataSet():                                    #定义已分类样本数据    group = array([(1.0,1.1),(1.0,1.0),(0, 0),(0,0.1),(0.2,0.4),(1.2,1.5)])    labels = ['A','A','B','B','B','A']    return group,labelsdef classify0(inX, dataSet, labels, k):                 #输入参数为未分类样本,已分类数据,已分类数据标签,K    dataSetSize = dataSet.shape[0]                          diffMat = 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):                                  #下面就是计算最近的K个样本中标签出现的次数        voteIlabel = labels[sortedDistIndicies[i]]      #从最近的样本开始循环,读取样本的标签        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1     #每出现一次标签,就给该标签加一    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)     #对标签出现次数进行排序    print sortedClassCount    return sortedClassCount[0][0]group,labels = createDataSet()classify0([1.2,1.3],group,labels,4)

上述算法运行结果如下:
这里写图片描述
算法的原理及实现都不是很复杂,但是作为一个Python小白,其中有不少Python的相关知识点还是值得仔细学习学习。
一、高维数组表示
一维二维数组就不说了,Python中高维数组表示刚开始总弄不清,还按照平面到立体的方法,到了四维五维更多维的时候就完全蒙了,高维数组还是要按照括号一个一个来看。例如

>>> d = arange(36).reshape(2,3,2,3)>>> darray([[[[ 0,  1,  2],         [ 3,  4,  5]],        [[ 6,  7,  8],         [ 9, 10, 11]],        [[12, 13, 14],         [15, 16, 17]]],       [[[18, 19, 20],         [21, 22, 23]],        [[24, 25, 26],         [27, 28, 29]],        [[30, 31, 32],         [33, 34, 35]]]])

可以看出前三块是一个整体,后三块是一个整体,共两个整体,对应这高维数组中的第一个维度2。在第一个整体中,共有三块,对应着第二个维度3。每块都是一个2x3的矩阵,对应着最后两个维度2,3。所以高维数组的表示可以如下图所示,最后两个维度就是最小块矩阵的行和列。
这里写图片描述

二、一些Python函数的用法
1、tile函数
tile函数就是实现由小块矩阵通过行和列的复制生成更大规模矩阵的功能。基本操作语句就是tile(A,reps)。A基本可以是所有类型,但reps不可以是float, string, matrix类型。
这里写图片描述
可以看出,将A根据reps复制的方法与高维数组的方法一模一样。
2、.sum函数
.sum函数实现数组求和功能。基本操作语句为A.sum(axis=n)。axis默认为none,就是对数组所有元素求和,对于二维数组,axis=1按行求和,axis=0按列求和。
3、argsort函数
argsort函数实现对一维数组从小到大排序(高维数组也都按行排序),并返回对应的索引值。

>>> a=array([3,2,5,1,4,6])>>> aarray([3, 2, 5, 1, 4, 6])>>> argsort(a)array([3, 1, 0, 4, 2, 5])

4、.get函数
.get函数对应的是Python中字典这一数据结构。基本操作语句为dict.get(key, default=None)。key就是要查找的键值,该函数返回指定键的值,如果指定键不存在,就返回default值。上述算法中定义一个空数组,在第一次查找标签时返回0并加一,此后每进入一个标签,就在该标签上加一。从而实现了对标签出现次数的统计。
5、sorted函数
sorted函数也是实现了排序功能。基本操作语句为sorted(iterable, cmp=None, key=None, reverse=False)。iterable为可迭代类型;cmp接受一个函数,用于比较;key是列表元素中的某个元素或属性,只接受一个元素;reverse是排序规则,True降序,False升序。上述算法中将operator.itemgetter(1)作为key的值,也就是取标签出现次数这一元素进行排序。还可以使用cmp参数来实现。

def f(a,b):    return a[1]-b[1]sortedClassCount = sorted(classCount.iteritems(), cmp=f, reverse=True)

这样就实现了按照标签出现次数的降序排列,同时还发现若cmp函数返回a-b时,则排序规则与reverse相同,若返回b-a,则排序规则与reverse相反。

原创粉丝点击