K近邻算法(一)

来源:互联网 发布:电视直播软件tv版 编辑:程序博客网 时间:2024/04/29 11:38

**

K近邻算法原理与实现

**

1. K近邻算法概述
k近邻算法简单的来说就是采用测量不同特征值之间的距离方法来进行分类。它的工作原理是:
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据 与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。 最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
2. 算法(K近邻)
这里写图片描述

3. 模型
在k近邻算法中,当训练集、最近邻值k、距离度量、决策规则等确定下来时,整个算法实际上是利用训练集把特征空间划分成一个个子空间,训练集中的每个样本占据一部分空间。对最近邻而言,当测试样本落在某个训练样本的领域内,就把测试样本标记为这一类。
这里写图片描述

4. 距离度量
k近邻模型的特征空间一般是n维特征向量空间R,使用的距离是欧式距离,但也可以使用其他距离。如更一般Lp距离或Minkowski距离
这里写图片描述

5. k的选择
k的选择会对k近邻算法的结果产生重大影响。
如果选择的k值比较小,就相当于从较小的邻域中训练实例进行预测。“学习”的近似误差会减小,只有与输入实例中较接近的训练样本才会起到预测作用。但缺点是估计误差会增大,预测结果对近邻的实例点非常敏感。如果近邻点恰好是噪音,则预测结果会出错。如果k值选择较大则相当于从较大的邻域中的训练样本进行预测。其优点是估计误差可以减小,但缺点是近似误差会增大。这时与输入实例距离较远的也会起到预测作用,使预测发生错误。极端情况k=n,无论输入什么实例,其预测结果都会是训练实例中最多的类。
6. 分类决策规则
分类结果是由输入实例的k个临近的训练实例中多数类决定的。
7.示例1:用k-近邻算法对电影分类
有人曾经统计过 很多电影的打斗镜头和接吻镜头,图2-1显示了6部电影的打斗和接吻_ 头数。假如有一部未看过 的电影,如何确定它是爱情片还是动作片呢?我们可以使用_ 来解决这个问题。
这里写图片描述
首先我们需要知道这个未知电影存在多少个打斗镜头和接吻镜头,图2-1中问号位置是该未 知电影出现的镜头数图形化展示,具体数字参见表2-1。
这里写图片描述
首先计算未知电影与样本集中其他电影的距离,如表2-2所示:
这里写图片描述
现在我们得到了样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到k个距 离最近的电影。假定k=3,则三个最靠近的电影依次是He’s Not Really into Dudes,Beautiful Woman和California Man 。从 k-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。
8.KNN算法的Python代码实现

#encoding:utf-8from numpy import *import operatordef createDataSet():    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])    labels = ['A','A','B','B']    return group,labelsdef classify0(inX,dataSet,labels,k):    #返回“数组”的行数,如果shape[1]返回的则是数组的列数    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    #排序 classCount.iteritems() 输出键值对 key代表排序的关键字 True代表降序    sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse = True)    #返回距离最小的点对应的标签   return sortedClassCount[0][0]
原创粉丝点击