k近邻法

k近邻法

k近邻法(k-nearest neighbor,k-NN)是一种基本分类与回归方法。k近邻法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类。
k近邻法不具有显式的学习过程,实际上是利用训练数据集对特征向量空间进行划分,并作为其分类的“模型”。
k近邻法三要素:k值的选择、距离度量、分类决策规则。

1. k近邻算法

k近邻算法简单直观:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某各类,就把该输入实例分为这个类。

算法如下:

k近邻法的特殊情况是\(k=1\)的情形,称为最近邻算法。对于输入的实例点(特征向量)\(\pmb{x}\),最近邻法将训练数据集中与\(\pmb{x}\)最邻近点的类作为\(\pmb{x}\)的类。

2. k近邻模型

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

2.1. 模型

特征空间中,对每个训练实例点\(\pmb{x}_i\),距离该点比其他点更近的所有点组成一个区域,叫做单元(cell)。每个训练实例点拥有一个单元,所有训练实例点的单元构成对特征空间的划分。最近邻法将实例\(\pmb{x}_i\)的类\(y_i\)作为其单元中所有点的类标记。这样,每个单元的实例点的类别是确定的。

2.2. 距离度量

特征空间中两个实例点的距离是两个实例点相似程度的反映,k近邻模型的特征空间一般是\(n\)维实数向量空间\(\mathbf{R}^n\),使用的额距离一般是欧氏距离,但也可以是其他距离。

给定样本\(\pmb{x}_i = (x_{i1},x_{i2},\cdots,x_{in})\)\(\pmb{x}_j = (x_{j1},x_{j2},\cdots,x_{jn})\),最常用的是“闵可夫斯基距离”(Minkowski distance):
\[dist_{mk}(\pmb{x}_i,\pmb{x}_j) = (\sum_{u=1}^n |x_{iu} - x_{ju}|^p)^{\frac{1}{p}}\] (1)\(p=1\)时,为曼哈顿距离(Manhattan distance)
\[dist_{man}(\pmb{x}_i,\pmb{x}_j) = ||\pmb{x}_i - \pmb{x}_j||_1 = \sum_{u=1}^n |x_{iu} - x_{ju}|\]
(2)\(p=2\)时,为欧氏距离(Euclidean distance)\[dist_{ed}(\pmb{x}_i,\pmb{x}_j) = ||\pmb{x}_i - \pmb{x}_j||_2 = \sqrt{\sum_{u=1}^n |x_{iu} - x_{ju}|^2}\]
(3)\(p= \infty\),为各个坐标距离的最大值: \[dist(\pmb{x}_i,\pmb{x}_j) = \max_{1 \leq u \leq n} |x_{iu} - x_{ju}|\]

下图给出二维空间中\(p\)取不同值时,与原点的\(dist\)距离为1的点的图形。

2.3. k值的选择

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

2.4. 分类决策规则

k近邻法中的分类决策规则往往是多数表决,即有输入实例的k个邻近的训练实例中的多数类决定输入实例的类。
多数表决规则(majority voting rule)有如下解释:如果损失函数是0-1损失函数,分类函数为: \[f: \mathbf{R}^n \to \{c_1,c_2,\cdots,c_K\}\] 那么误分类的概率为 \[P(Y \neq f(\pmb{X})) = 1 - P(Y = f(\pmb{X}))\] 对于给定的实例\(\pmb{x}\),其最近邻的k个训练实例点构成集合\(N_k(\pmb{x})\),如果涵盖\(N_k(\pmb{x})\)的区域类别是\(c_j\),那么误分类率是 \[\frac{1}{k} \sum_{\pmb{x}_i \in N_k(\pmb{x})} I(y_i \neq c_j) = 1 - \frac{1}{k} \sum_{\pmb{x}_i \in N_k(\pmb{x})} I(y_i = c_j)\] 要使误分类率最小即经验风险最小,就要使\(\sum_{\pmb{x}_i \in N_k(\pmb{x})} I(y_i \neq c_j)\)最大,所以多数表决规则等价于经验风险最小化。

3. kd树

3.1. 构造kd树

为了提高k近邻搜索的效率,考虑使用特殊的结构存储训练数据,以减少计算距离的次数。
kd树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。kd树是二叉树,表示对k维空间的一个划分。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个节点对应于一个k维超矩形区域。
构造kd树的方法如下:

  1. 构造根节点,使根节点对应于k维空间中包含所有实例点的超矩形区域;
  2. 递归的执行下述方法:不断地对k维空间进行切分,生成子节点。在超矩形区域(节点)上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面,这个超平面通过选定的切分点并垂直于选定的坐标轴,将当前超矩形区域切分为左右两个子区域(子节点);此时,实例被分到两个子区域。这个过程直到子区域内没有实例点时终止(终止时的节点为叶节点)。在此过程中,将实例保存在相应的节点上。

通常,依次选择坐标轴对空间进行切分,选择训练实例点在选定坐标轴上的中位数为切分点,这样得到的kd树是平衡的。
平衡的kd树搜索时的效率未必是最优的。

构造kd树的算法如下:

例题:

3.2. 搜索kd树

给定一个目标点,搜索其最近邻:

  1. 首先找到包含目标点的叶节点;
  2. 从叶节点出发,依次回退到父节点;此过程中,不断查找与目标点最邻近的节点,当确定不可能存在更近的节点时终止。

这样搜索就被限制在空间的局部区域上,效率大为提高。
包含目标点的叶节点对应包含目标点的最小超矩形区域。以此叶节点的实例点作为当前最近点。目标点的最近邻一定在以目标点为中心并通过当前最近点的超球体的内部。然后返回当前节点的父节点,如果父节点的另一子节点的超矩形区域与超球体相交,那么在相交的区域内寻找与目标点更近的实例点。如果存在这样的点,将此点作为新的当前最近点。算法转到更上一级的父节点,继续上述过程。如果已证实不存在比当前最近点更近的点,则停止搜索。
最近邻搜索算法:

如果实例点是随机分布的,kd树搜索的平均时间复杂度是\(O(\log N)\),这里的\(N\)是训练实例数。kd树更适用于训练实例数远大于空间维数时的k近邻搜索。当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近线性扫描。

例题: