1 前言  

  Kjin邻法(k-nearest neighbors,KNN)是一种基本的机器学*方法,采用类似“物以类聚,人以群分”的思想。比如,判断一个人的人品,只需观察他来往最密切的几个人的人品好坏就可以得出。这里就运用了KNN的思想。KNN方法可以做分类,也可以做回归,这点和决策树算法相同。

  KNN做回归和分类的主要区别在于做预测时候的决策方式不同。

  KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最jin的K个样本,预测为里面有最多类别数的类别。
  KNN做回归时,一般是选择平均法,即最jin的K个样本的样本输出的平均值作为回归预测值。

2 KNN算法原理  

  给定一个训练集,对新输入的实例,在训练集中找到与该实例最邻jin的k个实例,这k个实例的多数属于某个类,我们就把该输入实例分为这个类。

2.1 算法描述

  输入:训练数据集$T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}$,其中$x_i\in{\chi}$为实例的特征向量,$y_i\in{\{c_1,c_2,...,c_m\}}$为实例的类别,实例特征向量x。
  输出:实例 x 所属的类别 y。
  1.根据给定的距离度量方式,在训练集T中找到与x最邻jin的k个点,涵盖着k个点的x的领域记住$N_k(x)$。
  2.在$N_k(x)$中根据分类决策规则决定x的类别y
    $y=argmax_{c_j}\sum_{x_i\in{N_k(x)}}I(y_i=c_j)$
  其中$I(y_i=c_j)$为指示函数,当$y_i=c_j$的时候$I=1$,后者$I=0$ 。

3. KNN的基本要素

  对于一个确定的训练集,确定距离度量、k值和分类决策规则,就能对任何一个新的实例,确定它的分类。

3.1 距离度量

  距离度量是描述特征空间中两个实例的距离,也是这两个实例的相似程度。在n维实数向量空间中,我们主要使用的距离度量方式是欧式距离,但也可以使用更加一般化$L_p$距离(闵可夫斯基距离)。
  在特征空间中,取出两个特征$x_i$,$x_j$,它们分别是n维的特征向量。
  Lp距离(闵可夫斯基距离)
    $L_p(x_i,x_j)=(\sum_{l=1}^n|x_i^l-x_j^l|^p)^{\frac{1}{p}}$
  欧氏距离
    $L_2(x_i,x_j)=(\sum_{l=1}^n|x_i^l-x_j^l|^2)^{\frac{1}{2}}$
  曼哈顿距离
    $L_1(x_i,x_j)=\sum_{l=1}^n|x_i^l-x_j^l|$
  $L_{\infty}$距离
    $L_{\infty}(x_i-x_j)=\max_{l}|x_i^l-x_j^l|$

3.2 k值的选择

  对于k值的选择,没有一个固定的经验,一般根据样本的分布,选择一个较小的值,然后通过交叉验证选择一个合适的k值。
  • 如果选择较小的K值
    • “学*”的jin似误差(aproximation eror)会减小,但 “学*”的估计误差(estimation eror) 会增大。
    • 噪声敏感。
    • K值的减小就意味着整体模型变得复杂,容易发生过 拟合。
  • 如果选择较大的K值,
    •减少学*的估计误差,但缺点是学*的jin似误差增大。
    •K值的增大 就意味着整体的模型变得简单。
  一个极端是k等于样本数m,则完全没有分类,此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单。

3.3 分类决策规则

  对于分类决策规则,一般都是使用前面提到的多数表决法。

4. kd树  

  KNN算法最简单的实现方式:计算输入实例和所有训练实例的距离,进行排序,取前k个,进行分类。当训练集特别大的时候,非常耗时。
  下面介绍kd树的方式,kd树通过减少输入实例和训练实例的计算次数来达到优化的目的。
  kd树是一种对K维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。
  kd树是二叉树,表示对K维空间的一个划分。构造Kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一 系列的k维超矩形区域。Kd树的每个结点对应于一个k维超矩形区域.
  kd树算法包括三步,第一步是建树,第二步是搜索最jin邻,最后一步是预测。

  

4.2 kd树搜索最jin邻居

  当我们生成kd树以后,就可以去预测测试集里面的样本目标点了。预测的过程如下:
  1、对于一个目标点,我们首先在kd树里面找到包含目标点的叶子节点。以目标点为圆心,以目标点到叶子节点样本实例的距离为半径,得到一个超球体,最jin邻的点一定在这个超球体内部。
  2、然后返回叶子节点的父节点,检查另一个子节点包含的超矩形体是否和超球体相交,如果相交就到这个子节点寻找是否有更加jin的jin邻,有的话就更新最jin邻,并且更新超球体。如果不相交那就简单了,我们直接返回父节点的父节点,在另一个子树继续搜索最jin邻。
  3、当回溯到根节点时,算法结束,此时保存的最jin邻节点就是最终的最jin邻。
  从上面的描述可以看出,kd树划分后可以大大减少无效的最jin邻搜索,很多样本点由于所在的超矩形体和超球体不相交,根本不需要计算距离。大大节省了计算时间。
  搜索过程,大致如下:

4.3 kd树预测

  有了kd树搜索最jin邻的办法,kd树的预测就很简单了,在kd树搜索最jin邻的基础上,我们选择到了第一个最jin邻样本,就把它置为已选。在第二轮中,我们忽略置为已选的样本,重新选择最jin邻,这样跑k次,就得到了目标的k个最jin邻。然后根据多数表决法,如果是KNN分类,预测为k个最jin邻里面有最多类别数的类别。如果是KNN回归,用k个最jin邻样本输出的平均值作为回归预测值。

4.4 示例:使用k-jin邻算法进行分类

from sklearn.datasets import make_blobs
# 生成数据
"""
代码中,生成60个训练样本,这60个样本分布在以centers参数指定中心点周围。cluster_std是标准差,用来指明生成的点分布的松散程度。
生成的训练数据集放在变量X里面,数据集的类别标记放在y里面。
make_blobs函数是为聚类产生数据集
产生一个数据集和相应的标签
n_samples:表示数据样本点个数,默认值100
n_features:表示数据的维度,默认值是2
centers:产生数据的中心点,默认值3
cluster_std:数据集的标准差,浮点数或者浮点数序列,默认值1.0
center_box:中心确定之后的数据边界,默认值(-10.0, 10.0)
shuffle :洗乱,默认值是True
random_state:官网解释是随机生成器的种子
"""
centers = [[-2,2], [2,2], [0,4]]
X, y = make_blobs(n_samples=100,centers=centers,random_state=6, cluster_std=0.60)
print(X) #坐标点
print(y) #类别
# 画出数据
"""
这些点的分布情况在坐标轴上一目了然,其中三角形的点即各个类别的中心节点。
"""
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16,10), dpi=144)
c = np.array(centers)
# 画出样本
plt.scatter(X[:,0], X[:,1], c=y, s=100, cmap='cool')
# 画出中心点
plt.scatter(c[:,0], c[:,1], s=100, marker='^',c='orange')
plt.savefig('knn_centers.png')
plt.show() # 使用KNeighborsClassifier对算法进行训练,我们选择参数k=5
from sklearn.neighbors import KNeighborsClassifier
# 模型训练
k = 5
clf = KNeighborsClassifier(n_neighbors = k)
clf.fit(X, y)
# 对一个新样本进行预测:
# 进行预测
"""
我们要预测的样本是[0, 2],使用kneighbors()方法,把这个样本周围距离最*的5个点取出来。
取出来的点是训练样本X里的索引,从0开始计算。
"""
X_sample = np.array([[0, 2]])
y_sample = clf.predict(X_sample)
neighbors = clf.kneighbors(X_sample, return_distance=False) # 把待预测的样本以及和其最*的5个样本在图上标记出来。
# 画出示意图
plt.figure(figsize=(16,10), dpi=144)
c = np.array(centers)
plt.scatter(X[:,0], X[:,1], c=y, s=100, cmap='cool') # 出样本
plt.scatter(c[:,0], c[:,1], s=100, marker='^',c='k') # 中心点
plt.scatter(X_sample[0][0], X_sample[0][1], marker="x",
s=100, cmap='cool') # 待预测的点
for i in neighbors[0]:
plt.plot([X[i][0], X_sample[0][0]], [X[i][1], X_sample[0][1]],
'k--', linewidth=0.6) # 预测点与距离最*的5个样本的连线
plt.savefig('knn_predict.png')
plt.show()

机器学*——K*邻算法(KNN)的更多相关文章

  1. 【机器学*与R语言】2-懒惰学*K*邻(kNN)

    目录 1.理解使用KNN进行分类 KNN特点 KNN步骤 1)计算距离 2)选择合适的K 3)数据准备 2.用KNN诊断乳腺癌 1)收集数据 2)探索和准备数据 3)训练模型 4)评估模型的性能 5) ...

  2. 【机器学*】k*邻算法-02

    k邻*算法具体应用:2-2约会网站配对 心得体会: 1.对所有特征值进行归一化处理:将特征值单位带来的距离影响消除,使所有特征同权重--然后对不同的特征进行加权2.对于相互独立的特征,可以通过建立(特 ...

  3. 【机器学*】k-*邻算法(kNN) 学*笔记

    [机器学*]k-*邻算法(kNN) 学*笔记 标签(空格分隔): 机器学* kNN简介 kNN算法是做分类问题的.思想如下: KNN算法的思想总结一下:就是在训练集中数据和标签已知的情况下,输入测试数 ...

  4. k近邻算法(KNN)

    k近邻算法(KNN) 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. from sklearn.model_selection ...

  5. 什么是机器学习的分类算法?【K-近邻算法(KNN)、交叉验证、朴素贝叶斯算法、决策树、随机森林】

    1.K-近邻算法(KNN) 1.1 定义 (KNN,K-NearestNeighbor) 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类 ...

  6. 【机器学*】k*邻算法-03

    心得体会: 需要思考如何将现实对象转化为特征向量,设置特征向量时记住鸭子定律1 鸭子定律1 如果走路像鸭子.说话像鸭子.长得像鸭子.啄食也像鸭子,那它肯定就是一只鸭子 事物的外在特征就是事物本质的表现 ...

  7. 【机器学*】k*邻算法-01

    k临*算法(解决分类问题): 已知数据集,以及该数据对应类型 给出一个数据x,在已知数据集中选择最接*x的k条数据,根据这k条数据的类型判断x的类型 具体实现: from numpy import * ...

  8. 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!

    1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...

  9. K-近邻算法kNN

    K-近邻算法(k-Nearest Neighbor,简称kNN)采用测量不同特征值之间的距离方法进行分类,是一种常用的监督学习方法,其工作机制很简单:给定测试样本,基于某种距离亮度找出训练集中与其靠近 ...

随机推荐

  1. 使用Cobertura做代码覆盖率测试

    经验总结:首先要把cobertura.jar包含ant的classpath路径中,其次要求它包含在测试用例的classpath中: 使用cobertura做代码覆盖率测试中出现的问题:覆盖率始终为0, ...

  2. Java Swing 盒布局管理器

    Swing 盒布局管理器 因为项目的原因,重新看看swing的东西,在想要将两个横向的容器纵向表示的时候,发现用盒布局 话不多说,直接代码 package ui; import javax.swing ...

  3. Java基础技术-Java其他主题【面试】

    Java基础技术-Java其他主题[面试] Java基础技术IO与队列 Java BIO.NIO.AIO Java 中 BIO.NIO.AIO 的区别是什么? 含义不同: BIO(Blocking I ...

  4. eclipse中添加进新的java项目中文乱码

    eclipse中添加进新的java项目中文乱码 添加学习的一些项目进eclipse中,结果其中的中文注释都变成了乱码 右击项目,点最下面的属性,出来新得弹框 在文本文件编码部分可以发现是GBK格式,选 ...

  5. NOIP 模拟 $36\; \rm Cicada 拿衣服$

    题解 \(by\;zj\varphi\) 发现右端点固定时,左端点的 \(min-max\) 单调递减,且对于 \(or\) 和 \(and\) 相减,最多有 \(\rm2logn\)个不同的值,且相 ...

  6. SpringBoot请求日期参数异常(Failed-to-convert-value-of-type-'java-lang-String'-

    问题 Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exce ...

  7. dataTemplate 之 ContentTemplate 的使用

    <Window x:Class="WpfApplication1.Window38" xmlns="http://schemas.microsoft.com/win ...

  8. HttpClient4.3教程 第四章 HTTP认证

    HttpClient既支持HTTP标准规范定义的认证模式,又支持一些广泛使用的非标准认证模式,比如NTLM和SPNEGO. 4.1.用户凭证 任何用户认证的过程,都需要一系列的凭证来确定用户的身份.最 ...

  9. servlet中servletContext的五大作用(一)

    获取web的上下文路径 获取全局的参数 作为域对象使用 请求转发 读取web项目的资源文件 package day10.about_servletcontext.get_path; /** * 首先区 ...

  10. Flink的状态管理与恢复机制

    参考地址:https://www.cnblogs.com/airnew/p/9544683.html 问题一.什么是状态? 问题二.Flink状态类型有哪几种? 问题三.状态有什么作用? 问题四.如何 ...