我一见钟情就爱上了k-Nearest Neighbors算法,但这不是盲目的爱。我有很多理由对此感到生气。

1.它非常直观和简单

鉴于您需要做的就是比较样本,最近邻(k-NN)算法是引入机器学习的完美第一步。理解起来非常简单,易于解释并且完美地向每个人展示。尽管它很简单,但最近邻居也非常强大并且在工业中广泛使用。

2.它没有假设

这是非参数算法的特征,如k-NN。他们对输入数据分布没有任何假设。参数模型,如线性回归,假设大多数数据集遵循典型的理论约束。但是,现实世界的数据集不遵守这些假设。因此,当对数据分布有一点或没有先验知识时,k-Nearest Neighbors通常是第一选择。

3.没有训练步骤

它不需要明确的训练步骤,因为没有可以构建的模型。K-NN是基于实例的学习,意味着我们的算法没有明确地学习模型。算法的训练阶段仅包括存储训练样本的特征向量和类标签。这也意味着训练阶段非常快,因为数据存储实际上正在发生。

4.它立即适应变化

鉴于它是基于实例的学习,k-NN是一种基于记忆的方法。当我们收集新的训练数据时,分类器立即适应。它允许算法在实时使用期间快速响应输入的变化。

5.它自然会导致多类问题

许多分类算法本质上是二进制算法。使它们适应多类问题需要多种策略:转换为二进制,从二进制扩展等。但是,k-NN自然允许我们使用两个以上的类。

6.它可用于分类和回归任务

此方法的自然实践是将输入点放入适当的类别,但我们可以轻松地将此算法扩展到回归问题。我们必须结合连续预测,而不是组合k-邻居的离散标签。这些预测可以以不同方式获得,例如,通过平均k个最相似实例的值。

7.只能设置一个超参数

需要一些时间来了解哪种超参数设置适合哪种模型行为。此外,参数的数量与过度拟合的可能性直接相关:越少越好。

8.灵活的距离选择

不同的距离函数为不同类型的数据集提供不同的目的。因此,您可以花时间选择最佳选择。请记住,您的选举必须首先取决于功能的性质。并且k-NN承认他们全部!因此可以使用数字(欧几里德,曼哈顿等)和分类特征(汉明等)。

9.它可以提供密度估计

虽然分类仍然是k-NN的主要应用,但我们也可以将其转化为密度估算器。为了估计点x处的数据密度,我们可以使用包含其所有邻居的最大超立方体的体积。此外,我们可以将标记为A类的邻居的分数解释为该类的条件概率。此外,如果没有多数协议,k-NN提供明确的拒绝选项。换句话说,您可以轻松更改标准以估计类并获得概率估计而不是修复标签。

10.它易于实现和调整

实现k-NN不需要太多代码并且可以快速。鉴于此,创建自己的版本并不需要花费很多时间,这个版本更适合您特定问题的关键点; k-NN可以用作基线方法。此外,你可以找到k-NN的许多扩展; 我在帖子的下一部分概述了其中的一些内容。
处理它们的问题和关键
当然,并非所有东西都是关于k-NN的玫瑰床,你需要考虑几个可能影响算法并降低其性能的棘手要点。下面我列出其中一些,但请不要对k-NN感到沮丧,生活中的一切都有解决方案!

1.测试阶段很慢

与快速训练阶段相比,它需要非常昂贵的测试。算法的所有成本都在于预测的计算,因为对于每个测试样本,模型必须遍历整个数据集以计算距离,然后找到最近的邻居。
提案:为了应对k-NN的挑战性计算,已经创建了一些蛮力的替代技术。KD树和球树是最知名的。

2.它通常需要同质的特征

如果您决定使用公共距离(如欧几里德或曼哈顿距离)构建k-NN,则必须使要素具有相同的比例,因为要素的绝对差异权重相同,即要素1中的给定距离必须表示功能2相同。
建议:如果您的主要数据是异构数据,则需要重新调整数据,以确保距离度量标准有意义。也许z-将您的数据评分到范围[0,1]是个好主意。另一种解决方案是通过使其适应特征的性质来设计自己的距离函数。只要输入功能和距离标准完美匹配,一切都可以。

3.需要选择超参数k

选择邻居数量是一个关键点,您需要知道这将如何影响您的分类器。选择一个非常小的k意味着低偏差但高方差,而许多选民参与方差减少但偏差增加。
建议:我们可以在交叉验证的帮助下找到平衡点。K折交叉验证是最受欢迎的之一(这个k表示折叠的数量 - 完全独立于您的k个邻居!)并通过测试超出测试集的超参数精度来防止过度拟合。此外,我们可以找到低估k选择的k-NN算法的不同版本:加权k-NN使用距离的倒数来加权邻居类,这有助于使相似性度量比一定数量的邻居更具决定性。

4.不平衡的数据会导致问题

k-NN在不平衡数据上表现不佳。如果我们考虑两个类,A和B,并且大多数训练数据被标记为A,那么该模型最终将给予A很多偏好。这可能导致不太常见的B类被错误地分类。
建议:这可以通过单独装袋 A类和B类样品来减轻:我们可以使用几个k-最近邻集来对新样本进行分类,其中每个样本通过随机抽样可用数据获得; 我们应该强制随机抽样选择具有平衡类频率的例子。另一种解决方案可以是通过对邻居的决策进行加权来实现频率校正:对于那些标记频率较低的类别的人来说更多。SMOTE(合成少数过采样技术)和MSMOTE也是专门用于从不平衡数据集中学习的方法。

5.它对异常值很敏感

算法对异常值很敏感,因为单个错误标记的示例会显着改变类边界。异常会显着影响方法,因为k-NN从输入中获取所有信息,而不是从尝试推广数据的算法中获取。
建议:避免使用非常少量的邻居(例如k = 1),特别是如果你在嘈杂的数据前面,所以总是如此。

6.它无法处理缺失值

我们需要为每个实例提供完整的特征向量,以便计算距离。因此,必须填写任何缺失的值。
建议:在整个数据集中为缺失值设置要素的平均值,或将距离计算限制为子空间可能是合理的选择。

7.与最近邻居的距离可能会因不同情况而发生很大变化

当您计算k-NN算法来做出决策时,有时选民可能非常接近新实例进行分类。但是,在其他情况下,当我们在训练集中缺少紧密的例子时,很远的邻居决定实例的类。
建议:如果您的问题需要保留选民的距离,那么您应该切换到最近邻居版本的无线电。然后,算法将找到那些不远离距离限制的示例,而不是寻找k个最近邻居并做出决定。我真的很喜欢这个版本。请注意,在这种情况下,投票数将因实例而异。如果没有足够相似的数据样本,甚至可能会得到一些错误分类的例子。

8. K-NN不适用于高维数据

当特征向量维度很大时,k-NN可能会受到影响。这是因为距离测量通常会失去准确性:最近和最远的邻居之间存在一点差异。
建议:在将特征向量用作算法的输入之前,您应该进入维度降低技术(特征选择和特征提取)以重新定义特征向量。

9.它不能抵抗不相关的功能

鉴于距离度量通常对所有特征赋予相同的重要性,因此避免包括与分类问题无关的特征是关键。否则,不相关的功能肯定会降低准确性。
建议: 特征选择方法,包装器,过滤器和嵌入方法,包括选择要在模型中使用的相关特征的子集。您还可以通过向要素添加自定义权重或实现自身处理不相关性的提升算法来调整k-NN ,方法是随机抽取特征向量并在每次迭代时评估子集的错误,以根据其自身更新要素权重重要性。

10.冗余会影响性能

如果两个或更多特征依赖,则算法将为它们设置一个失代偿权重,而没有任何理由这样做。
建议:选择相关功能后,可以使用特征提取技术将原始特征向量转换为不包含冗余信息的较小特征向量。PCA是最广泛的方法之一。
你知道其他任何你想分享的技巧吗?你有问题没找到答案吗?请随时告诉我们您对k-Nearest Neighbors的感受。