K-近邻分类算法解析实践

教材选用《统计学习方法》,第一版,李航著;
代码取自《机器学习实战》,人民邮电出版社;


K-近邻算法(K-NearestNeighbours)是一种最简单的基本分类方法,它的定义为:在给定训练集中,找到与新的输入实例最相近的K个实例,新实例的类型就被划分为这K个实例多数属于的类型。

K-近邻算法的模型实际对应特征空间的划分,模型由距离度量、K值的选择和分类决策规则所决定。
距离度量一般使用欧氏距离,不同的距离度量所确定的最近邻点是不同的。距离度量相关的资料点这里。
K值的选择会对模型结果产生重大影响,在应用中K一般选一个较小的值,再采用交叉验证法找出最优的K值。
分类决策规则一般选用多数表决,多数表决规则等价于经验风险最小化。

K-近邻算法最简单的实现方法是线性扫描,但考虑到效率问题采用kd树实现可以优化速度,kd树更适用于训练实例远大于空间维数时的K-近邻搜索。


K-近邻算法的特点

K-近邻算法的一般流程

以下为K-近邻算法的简单实现例子,首先将以下4个数据点分为蓝和红两类,然后通过K-近邻算法找出新输入的点属于哪一类。

1.使用Python导入数据

首先导入科学计算包numpy和operator模块,然后建立数据集,样本为4个点,前两个设为红点,后两个设为蓝点。(运行环境为Python3.6)

from numpy import *
import operator

def createDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) 
    labels = ['r','r','b','b']
    return group, labels

为了更清晰地看出数据之间的关系,通过数据可视化包matplotlib绘制出散点图。散点图的绘制教程点这里。

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(group[:,0],group[:,1],15,labels)
plt.show()
4个数据点的散点图

2.K-近邻算法的实现

接下来定义分类算法classify0(),下面是Python代码,然后会详细解释每行代码的含义。

from os import listdir

def classify0(inX, dataSet, labels, k): 
    #1 计算欧氏距离,见下方计算公式
    dataSetSize = dataSet.shape[0] #获取数据形状
    diffMat = tile(inX, (dataSetSize,1)) - dataSet #用tile()重复计算新输入分类点和样本点之前的差值数组
    sqDiffMat = diffMat**2 #将差值数组平方
    sqDistances = sqDiffMat.sum(axis=1) #将平方后的数组累加
    distances = sqDistances**0.5 #开方得欧氏距离distances 
    sortedDistIndicies = distances.argsort() #argsort()按从小到大顺序排序所有点距离
    #2 得到主要分类
    classCount={}   #新建classCount数组
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]  #取出数组标签
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #按前k个投票给点,得到主要标签
    #3 返回频率最高的分类
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

classify0有四个输入:inX为新输入的分类点,dataSet为样本训练集(4个数据点),labels为分类标签(蓝和红),k为选择近邻的参数。

1.按照公式计算新输入点和所有样本点之间的欧氏距离;


欧氏距离计算公式

2.按照从小到大的次序进行排序,确定前k个距离最小元素的主要分类;

3.将classcount分解为元组列表,按照第二个元素从大到小排序,返回频率最高的元素标签。

3.测试分类器classify0

为了测试数据所有分类,在命令行中输入如下命令:

print(classify0([0.8,0.8], group, labels, 3))  #测试用了(0.8,0.8)这个点,k值用了3

在调试模式下运行命令,查看变量的属性。dataSetSize 为4,代表样本4个点;diffMat 显示了前两个点的差值( -0.2 = 0.8 - 1)。


调试中的变量截图1

sqDiffMat 为 diffMat数组的平方; sqDiffMat 为 sqDiffMat 数组中的平方值相加;distances 为sqDiffMat 数组的开方;sortedDistIndicies 为distances 进行了排序,并取索引为新数组。


调试中的变量截图2

调试中的变量截图3

调试中的变量截图4

classcount统计出样本空间里前k=3个距离最近的点,红色的为2个,蓝色的1个;sortedclasscount为排序后的标签数组,因此预测新输入的点属于红色类别。


调试中的变量截图5

调试中的变量截图6
因此,最后按照分类器得出的结果是:r为红点。
测试结果
可视化结果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 一.图层 1)图层是什么 (1)图层的定义 (2)图层的类型 (3)图层和视图的关系 二.动画 1)动画的种类 2...
    YGoooooooooal阅读 707评论 0 0
  • 罗布胡杨 题记:罗布胡杨是生长在罗布泊的胡杨树,据说活着一千年不死,死了一千年不倒,倒下一千年不烂。是英雄之树的...
    春雪伊人阅读 544评论 4 9
  • 有些事总是要试一试的,不试怎么知道不可能! 有些想法总是要去付出行动的,不然,想法永远只是想法,永远不可能有实...
    自然也是一种范er阅读 328评论 0 0
  • 从hello world开始 准备尝试使用简书发布第一篇文章, 尝试markdown语法,粗体,斜体 文本1 文本...
    nikola阅读 139评论 0 1