Python K最近邻从原理到实现的方法


Posted in Python onAugust 15, 2019

本来这篇文章是5月份写的,今天修改了一下内容,就成今天发表的了,CSDN这是出BUG了还是什么改规则了。。。

引文:决策树和基于规则的分类器都是积极学习方法(eager learner)的例子,因为一旦训练数据可用,他们就开始学习从输入属性到类标号的映射模型。一个相反的策略是推迟对训练数据的建模,直到需要分类测试样例时再进行。采用这种策略的技术被称为消极学习法(lazy learner)。最近邻分类器就是这样的一种方法。

注:KNN既可以用于分类,也可以用于回归。

1.K最近邻分类器原理

首先给出一张图,根据这张图来理解最近邻分类器,如下:

Python K最近邻从原理到实现的方法

根据上图所示,有两类不同的样本数据,分别用蓝色的小正方形红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,现在, 我们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形or红色小三角形),下面,我们就要解决这个问题:给这个绿色的圆分类。

我们常说,物以类聚,人以群分,判别一个人是一个什么样品质特征的人,常常可以从他or她身边的朋友入手,所谓观其友,而识其人。我们不是要判别上图中那个绿色的圆是属于哪一类数据么,好说,从它的邻居下手。但一次性看多少个邻居呢?从上图中,你还能看到:

  • 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
  • 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。

于此我们看到,当无法判定当前待分类点是从属于已知分类中的哪一类时,我们可以依据统计学的理论看它所处的位置特征,衡量它周围邻居的权重,而把它归为(或分配)到权重更大的那一类。这就是K近邻算法的核心思想。其关键还在于K值的选取,所以应当谨慎。

KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

KNN 算法本身简单有效,它是一种 lazy-learning 算法,分类器不需要使用训练集进行训练,训练时间复杂度为0。KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为 n,那么 KNN 的分类时间复杂度为O(n)。

前面的例子中强调了选择合适的K值的重要性。如果太小,则最近邻分类器容易受到训练数据的噪声而产生的过分拟合的影响;相反,如果K太大,最近分类器可能会误会分类测试样例,因为最近邻列表中可能包含远离其近邻的数据点。(如下图所示)

Python K最近邻从原理到实现的方法 

K较大时的最近邻分类

可见,K值的选取还是非常关键。

2.算法算法描述

k近邻算法简单、直观:给定一个训练数据集(包括类别标签),对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。下面是knn的算法步骤。

算法步骤如下所示:

Python K最近邻从原理到实现的方法

对每个测试样例z=(x′,y′),算法计算它和所有训练样例(x,y)属于D之间的距离(如欧氏距离,或相似度),以确定其最近邻列表Dz。如果训练样例的数目很大,那么这种计算的开销就会很大。不过,可以使索引技术降低为测试样例找最近邻是的计算量。

特征空间中两个实例点的距离是两个实例相似程度的反映。

一旦得到最近邻列表,测试样例就可以根据最近邻的多数类进行分类,使用多数表决方法。

K值选择

k值对模型的预测有着直接的影响,如果k值过小,预测结果对邻近的实例点非常敏感。如果邻近的实例恰巧是噪声数据,预测就会出错。也就是说,k值越小就意味着整个模型就变得越复杂,越容易发生过拟合。

相反,如果k值越大,有点是可以减少模型的预测误差,缺点是学习的近似误差会增大。会使得距离实例点较远的点也起作用,致使预测发生错误。同时,k值的增大意味着模型变得越来越简单。如果k=N,那么无论输入实例是什么,都将简单的把它预测为样本中最多的一类。这显然实不可取的。

在实际建模应用中,k值一般取一个较小的数值,通常采用cross-validation的方法来选择最优的k值。

3.K最邻近算法实现(Python)

KNN.py(代码来源《机器学习实战》一书)

from numpy import *
import operator

class KNN:
  def createDataset(self):
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group,labels

  def KnnClassify(self,testX,trainX,labels,K):
    [N,M]=trainX.shape

  #calculate the distance between testX and other training samples
    difference = tile(testX,(N,1)) - trainX # tile for array and repeat for matrix in Python, == repmat in Matlab
    difference = difference ** 2 # take pow(difference,2)
    distance = difference.sum(1) # take the sum of difference from all dimensions
    distance = distance ** 0.5
    sortdiffidx = distance.argsort()

  # find the k nearest neighbours
    vote = {} #create the dictionary
    for i in range(K):
      ith_label = labels[sortdiffidx[i]];
      vote[ith_label] = vote.get(ith_label,0)+1 #get(ith_label,0) : if dictionary 'vote' exist key 'ith_label', return vote[ith_label]; else return 0
    sortedvote = sorted(vote.iteritems(),key = lambda x:x[1], reverse = True)
    # 'key = lambda x: x[1]' can be substituted by operator.itemgetter(1)
    return sortedvote[0][0]

k = KNN() #create KNN object
group,labels = k.createDataset()
cls = k.KnnClassify([0,0],group,labels,3)
print cls

运行:
1. 在Python Shell 中可以运行KNN.py

>>>import os
>>>os.chdir("/home/liudiwei/code/data_miningKNN/")
>>>execfile("KNN.py")

输出:B
(B表示类别)

2.或者terminal中直接运行

$ python KNN.py

3.也可以不在KNN.py中写输出,而选择在Shell中获得结果,i.e.,

>>>import KNN
>>> KNN.k.KnnClassify([0,0],KNN.group,KNN.labels,3)

附件(两张自己的计算过程图):

Python K最近邻从原理到实现的方法 

1 KNN算法核心部分

Python K最近邻从原理到实现的方法 

图2 KNN计算过程

说明:上述图片仅供参考,看不懂就自己测试一组数据如[0,1]慢慢推导一下吧

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 第一步 hello world
Sep 25 Python
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
Nov 27 Python
用Python实现一个简单的能够发送带附件的邮件程序的教程
Apr 08 Python
深入解析Python编程中JSON模块的使用
Oct 15 Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 Python
tensorflow实现图像的裁剪和填充方法
Jul 27 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
May 27 Python
Django ModelForm组件使用方法详解
Jul 23 Python
Python 实现大整数乘法算法的示例代码
Sep 17 Python
python 多进程队列数据处理详解
Dec 23 Python
python实现简单俄罗斯方块
Mar 13 Python
django下创建多个app并设置urls方法
Aug 02 Python
Python数据可视化 pyecharts实现各种统计图表过程详解
Aug 15 #Python
浅谈Python 敏感词过滤的实现
Aug 15 #Python
pycharm创建scrapy项目教程及遇到的坑解析
Aug 15 #Python
通过selenium抓取某东的TT购买记录并分析趋势过程解析
Aug 15 #Python
Python依赖包整体迁移方法详解
Aug 15 #Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 #Python
python 修改本地网络配置的方法
Aug 14 #Python
You might like
多个PHP中文字符串截取函数
2013/11/12 PHP
PHP 之 写时复制介绍(Copy On Write)
2014/05/13 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
PHP中list()函数用法实例简析
2016/01/08 PHP
PHP+Ajax实现验证码的实时验证
2016/07/20 PHP
PHP命名空间namespace用法实例分析
2016/09/27 PHP
asp批量修改记录的代码
2008/06/25 Javascript
Javascript 函数对象的多重身份
2009/06/28 Javascript
可在线编辑网页文字效果代码(单击)
2013/03/02 Javascript
JS获取客户端IP地址、MAC和主机名的7个方法汇总
2014/07/21 Javascript
Javascript学习笔记之函数篇(六) : 作用域与命名空间
2014/11/23 Javascript
推荐10 款 SVG 动画的 JavaScript 库
2015/03/24 Javascript
JS中获取函数调用链所有参数的方法
2015/05/07 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
2016/04/07 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
JavaScript注入漏洞的原理及防范(详解)
2016/12/04 Javascript
Bootstrap表单控件学习使用
2017/03/07 Javascript
微信小程序实战之轮播图(3)
2017/04/17 Javascript
Vue.js图片预览插件使用详解
2018/08/27 Javascript
Vue 动态组件与 v-once 指令的实现
2019/02/12 Javascript
详解React项目中碰到的IE问题
2019/03/14 Javascript
vue路由对不同界面进行传参及跳转的总结
2019/04/20 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
神经网络理论基础及Python实现详解
2017/12/15 Python
python pandas读取csv后,获取列标签的方法
2018/11/12 Python
如何用Python来搭建一个简单的推荐系统
2019/08/07 Python
python实现批量修改服务器密码的方法
2019/08/13 Python
Python for循环及基础用法详解
2019/11/08 Python
如何使用Python脚本实现文件拷贝
2019/11/20 Python
基于python-pptx库中文文档及使用详解
2020/02/14 Python
日语求职信范文
2013/12/17 职场文书
茶叶生产计划书
2014/01/10 职场文书
自我鉴定注意事项
2014/01/19 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
人力资源求职信
2014/05/25 职场文书
教师听课评语大全
2014/12/31 职场文书