Python K最近邻从原理到实现的方法
作者:拾毅者 发布时间:2022-10-13 09:41:45
本来这篇文章是5月份写的,今天修改了一下内容,就成今天发表的了,CSDN这是出BUG了还是什么改规则了。。。
引文:决策树和基于规则的分类器都是积极学习方法(eager learner)的例子,因为一旦训练数据可用,他们就开始学习从输入属性到类标号的映射模型。一个相反的策略是推迟对训练数据的建模,直到需要分类测试样例时再进行。采用这种策略的技术被称为消极学习法(lazy learner)。最近邻分类器就是这样的一种方法。
注:KNN既可以用于分类,也可以用于回归。
1.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太大,最近分类器可能会误会分类测试样例,因为最近邻列表中可能包含远离其近邻的数据点。(如下图所示)
K较大时的最近邻分类
可见,K值的选取还是非常关键。
2.算法算法描述
k近邻算法简单、直观:给定一个训练数据集(包括类别标签),对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。下面是knn的算法步骤。
算法步骤如下所示:
对每个测试样例,算法计算它和所有训练样例之间的距离(如欧氏距离,或相似度),以确定其最近邻列表。如果训练样例的数目很大,那么这种计算的开销就会很大。不过,可以使索引技术降低为测试样例找最近邻是的计算量。
特征空间中两个实例点的距离是两个实例相似程度的反映。
一旦得到最近邻列表,测试样例就可以根据最近邻的多数类进行分类,使用多数表决方法。
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)
附件(两张自己的计算过程图):
1 KNN算法核心部分
图2 KNN计算过程
说明:上述图片仅供参考,看不懂就自己测试一组数据如[0,1]慢慢推导一下吧
来源:https://blog.csdn.net/dream_angel_z/article/details/45896449


猜你喜欢
- 本文实例讲述了Python中xml和json格式相互转换操作。分享给大家供大家参考,具体如下:Python中xml和json格式是可以互转的
- 关于tensor.repeat()的使用考虑到很多人在学习这个函数,我想在这里提 一个建议:强烈推荐 使用 einops 模块中的 repe
- 在类unix中,是\n (0x0A)。以为没有什么大的问题,没想到,这次开发一个小程序,却让我对这个问题大为头痛。 首先发现这个问题是这样的
- 有个小项目,碰到需要批量建立输入框的需求,本文利用WxPython建立批量录入框窗口研究了一下WxPython ,实现了这个功能。# cod
- mysql蠕虫复制,简单来说就是将查询出来的数据不断的新增插入到指定的数据表中。通常情况,mysql蠕虫复制时用来测试表压力。下面我们就结合
- 取行和列的几种常用方式:data[ 列名 ]: 取单列或多列,不能用连续方式取,也不能用于取行。data.列名: 只用于取单列,不能用于行。
- 在keras中,数据是以张量的形式表示的,不考虑动态特性,仅考虑shape的时候,可以把张量用类似矩阵的方式来理解。例如[[1],[2],[
- 安装redis并启动下载地址,选择Stable版本下载或者本地下载地址:https://www.jb51.net/softs/504128.
- 1、从数据库表中检索信息实际上,前面我们已经用到了SELECT语句,它用来从数据库表中检索信息。select语句格式一般为:SELECT 检
- 银行跨行转账业务是一个典型分布式事务场景,假设 A 需要跨行转账给 B,那么就涉及两个银行的数据,无法通过一个数据库的本地事务保证转账的 A
- try-except作用:处理异常情况用法:try:后面写正常运行的代码,except + 异常情况:后面写对异常情况的处理示例:try:
- function map(a,f){f(a);} function getRand(a,b) {  
- docker-compose.yal文件中: redis: image: redis container_name:
- 一、查看event是否开启show variables like '%sche%'; set global ev
- 分享由字符“\”转义引起的SQL数据库实例名称找不到或远程连接失败并显示错误error40的解决办法:一、问题介绍很久没有用c#去连数据库程
- frame标签有frameset、frame、iframe三种,frameset和其它普通标签没有区别,不会影响正常定位,而frame与if
- 效果图:代码如下:<!DOCTYPE html><html><head> <meta
- 1,不带参数的存储过程2,带输入参数的存储过程3,带输入和输出参数的存储过程4,带返回值的存储过程不带参数的存储过程例如,以下存储过程返回E
- 有一个txt文本如下:151 151 1234561 156421 214156 1523132 031320现希望将两行合并为一行,并将
- 新公司是内网环境,无法使用pip安装第三方资源库,在网上搜下,可以直接使用pip打包本机所安装的第三方资源库,打包成whl文件一 进入cmd