K-近邻算法的Python实现 : 源码分析

网上介绍K-近邻算法的例子很多,其Python实现版本基本都是来自于机器学习的入门书籍《机器学习实战》,虽然K-近邻算法本身很简单,但很多初学者对其Python版本的源代码理解不够,所以本文将对其源代码进行分析。

什么是K-近邻算法?

简单的说,K-近邻算法采用不同特征值之间的距离方法进行分类。所以它是一个分类算法。

优点:无数据输入假定,对异常值不敏感

缺点:复杂度高

好了,直接先上代码,等会在分析:(这份代码来自《机器学习实战》)

def classify0(inx, dataset, lables, k):
    dataSetSize = dataset.shape[0]
    diffMat = tile(inx, (dataSetSize, 1)) - dataset
    sqDiffMat = diffMat**2
    sqDistance = sqDiffMat.sum(axis=1)
    distances = sqDistance**0.5
    sortedDistances = distances.argsort()
    classCount={}
    for i in range(k):
        label = lables[sortedDistances[i]]
        classCount[label] = classCount.get(label, 0) + 1
    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

该函数的原理是:

存在一个样本数据集合,也称为训练集,在样本集中每个数据都存在标签。在我们输入没有标签的新数据后,将新数据的每个特征与样本集中对应的特征进行比较,然后提取最相似(最近邻)的分类标签。一般我们只选样本数据集中前K 个最相似的数据。最后,出现次数最多的分类就是新数据的分类。

classify0函数的参数意义如下:

inx : 是输入没有标签的新数据,表示为一个向量。

dataset: 是样本集。表示为向量数组。

labels:对应样本集的标签。

k:即所选的前K。

用于产生数据样本的简单函数:

def create_dataset():
    group = array([[1.0, 1.1], [1.0, 1.1], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

注意,array是numpy里面的。我们需要实现import进来。

from numpy import *
import operator

我们在调用时,

group,labels = create_dataset()
result = classify0([0,0], group, labels, 3)
print result

显然,[0,0]特征向量肯定是属于B 的,上面也将打印B。

知道了这些,初学者应该对实际代码还是很陌生。不急,正文开始了!

源码分析

dataSetSize = dataset.shape[0]

shape是array的属性,它描述了一个数组的“形状”,也就是它的维度。比如,

In [2]: dataset = array([[1.0, 1.1], [1.0, 1.1], [0, 0], [0, 0.1]])

In [3]: print dataset.shape
(4, 2)

所以,dataset.shape[0] 就是样本集的个数。

diffMat = tile(inx, (dataSetSize, 1)) - dataset

tile(A,rep)函数是基于数组A来构造数组的,具体怎么构造就看第二个参数了。其API介绍有点绕,但简单的用法相信几个例子就能明白。

我们看看tile(inx, (4, 1))的结果,

In [5]: tile(x, (4, 1))
Out[5]:
array([[0, 0],
       [0, 0],
       [0, 0],
       [0, 0]])

你看,4扩展的是数组的个数(本来1个,现在4个),1扩展的是每个数组元素的个数(原来是2个,现在还是两个)。

为证实上面的结论,

In [6]: tile(x,(4,2))
Out[6]:
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

和,

In [7]: tile(x,(2,2))
Out[7]:
array([[0, 0, 0, 0],
       [0, 0, 0, 0]])

关于,tile的具体用法,请自行查阅API DOC。

得到tile后,减去dataset。这类似一个矩阵的减法,结果仍是一个 4 * 2的数组。

In [8]: tile(x, (4, 1)) - dataset
Out[8]:
array([[-1. , -1.1],
       [-1. , -1.1],
       [ 0. ,  0. ],
       [ 0. , -0.1]])

结合欧式距离的求法,后面的代码就清晰些,对上面结果平方运算,求和,开方。

我们看看求和的方法,

sqDiffMat.sum(axis=1)

其中,

In [14]: sqDiffmat
Out[14]:
array([[ 1.  ,  1.21],
       [ 1.  ,  1.21],
       [ 0.  ,  0.  ],
       [ 0.  ,  0.01]])

求和的结果是对行求和,是一个N*1的数组。

如果要对列求和,

sqlDiffMat.sum(axis=0)

argsort()是对数组升序排序的。

classCount是一个字典,key是标签,value是该标签出现的次数。

这样,算法的一些具体代码细节就清楚了。

时间: 2024-10-13 19:53:22

K-近邻算法的Python实现 : 源码分析的相关文章

k近邻算法的Python实现

k近邻算法的Python实现 0. 写在前面 这篇小教程适合对Python与NumPy有一定了解的朋友阅读,如果在阅读本文的源代码时感到吃力,请及时参照相关的教程或者文档. 1. 算法原理 k近邻算法(k Nearest Neighbor)可以简称为kNN.kNN是一个简单直观的算法,也是机器学习从业者入门首选的算法.先看一个简单的应用场景. 小例子 设有下表,命名为为表1 电影名称 打斗镜头数量 接吻镜头数量 电影类型 foo1 3 104 爱情片 foo2 2 100 爱情片 foo3 1

数据挖掘:关联规则的apriori算法在weka的源码分析

相对于机器学习,关联规则的apriori算法更偏向于数据挖掘. 1) 测试文档中调用weka的关联规则apriori算法,如下 try { File file = new File("F:\\tools/lib/data/contact-lenses.arff"); ArffLoader loader = new ArffLoader(); loader.setFile(file); Instances m_instances = loader.getDataSet(); Discre

python slots源码分析

上次总结Python3的字典实现后的某一天,突然开窍Python的__slots__的实现应该也是类似,于是翻了翻CPython的源码,果然如此! 关于在自定义类里面添加__slots__的效果,网上已经有很多资料了,其中优点大致有: (1)更省内存. (2)访问属性更高效. 而本文讲的是,为什么更省内存?为什么更高效?当然为了弄明白这些,深入到CPython的源码是必不可少的.不过,心里有个猜想之后再去看源码效果或许更好,这样目的性更强,清楚自己需要关注的是什么以免在其中迷失! 我先稍微解释一

K近邻算法及其Python实现

下面贴出Python代码 knnClassify.py 1 from numpy import * 2 import operator 3 4 def creatDataSet(): 5 group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) 6 labels = ['A','A','B','B'] 7 return group, labels 8 9 def classify(inX,dataSet,labels,k): 10 numSamples

python SocketServer 源码分析

附上原文链接: http://beginman.cn/python/2015/04/06/python-SocketServer/

用Python从零开始实现K近邻算法

K近邻算法 (或简称kNN)是易于理解和实现的算法,而且是你解决问题的强大工具. http://python.jobbole.com/87407/ 在本教程中,你将基于Python(2.7)从零开始实现kNN算法.该实现主要针对分类问题,将会用鸢尾花分类问题来演示. 这篇教程主要针对Python程序员,或者你可以快速上手Python,并且对如何从零实现kNN算法感兴趣. kNN算法图片,来自Wikipedia,保留所有权利 什么是kNN kNN算法的模型就是整个训练数据集.当需要对一个未知数据实

从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经网络:3.编程艺术第28章.你看到,blog内的文章与你于别处所见的任何都不同.于是,等啊等,等一台电脑,只好等待..”.得益于田,借了我一台电脑(借他电脑的时候,我连表示感谢,他说“能找到工作全靠你的博客,这点儿小忙还说,不地道”,有的时候,稍许感受到受人信任也是一种压力,愿我不辜负大家对我的信任)

K 近邻算法

声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,因为本人在学习初始时有非常多数学知识都已忘记,所以为了弄懂当中的内容查阅了非常多资料.所以里面应该会有引用其它帖子的小部分内容,假设原作者看到能够私信我,我会将您的帖子的地址付到以下. 3.假设有内容错误或不准确欢迎大家指正. 4.假设能帮到你.那真是太好了. 描写叙述 给定一个训练数据集,对新的输入实例.在训练数据集中找到与该实例最邻近的K个实例,若这K个实

OpenStack_Swift源码分析——Ring的rebalance算法源代码详细分析

今天有同学去百度,带回一道面试题,和大家分享一下: 打印: n=1 1 n=2 3 3 2 4 1 1 4 5 5 n=3 7 7 7 7 6 8 3 3 2 6 8 4 1 1 6 8 4 5 5 5 8 9 9 9 9 提供一段参考程序: <pre name="code" class="cpp">// ConsoleApplication1.cpp: 主项目文件. #include "stdafx.h" #include &quo