您的位置:首页 > 其它

【Machine Learning in Action --2】K-最近邻分类

2015-09-15 23:30 162 查看
1、K-近邻算法(KNN)概述

K-近邻算法采用测量不同特征值之间的距离方法进行分类。

工作原理:存在一个样本数据集合(也称作训练样本集),并且样本集中每个数据都存在标签(即我们知道样本集中每一数据与所属分类的对应关系)。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

例如:电影分类,用K-近邻算法分类爱情片和动作片,假如有一部未看过的电影,如何确定它是爱情片还是动作片?

表1 每部电影的打斗镜头数、接吻镜头数以及电影评估类型

电影名称打斗镜头接吻镜头电影类型
California Man3104爱情片
He's Not Really into Dudes2100爱情片
Beautiful Woman181爱情片
Kevin Longblade10110动作片
Robo Slayer 3000995动作片
Amped II982动作片
?1890未知
首先计算未知电影与样本集中其他电影的距离(先忽略如何计算得到这些距离值),如表2

表2 已知电影与未知电影的距离

电影名称与未知电影的距离
California Man20.5
He's Not Really into Dudes18.7
Beautiful Woman19.2
Kevin Longblade115.3
Robo Slayer 3000117.4
Amped II118.9
现在按照距离递增排序,可以找到K个距离最近的电影。假定K=3,则三个最靠近的电影依次是He's Not Really into Dudes、Beautiful Woman、California Man。K-近邻算法按照距离最近的三部电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。

2、K-近邻算法的一般流程

(1)收集数据:可以使用任何方法

(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式

(3)分析数据:可以使用任何方法

(4)训练算法:此步骤不适合用于K-近邻算法

(5)测试算法:计算错误率

(6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行K-近邻算法判定输入数据分别属于那个类别,最后应用对计算出的分类执行后续的处理。

3、用python实现kNN算法

首先创建名为kNN.py模块



在kNN.py文件中增加下面代码:

# -*- coding: utf-8 -*-

from numpy import *     #引入科学计算包numpy
import operator         #经典python函数库,运算符模块。
#创建数据集
def createDataSet():
group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels=['A','A','B','B']
return group,labels
#k-近邻算法核心
#inX:用户分类的输入向量,即将对其进行分类
#dataSet:训练样本集
#labels:标签向量
def classifyO(inX,dataSet,labels,k):
#距离计算
dataSetSize=dataSet.shape[0] #得到数组的行数,即知道有几个训练数据,这里为4
diffMat=tile(inX,(dataSetSize,1))-dataSet  #tile是numpy中的函数,tile将一个数组,扩充成了4个一样的数组;diffMat得到目标与训练数值之间的差值
sqDiffMat=diffMat**2         #各个差值分别平方
sqDistances=sqDiffMat.sum(axis=1)  #对平方后的数据求和,sum(axis=1)表示求矩阵的行的和
distances=sqDistances**0.5   #开方,得到距离
sortedDistIndicies=distances.argsort()  #对距离进行升序排列
#选择距离最小的k个点
classCount={}
for i in range(k):
voteIlabel=labels[sortedDistIndicies[i]]  #获得前k个距离对应的类标签
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1 #对这些类标签进行统计,求出对应的数量,形成的列表有两列,一列为类标签,一列为数量
#排序
sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)  #对上面前k个类标签数量进行排序
return sortedClassCount[0][0] #取最小的距离对应的类标签


在centos中运行(kNN.py在desktop/algorithm/)

#cd algorithm
#python
>>>import kNN
>>>group,labels=kNN.createDataSet()
>>>group
array([[1. , 1.1],
[1. , 1.  ],
[0. , 0.  ],
[0. , 0.1] ])
>>>labels
['A','A','B','B']
>>>kNN.classifyO([0,0],group,labels,3) #输入[0,0]测试值,测试运行结果
'B'


4、kNN算法的优缺点

优点:精度高,对异常数据不敏感(你的类别是由邻居中的大多数决定的,一个异常邻居并不能影响太大),无数据输入假定;

缺点:计算发杂度高(需要计算新的数据点与样本集中每个数据的“距离”,以判断是否是前k个邻居),空间复杂度高(巨大的矩阵);无法给出任何数据的基础结构信息,无法知晓平均实例样本和典型实例样本具有什么特征。

适用数据范围:数值型(目标变量可以从无限的数值集合中取值)和标称型(目标变量只有在有限目标集中取值)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: