# 监督学习\_K近邻法

![异世界.png](/files/nw6rbg3z9dn5dtlrsTKh)

\[TOC]

## K近邻法(KNN)

> `k近邻法`(k-nearest neighbor，k-NN)是一种基本分类与回归方法。
>
> k近邻法的输入为实例的特征向量，对应于特征空间的点；输出为实例的类别，可以取多类。
>
> k近邻法假设给定一个训练数据集，其中的实例类别已定。分类时，对新的实例，根据其k个最近邻的训练实例的类别，通过多数表决等方式进行预测。因此，k近邻法`不具有显式的学习过程`。
>
> k近邻法实际上利用训练数据集对特征向量空间进行划分，并作为其分类的“模型”。
>
> k值的选择、距离度量及分类决策规则是k近邻法的`三个基本要素`。
>
> k近邻法1968年由Cover和Hart提出。
>
> 输入：训练数据集
>
> $$
> T={ (x\_1,y\_1),(x\_2,y\_2),...,(x\_N,y\_N) }
> $$
>
> 其中，$$x\_i \in x \subseteq R^n$$为实例的特征向量，$$y\_i \in Y ={ c\_1,c\_2,...,c\_k }$$为实例的类别，$$i＝1,2,...,N$$；实例特征向量$$x$$；
>
> 输出：实例$$x$$所属的类$$y$$。
>
> 1. 根据给定距离度量，在训练集$$T$$中找出与$$x$$最邻近的$$k$$个点，涵盖这$$k$$个点的$$x$$的邻域记作$$N\_{k}(x)$$；
> 2. 在$$N\_{k}(x)$$中根据分类决策规则(如多数表决)决定$$x$$的类别$$y$$：
>
> $$
> y=\arg \max\_{c\_j}\sum\_{x\_i \in N\_k(x)}{I(y\_i=c\_j)},i=1,2,...,N;j=1,2,...,K
> $$
>
> 1. 式（3.1）中，I为指示函数，即当y i ＝c j 时I为1，否则I为0。k近邻法的特殊情况是k＝1的情形，称为最近邻算法。对于输入的实例点（特征向量）x，最近邻法将训练数据集中与x最邻近点的类作为x的类。

## k近邻模型

> k近邻法使用的模型实际上对应于对特征空间的划分。模型由三个基本要素——距离度量、k值的选择和分类决策规则决定。

### 模型

> k近邻法中，当训练集、距离度量（如欧氏距离）、k值及分类决策规则（如多数表决）确定后，对于任何一个新的输入实例，它所属的类唯一地确定。
>
> 这相当于根据上述要素将特征空间划分为一些子空间，确定子空间里的每个点所属的类。这一事实从最近邻算法中可以看得很清楚。
>
> 特征空间中，对每个训练实例点$$ix$$，距离该点比其他点更近的所有点组成一个区域，叫作单元(cell)。
>
> 每个训练实例点拥有一个单元，所有训练实例点的单元构成对特征空间的一个划分。
>
> 最近邻法将实例$$ix$$的类$$iy$$作为其单元中所有点的类标记(class label)。
>
> 这样，每个单元的实例点的类别是确定的。下图是二维特征空间划分的一个例子。
>
> <img src="/files/-Lz66mVQysu37y2Hl42T" alt="1570101631106" data-size="original">

### 距离度量

> 特征空间中两个实例点的距离是两个实例点相似程度的反映。k近邻模型的特征空间一般是$$n$$维实数向量空间$$R^n$$ 。
>
> 使用的距离是欧氏距离，但也可以是其他距离，如更一般的$$L\_p$$距离($$L\_p$$ pdistance)或Minkowski距离(Minkowski distance)。
>
> 设特征空间$$x$$是$$n$$维实数向量空间$$R^n$$ ，$$x\_i,x\_j \in X$$，
>
> $$x\_i=(x\_i^{(1)},x\_i^{(2)},...,x\_i^{(n)})^T$$，
>
> $$x\_j=(x\_j^{(1)},x\_j^{(2)},...,x\_j^{(n)})^T$$，$$x\_i$$，$$x\_j$$的$$L\_p$$距离定义为
>
> $$
> L\_p(x\_i,x\_j)=(\sum\_{l=1}^{n}{|x\_i^{(l)}-x\_j^{(l)}|^{p}})^{\frac{1}{p}}
> $$
>
> 这里$$p \geq 1$$。
>
> 当$$p＝2$$时，称为欧氏距离(Euclidean distance)，即
>
> $$
> L\_2(x\_i,x\_j)=(\sum\_{l=1}^{n}{|x\_i^{(l)}-x\_j^{(l)}|^{2}})^{\frac{1}{2}}
> $$
>
> 当$$p＝1$$时，称为曼哈顿距离(Manhattan distance)，即
>
> $$
> L\_p(x\_i,x\_j)=\sum\_{l=1}^{n}{|x\_i^{(l)}-x\_j^{(l)}|}
> $$
>
> 当$$p＝\infty$$时，它是各个坐标距离的最大值，即
>
> $$
> L\_{\infty}(x\_i,x\_j)=\max\_{l}{|x\_i^{(l)}-x\_j^{(l)}|}
> $$
>
> 下图给出了二维空间中$$p$$取不同值时，与原点的$$L\_p$$距离为1($$L\_p＝1$$)的点的图形。
>
> <img src="/files/-Lz66mVSpqlYVKK4ZhQQ" alt="1570102425834" data-size="original">

### k值的选择

> k值的选择会对k近邻法的结果产生重大影响。
>
> 如果选择较小的k值，就相当于用较小的邻域中的训练实例进行预测，“学习”的近似误差(approximation error)会减小，只有与输入实例较近的(相似的)训练实例才会对预测结果起作用。
>
> 但缺点是“学习”的估计误差(estimation error)会增大，预测结果会对近邻的实例点非常敏感。
>
> 如果邻近的实例点恰巧是噪声，预测就会出错。
>
> 换句话说，k值的减小就意味着整体模型变得复杂，容易发生过拟合。
>
> 如果选择较大的k值，就相当于用较大邻域中的训练实例进行预测。其优点是可以减少学习的估计误差。但缺点是学习的近似误差会增大。这时与输入实例较远的(不相似的)训练实例也会对预测起作用，使预测发生错误。k值的增大就意味着整体的模型变得简单。
>
> 如果$$k＝N$$，那么无论输入实例是什么，都将简单地预测它属于在训练实例中最多的类。
>
> 这时，模型过于简单，完全忽略训练实例中的大量有用信息，是不可取的。
>
> 在应用中，k值一般取一个比较小的数值。通常采用`交叉验证法`来选取最优的k值。

### 分类决策规则

> k近邻法中的分类决策规则往往是`多数表决`，即由输入实例的k个邻近的训练实例中的多数类决定输入实例的类。
>
> 多数表决规则(majority voting rule)有如下解释：如果分类的损失函数为0-1损失函数，分类函数为
>
> $$
> f:R^n \to { c\_1,c\_2,...,c\_k }
> $$
>
> 那么误分类的概率是
>
> $$
> P(Y \neq f(X))=1-P(Y=f(X))
> $$
>
> 对给定的实例$$x \in x$$，其最近邻的k个训练实例点构成集合$$N\_k^{(x)}$$。如果涵盖$$N\_k{(x)}$$的区域的类别是$$c\_j$$ ，那么误分类率是
>
> $$
> \frac{1}{k}\sum\_{x\_i \in N\_k{(x)}}I(y\_i \neq c\_j)=1-\frac{1}{k}\sum\_{x\_i \in N\_k{(x)}}{}I(y\_i=c\_j)
> $$
>
> 要使误分类率最小即经验风险最小，就要使$$\sum\_{x\_i \in N\_k{(x)}}{}I(y\_i=c\_j)$$最大，所以多数表决规则等价于`经验风险最小化`。

## 构建kd树

> 实现k近邻法时，主要考虑的问题是如何对训练数据进行快速k近邻搜索。这点在特征空间的维数大及训练数据容量大时尤其必要。
>
> k近邻法最简单的实现方法是线性扫描(linear scan)。这时要计算输入实例与每一个训练实例的距离。当训练集很大时，计算非常耗时，这种方法是不可行的。
>
> 为了提高k近邻搜索的效率，可以考虑使用特殊的结构存储训练数据，以减少计算距离的次数。具体方法很多，下面介绍其中的kd树(kd tree)方法。
>
> `kd树`是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。
>
> kd树是二叉树，表示对k维空间的一个划分(partition)。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分，构成一系列的k维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。
>
> `构造kd树`的方法如下：
>
> 1. 构造根结点，使根结点对应于k维空间中包含所有实例点的超矩形区域；
> 2. 通过下面的递归方法，不断地对k维空间进行切分，生成子结点。
> 3. 在超矩形区域(结点)上选择一个坐标轴和在此坐标轴上的一个切分点，确定一个超平面，这个超平面通过选定的切分点并垂直于选定的坐标轴，将当前超矩形区域切分为左右两个子区域(子结点)；这时，实例被分到两个子区域。
> 4. 这个过程直到子区域内没有实例时终止(终止时的结点为叶结点)。
> 5. 在此过程中，将实例保存在相应的结点上。
>
> 通常，依次选择坐标轴对空间切分，选择训练实例点在选定坐标轴上的中位数(median)为切分点，这样得到的kd树是平衡的。注意平衡的kd树搜索时的效率未必是最优的。
>
> `Example1`: 给定一个二维空间的数据集：
>
> $$
> T={ (2,3)^T,(5,4)^T,(9,6)^T,(4,7)^T,(8,1)^T,(7,2)^T }
> $$
>
> 构造一个平衡kd树
>
> **解** 　根结点对应包含数据集$$T$$的矩形，选择$$x^{(1)}$$轴，6个数据点的$$x^{(1)}$$坐标的中位数是7，以平面$$x^{(1)}=7$$将空间分为左、右两个子矩形(子结点)；接着，左矩形以$$x^{(2)}=4$$分为两个子矩形，右矩形以$$x^{(2)}=6$$分为两个子矩形，如此递归，最后得到下图所示的特征空间划分和下图所示的kd树。
>
> <img src="/files/-Lz66mVUxzjszyegHDqB" alt="1570104114031" data-size="original">
>
> <img src="/files/-Lz66mVWpLfqoD8oJ7mg" alt="1570104123858" data-size="original">

## 搜索kd树

> 利用kd树可以省去对大部分数据点的搜索，从而减少搜索的计算量。这里以最近邻为例加以叙述，同样的方法可以应用到k近邻。
>
> 给定一个目标点，搜索其最近邻。首先找到包含目标点的叶结点；然后从该叶结点出发，依次回退到父结点；不断查找与目标点最邻近的结点，当确定不可能存在更近的结点时终止。这样搜索就被限制在空间的局部区域上，效率大为提高。
>
> 包含目标点的叶结点对应包含目标点的最小超矩形区域。
>
> 以此叶结点的实例点作为当前最近点。
>
> 目标点的最近邻一定在以目标点为中心并通过当前最近点的超球体的内部。
>
> 然后返回当前结点的父结点，如果父结点的另一子结点的超矩形区域与超球体相交，那么在相交的区域内寻找与目标点更近的实例点。
>
> 如果存在这样的点，将此点作为新的当前最近点。
>
> 算法转到更上一级的父结点，继续上述过程。
>
> 如果父结点的另一子结点的超矩形区域与超球体不相交，或不存在比当前最近点更近的点，则停止搜索。
>
> `Example1`: 给定一个如图所示的kd树，根结点为A，其子结点为B，C等。
>
> 树上共存储7个实例点；另有一个输入目标实例点S，求S的最近邻。
>
> <img src="/files/-Lz66mVYU-GnHyhicNqZ" alt="1570104452917" data-size="original">
>
> **解** 　首先在kd树中找到包含点S的叶结点D(图中的右下区域)，以点D作为近似最近邻。
>
> 真正最近邻一定在以点S为中心通过点D的圆的内部。
>
> 然后返回结点D的父结点B，在结点B的另一子结点F的区域内搜索最近邻。
>
> 结点F的区域与圆不相交，不可能有最近邻点。
>
> 继续返回上一级父结点A，在结点A的另一子结点C的区域内搜索最近邻。
>
> 结点C的区域与圆相交；该区域在圆内的实例点有点E，点E比点D更近，成为新的最近邻近似。
>
> 最后得到点E是点S的最近邻。

## 概要

> 1．k近邻法是基本且简单的分类与回归方法。k近邻法的基本做法是：对给定的训练实例点和输入实例点，首先确定输入实例点的k个最近邻训练实例点，然后利用这k个训练实例点的类的多数来预测输入实例点的类。
>
> 2．k近邻模型对应于基于训练数据集对特征空间的一个划分。k近邻法中，当训练集、距离度量、k值及分类决策规则确定后，其结果唯一确定。
>
> 3．k近邻法三要素：距离度量、k值的选择和分类决策规则。常用的距离度量是欧氏距离及更一般的pL距离。k值小时，k近邻模型更复杂；k值大时，k近邻模型更简单。k值的选择反映了对近似误差与估计误差之间的权衡，通常由交叉验证选择最优的k。常用的分类决策规则是多数表决，对应于经验风险最小化。
>
> 4．k近邻法的实现需要考虑如何快速搜索k个最近邻点。kd树是一种便于对k维空间中的数据进行快速检索的数据结构。kd树是二叉树，表示对k维空间的一个划分，其每个结点对应于k维空间划分中的一个超矩形区域。利用kd树可以省去对大部分数据点的搜索，从而减少搜索的计算量。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://narutohyc.gitbook.io/ml/jian-du-xue-xi/jian-du-xue-xikjin-lin-fa.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
