您的位置:首页 > 其它

ML--K-近邻算法

2015-12-07 21:45 288 查看

声明:本人学习的机器学习以machine learning in action 【美】peter Harrington著为主,练习上面代码并进行适当修改,不涉及任何版权不作任何商业用途,有问题可以联系本人,文中源码到一定时间将会在github上公开。

1、K-近邻算法(k-Nearest Neighbor,KNN)

该算法通过测量不同特征之间的距离来进行分类,说的是每个特征可以通过它的最邻近的K个邻居来表示。

下面是来自维基百科的一幅图:绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类,这就是KNN算法的基本思想。



2.KNN算法

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

缺点:计算较复杂

适用的数据范围包括:数值型和标称型

2.1KNN算法的流程

1.采集数据

2.分析数据

3.训练算法,计算距离

4.测试算法,计算错误率

5.验证算法,作测试

2.2 用python来跑算法环境简介

本人用的是win7 64位,python 2.7.10,用的编辑器是sublime text3 ,对于机器学习而已,Python需要额外安装三个库分别是Numpy,scipy和Matplotlib。大家自己安装相应的配置环境,这里专注算法,环境不做过多阐述。

3.kNN实战

在同一个文件夹下创建名为kNN.py的python模块和main.py的测试模块。

首先在kNN.py中添加如下代码,及注释:

# -*- coding:UTF-8 -*-
#Filename:kNN.py
from  numpy import *
import operator
def createDataSet():
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1],[5,5],[5.1,4.9]])
labels = ['A','A','B','B','C','C']
return group,labels


numpy模块是一个科学计算包,另一个是运算符模块。

上面代码以在(1,1),(0,0),(5,5)点附近定义了3个类别分别是A,B,C,随便用一个点来测试,距离(欧式距离)最小的点就是我们临近的类,在main.py中,输入如下代码,测试我们上面模块的正确性。

#!E:\machinelearning\KNN\python
# -*- coding:UTF-8 -*-
import kNN
group,labels = kNN.createDataSet()
print group
print labels


在sublime中配置好python的开发环境,ctrl+B就可以运行,显示如下图中所示的结果,则证明我们的所写的模块也可以说成是我们所定义的函数正常:



3.1用该算法分类

接上面,继续在kNN.py中定义一个函数classify0,如下中所示

def classify0(inX, dataSet, labels, 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):
voteLabel = labels[sortedDistIndicies[i]]
classCount[voteLabel] = classCount.get(voteLabel,0) + 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]


代码解释:

dataSetSize = dataSet.shape[0]:中,可以看到一个shape,这是一个属性,shape[0]:求数组中第一维数(二维数组中指行数),shape[1]:就是求数组中第二维数(二维数组中指列数)在本例中,dataSet.shape[0]= 6,dataSet.shape[1]=2;

diffMata = tile(inX,(dataSetSize,1))-dataSet:其中tile是指模板numpy.lib.shape_base中的函数,函数的形式是tile(A,reps),功能是重复某个数组,将A重复reps次,然后元素相减。

sqDiffMat = diffMat**2:求平方

sqDistances = sqDiffMat.sum(axis=1):axis=1表示按行相加。

sortedDistIndicies = distances.argsort() :argsort() :升序排列

classCount={} 定义字典

voteLabel = labels[sortedDistIndicies[i]]:找到最小的k个邻居

classCount[voteLabel] = classCount.get(voteLabel,0) + 1:统计标签出现的次数,以下是get()方法的语法:dict.get(key, default=None),get()方法返回给定键的值。如果键不可用,则返回默认值None。本例中如果键不存在,则会返回0。

reverse=True 倒序排列,最后返回最大值。

3.2在命令行中进行测试

结果如下图中所示:



这样就完成了我们一个简单的kNN算法的python编写,你也来试试吧。

4 kNN算法进阶

4.1用kNN改进网站的配对效果

4.2手写识别系统

本文接下来的数据集合和相应代码放在:

http://download.csdn.net/detail/yywan1314520/9335021

本文根据《机器学习实站》书中安排进行,关于代码的完整注释最后会放到github上,敬请大家关注。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: