一、KNN算法描述

  KNN(K Near Neighbor):找到k个最近的邻居,即每个样本都可以用它最接近的这k个邻居中所占数量最多的类别来代表。KNN算法属于有监督学习方式的分类算法,所谓K近邻算法,就是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(就是上面提到的K个邻居),如果这K个实例的多数属于某个类,就将该输入实例分类到这个类中,如下图所示。

                            

  上图中有两种不同类别的样本数据,分别用蓝色正方形和红色三角形表示,最中间绿色的圆表示的数据则是待分类的数据。我们现在要解决的问题是:不知道中间的圆是属于哪一类(正方形类还是三角形类)?我们下面就来给圆分类。

  从图中还能看出:如果K=3,圆的最近的3个邻居是2个三角形和1个正方形,少数从属于多数,基于统计的方法,判定圆标示的这个待分类数据属于三角形一类。但是如果K=5,圆的最近的5个邻居是2个三角形和3个正方形,还是少数从属于多数,判定圆标示的这个待分类数据属于正方形这一类。由此我们可以看到,当无法判定当前待分类数据从属于已知分类中的哪一类时,可以看它所处的位置特征,衡量它周围邻居的权重,而把它归为权重更大的一类,这就是K近邻算法分类的核心思想。


二、代码实现

算法步骤:

  1. 计算已知类别数据集中的点与当前点之间的距离;
  2. 按照距离递增依次排序;
  3. 选取与当前点距离最小的K个点;
  4. 确定前k个点所在类别的出现频率;
  5. 返回前k个点出现频率最高的类别作为当前点的预测分类
"""
kNN: k Nearest Neighbors Input: inX: vector to compare to existing dataset (1xN)
dataSet: size m data set of known vectors (NxM)
labels: data set labels (1xM vector)
k: number of neighbors to use for comparison (should be an odd number) Output: the most popular class label
""" from numpy import *
import operator
from os import listdir def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet #将inX重复成dataSetSize行1列,tile(A,n),功能是将数组A重复n次,构成一个新的数组
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1) #sum(axis=1)就是将矩阵的每一行向量相加
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort() #argsort()得到的是排序后数据原来位置的下标
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]#确定前k个距离最小元素所在的主要分类labels
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#计算各个元素标签的出现次数(频率),当voteIlabel在classCount中时,classCount.get()返回1,否则返回0
#operator.itemgetter(1)表示按照第二个元素的次序对元组进行排序,reverse=True表示为逆序排序,即从大到小排序
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0] #最后返回发生频率最高的元素标签

  classify0()函数有4个输入参数:用于分类的输入向量是inX,输入的训练样本集为dataSet,标签向量为labels,最后的参数k表示用于选择最近邻居的数目,其中标签向量的元素数目和矩阵dataSet的行数相同。除了K值之外,kNN算法的另一个核心参数是距离函数的选择。上述代码使用的是欧式距离,在日常生活中我们所说的距离往往是欧氏距离,也即平面上两点相连后线段的长度。欧氏距离的定义如下:

                         

除此之外,在机器学习中常见的距离定义有以下几种:

  • 汉明距离:两个字符串对应位置不一样的个数。汉明距离是以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数;

  • 马氏距离:表示数据的协方差距离。计算两个样本集相似度的距离;

  • 余弦距离:两个向量的夹角作为一种判别距离的度量;

  • 曼哈顿距离:两点投影到各轴上的距离总和;

  • 切比雪夫距离:两点投影到各轴上距离的最大值;

  • 标准化欧氏距离: 欧氏距离里每一项除以标准差。

还有一种距离叫闵可夫斯基距离,如下:

                       

q1时,即为曼哈顿距离。当q2时,即为欧氏距离。

在这里介绍距离的目的一个是为了让大家使用k近邻算法时,如果发现效果不太好时,可以通过使用不同的距离定义来尝试改进算法的性能。


KNN算法的优缺点

优点:

  1. 理解简单,数学知识基本为0

  2. 既能用于分来,又能用于回归;

  3. 支持多分类。

kNN算法可以用于回归,回归的思路是将离待测点最近的k个点的平均值作为待测点的回归预测结果。

kNN算法在测试阶段是看离待测点最近的k个点的类别比分,所以不管训练数据中有多少种类别,都可以通过类别比分来确定待测点类别。

注:当然会有类别比分打平的情况,这种情况下可以看待测点离哪个类别最近,选最近的类别作为待测点的预测类别。

缺点:

当然kNN算法的缺点也很明显,就是当训练集数据量比较大时,预测过程的效率很低。这是因为kNN算法在预测过程中需要计算待测点与训练集中所有点的距离并排序。可想而知,当数据量比较大的时候,效率会奇低。对于时间敏感的业务不太适合。

三、使用sklearn进行KNN分类与回归算法

1.使用sklearn中的kNN算法进行分类

sklearn中KNeighborsClassifier的参数

比较常用的参数有以下几个:

  • n_neighbors,即K近邻算法中的K值,为一整数,默认为5

  • metric,距离函数。参数可以为字符串(预设好的距离函数)或者是callable(可调用对象,大家不明白的可以理解为函数即可)。默认值为闵可夫斯基距离;

  • p,当metric为闵可夫斯基距离公式时,上文中的q值,默认为2

代码实现:

from sklearn.neighbors import KNeighborsClassifier

def classification(train_feature, train_label, test_feature):
'''
使用KNeighborsClassifier对test_feature进行分类
:param train_feature: 训练集数据
:param train_label: 训练集标签
:param test_feature: 测试集数据
:return: 测试集预测结果
''' clf = KNeighborsClassifier()
clf.fit(train_feature, train_label)
predict_result = clf.predict(test_feature)
return predict_result

2.使用sklearn中的kNN算法进行回归

当我们需要使用kNN算法进行回归器时,只需要把KNeighborsClassifier换成KNeighborsRegressor即可。KNeighborsRegressorKNeighborsClassifier的参数是完全一样的,所以在优化模型时可以参考上述的内容。

代码实现:

from sklearn.neighbors import KNeighborsRegressor

def regression(train_feature, train_label, test_feature):
'''
使用KNeighborsRegressor对test_feature进行分类
:param train_feature: 训练集数据
:param train_label: 训练集标签
:param test_feature: 测试集数据
:return: 测试集预测结果
''' clf = KNeighborsRegressor()
clf.fit(train_feature, train_label)
predict_result = clf.predict(test_feature)
return predict_result

上述为KNN算法的简述

机器学习-K近邻(KNN)算法详解的更多相关文章

  1. 算法代码[置顶] 机器学习实战之KNN算法详解

    改章节笔者在深圳喝咖啡的时候突然想到的...之前就有想写几篇关于算法代码的文章,所以回家到以后就奋笔疾书的写出来发表了 前一段时间介绍了Kmeans聚类,而KNN这个算法刚好是聚类以后经常使用的匹配技 ...

  2. 机器学习经典算法具体解释及Python实现--K近邻(KNN)算法

    (一)KNN依旧是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习全部算法中理论最简单.最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值 ...

  3. 机器学习-KNN算法详解与实战

    最邻近规则分类(K-Nearest Neighbor)KNN算法 1.综述 1.1 Cover和Hart在1968年提出了最初的邻近算法 1.2 分类(classification)算法 1.3 输入 ...

  4. knn算法详解

    邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代 ...

  5. 机器学习_K近邻Python代码详解

    k近邻优点:精度高.对异常值不敏感.无数据输入假定:k近邻缺点:计算复杂度高.空间复杂度高 import numpy as npimport operatorfrom os import listdi ...

  6. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  7. 机器学习之路--KNN算法

    机器学习实战之kNN算法   机器学习实战这本书是基于python的,如果我们想要完成python开发,那么python的开发环境必不可少: (1)python3.52,64位,这是我用的python ...

  8. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  9. kmp算法详解

    转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...

随机推荐

  1. 如何调试手机上的网页以及基于Cordova/Phonegap的Hybrid应用

    开发手机页面以及Hybird应用时,调试曾经是个老大难问题,不时需要用写log等方式曲线救国. 实际上,Chrome和Android(需要4.4+版本)已经提供了不亚于电脑版本的调试功能,只是看样子还 ...

  2. Dependabot 开始支持 pub package 版本检测

    今年年初,我们发布了 Flutter 2022 产品路线图,其中「基础设施建设」这部分提到:2022 年 Flutter 团队将增加对供应链的安全的投入,目的是达到符合基础设施 SLSA 4 级别中描 ...

  3. 关于fiddler抓包一键生成python脚本

    本人贡献一篇关于抓包转换成脚本的文章 步骤一 打开fiddler,抓到包之后,保存成txt文件 步骤二 脚本里str_filename改成保存的文件名 步骤三 执行脚本一键转换 附上脚本,感谢关注~ ...

  4. VUE 日期组件(包括年选择)

    封装vant 日期组件实现可以选择年份 <template> <div class="yearMonMain"> <div class="l ...

  5. v-show与v-if的一次事故

    v-show等同于设置dom元素的display为none,dom元素没有消失而是被隐藏了 v-if是删除或添加dom元素,频繁地删除和添加dom元素会比较耗费性能

  6. SSM框架中返回的是字符串还是页面跳转的问题

    如果你在控制器前的注解是@RestController的话,将返回controller方法指定的String值,@RestController注解相当于@ResponseBody和@Controlle ...

  7. python学习-Day38-HTML

    目录 前端 简介 什么是前端 什么是后端 前端特点 前端主要技术: 前端相关技能 关于 HTTP 的知识在这里 HTML 什么是HTML HTML 实例 实例解析 HTML 标签 HTML 元素 HT ...

  8. java基础4.20

    1.是否可以从一个static方法内部发出对非static方法的调用? 不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时 ...

  9. windows下载安装JDK8

    一 .下载链接 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 根据自己的电脑安 ...

  10. data structure assignment problem record

    Question1: Similar to pause command in linux read -n 1 Question2 read : Illegal option -n 原因为ubuntu ...