K-近邻算法

在模式识别领域中，最近邻居法（KNN算法，又译K-近邻算法）是一种用于分类和回归的无母数统计方法，由美国统计学家伊芙琳·费克斯和小约瑟夫·霍奇斯于1951年首次提出，后来由托马斯·M·寇弗扩展。在这两种情况下，输入包含特征空间中的k个最接近的训练样本。

- 在k-NN分类中，输出是一个分类族群。一个对象的分类是由其邻居的“多数表决”确定的，k个最近邻居（k为正整数，通常较小）中最常见的分类决定了赋予该对象的类别。若k = 1，则该对象的类别直接由最近的一个节点赋予。
- 在k-NN回归中，输出是该对象的属性值。该值是其k个最近邻居的值的平均值。

最近邻居法采用向量空间模型来分类，概念为相同类别的案例，彼此的相似度高，而可以借由计算与已知类别案例之相似度，来评估未知类别案例可能的分类。

K-NN是一种循例学习，或者是局部近似和将所有计算推迟到分类之后的惰性学习。k-近邻算法是所有的机器学习算法中最简单的之一。

无论是分类还是回归，衡量邻居的权重都非常有用，使较近邻居的权重比较远邻居的权重大。例如，一种常见的加权方案是给每个邻居权重赋值为1/ d，其中d是到邻居的距离。

邻居都取自一组已经正确分类（在回归的情况下，指属性值正确）的对象。虽然没要求明确的训练步骤，但这也可以当作是此算法的一个训练样本集。

k-近邻算法的缺点是对数据的局部结构非常敏感。

K-平均算法也是流行的机器学习技术，其名称和k-近邻算法相近，但两者没有关系。数据标准化可以大大提高该算法的准确性。

## 算法

<image>

训练样本是多维特征空间向量，其中每个训练样本带有一个类别标签。算法的训练阶段只包含存储的特征向量和训练样本的标签。

在分类阶段，k是一个用户定义的常数。一个没有类别标签的向量（查询或测试点）将被归类为最接近该点的k个样本点中最频繁使用的一类。

一般情况下，将欧氏距离作为距离度量，但是这是只适用于连续变量。在文本分类这种离散变量情况下，另一个度量——“重叠度量”（或海明距离）可以用来作为度量。例如对于基因表达微阵列数据，k-NN也与Pearson和Spearman相关系数结合起来使用。通常情况下，如果运用一些特殊的算法来计算度量的话，k近邻分类精度可显著提高，如运用大间隔最近邻居或者邻里成分分析法。

“多数表决”分类会在类别分布偏斜时出现缺陷。也就是说，出现频率较多的样本将会主导测试点的预测结果，因为他们比较大可能出现在测试点的K邻域而测试点的属性又是通过k邻域内的样本计算出来的。解决这个缺点的方法之一是在进行分类时将样本到k个近邻点的距离考虑进去。k近邻点中每一个的分类（对于回归问题来说，是数值）都乘以与测试点之间距离的成反比的权重。另一种克服偏斜的方式是通过数据表示形式的抽象。例如，在自组织映射（SOM）中，每个节点是相似的点的一个集群的代表（中心），而与它们在原始训练数据的密度无关。K-NN可以应用到SOM中。

## 参数选择

如何选择一个最佳的K值取决于数据。一般情况下，在分类时较大的K值能够减小噪声的影响，但会使类别之间的界限变得模糊。一个较好的K值能通过各种启发式技术（见超参数优化）来获取。

噪声和非相关性特征的存在，或特征尺度与它们的重要性不一致会使K近邻算法的准确性严重降低。对于选取和缩放特征来改善分类已经作了很多研究。一个普遍的做法是利用进化算法优化功能扩展，还有一种较普遍的方法是利用训练样本的互信息进行选择特征。

在二元（两类）分类问题中，选取k为奇数有助于避免两个分类平票的情形。在此问题下，选取最佳经验k值的方法是自助法。

## 加权最近邻分类器

k- 最近邻分类器可以被视为为k最近邻居分配权重$1 / k$以及为所有其他邻居分配0权重。这可以推广到加权最近邻分类器。也就是说，第i近的邻居被赋予权重$w_{ni}$，其中$\sum_{i = 1}^n w_{ni}= 1$。关于加权最近邻分类器的强一致性的类似结果也成立。

设$C ^{wnn}_n$表示权重为$\{w_{ni}\}_{i = 1}^n$的加权最近邻分类器。根据类别分布的规律性条件，超额风险具有以下渐近展开

$$\mathcal{R}_\mathcal{R}(C^{wnn}_{n}) - \mathcal{R}_{\mathcal{R} }(C^{Bayes}) = \left(B_1 s_n^2 + B_2 t_n^2\right) \{1+o(1)\},$$

对常数 $B_1$ and $B_2$ 当 $s_n^2 = \sum_{i=1}^n w_{ni}^2$ 并且 $t_n = n^{-2/d}\sum_{i=1}^n w_{ni}\{i^{1+2/d} - (i-1)^{1+2/d}\}$。

最佳加权方案$\{w_{ni}^* \}_{i = 1}^n$用于平衡上面显示中的两个项，如下所示：令 $k ^* = \lfloor B n ^{\frac 4 {d + 4} }\rfloor$。

$w_{ni}^* = \frac 1 {k^*} \left[1 + \frac d 2 - \frac d {2{k^*}^{2/d} } \{ i ^{1+2/d} - (i-1)^{1+2/d}\}\right]$ 对 $i=1,2,\dots,k^*$ 并且

$w^*_{ni} = 0$ 对 $i = k^*+1,\dots,n$.

利用最优权重，超额风险的渐近展开中的主项是$\mathcal{O}(n^{-\frac 4 {d+4} })$。当使用自助聚合时，类似的结果也是如此。

## 属性

原始朴素的算法通过计算测试点到存储样本点的距离是比较容易实现的，但它属于计算密集型的，特别是当训练样本集变大时，计算量也会跟着增大。多年来，许多用来减少不必要距离评价的近邻搜索算法已经被提出来。使用一种合适的近邻搜索算法能使K近邻算法的计算变得简单许多。

近邻算法具有较强的一致性结果。随着数据趋于无限，算法保证错误率不会超过贝叶斯算法错误率的两倍。对于一些K值，K近邻保证错误率不会超过贝叶斯的。

## 决策边界

近邻算法能用一种有效的方式隐含的计算决策边界。另外，它也可以显式的计算决策边界，以及有效率的这样做计算，使得计算复杂度是边界复杂度的函数。

## 连续变量估计

K近邻算法也适用于连续变量估计，比如适用反距离加权平均多个K近邻点确定测试点的值。该算法的功能有：

- 从目标区域抽样计算欧式或马氏距离。
- 在交叉验证后的RMSE基础上选择启发式最优的K邻域。
- 计算多元k-最近邻居的距离倒数加权平均。

## 发展

然而k最近邻居法因为计算量相当的大，所以相当的耗时，Ko与Seo提出一算法TCFP（text categorization using feature projection），尝试利用特征投影法来降低与分类无关的特征对于系统的影响，并借此提升系统效能，其实验结果显示其分类效果与k最近邻居法相近，但其运算所需时间仅需k最近邻居法运算时间的五十分之一。

除了针对文件分类的效率，尚有研究针对如何促进k最近邻居法在文件分类方面的效果，如Han等人于2002年尝试利用贪心法，针对文件分类实做可调整权重的k最近邻居法WAkNN（weighted adjusted k nearest neighbor），以促进分类效果；而Li等人于2004年提出由于不同分类的文件本身有数量上有差异，因此也应该依照训练集合中各种分类的文件数量，选取不同数目的最近邻居，来参与分类。

## 拓展阅读

- When Is "Nearest Neighbor" Meaningful?
- Fast k nearest neighbor search using GPU. In Proceedings of the CVPR Workshop on Computer Vision on GPU, Anchorage, Alaska, USA, June 2008. V. Garcia and E. Debreuve and M. Barlaud.
- Scholarpedia article on k-NN
- google-all-pairs-similarity-search