JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

k-近邻算法与朴素贝叶斯

机器学习中最简单的两种分类器——一个询问身边的邻居,一个做一点概率运算——以及为何这两种朴实的方法击败花哨模型的频率,远比你想象的要高。

两个几乎称不上算法的算法

你已经见过会*学习*的模型——线性回归拟合一条直线,决策树生长出分裂,随机森林在众多树之间投票。本指南要介绍的两种方法几乎像是在作弊,因为其中一个根本不做真正的训练,另一个只做一点计数。它们就是k-近邻朴素贝叶斯——尽管如此简单,这两者在真实系统中至今仍被天天使用。

两者都属于监督学习:你给它们带标签的样本——每个样本是一个带有已知标签特征向量——它们便学会为新点打标签。它们的特别之处在于*所需的机制极少*。它们非常适合用来建立基线:在任何人推出神经网络之前,你最先尝试的东西。

k-NN:问问你的邻居就好

k-近邻背后的思想你早已在做。要猜一家新餐厅好不好,你会看看自己熟悉的、最相似的几家餐厅,然后采纳多数人的评价。k-NN正是如此:要给一个新点分类,它找出离它最近的*k*个训练样本,让它们投票。想预测一个数值而非类别?那就对邻居们的取值求平均。这就是整个算法。

“最近”指的是特征空间中的距离——通常就是普通的欧氏距离,即把每个特征当作一根坐标轴时,你用尺子量出的直线间隔。*k*的取值是一个你需要调的超参数:*k*小(比如取1)会紧贴数据的每一处起伏,容易把噪声也学进去而过拟合;*k*大则把一切抹平,却可能模糊真实的边界——这正是你早先见过的偏差—方差权衡的清晰写照。

predict(x, k):
    dists = [ distance(x, xi) for (xi, yi) in training_set ]
    nearest = the k examples with smallest dists
    return majority_vote(label of each in nearest)   # or average, for regression
四行写完的k-NN。注意这里没有训练循环——所有工作都发生在预测时刻。

k-NN悄悄失灵之处

在你信任k-NN之前,有两个实实在在的弱点值得了解。第一,*尺度很重要*:如果一个特征以美元(0–100,000)计量,另一个以年(0–80)计量,那么美元那根轴会主宰距离,而年份特征则被忽略。务必先做特征缩放——这不是锦上添花的可选项,它会改变结果。

第二,更微妙的是,k-NN深受维度灾难之苦。随着你增加特征,空间膨胀得如此之快,以至于*每个*点与其他每个点都变得大致等距——“最近”失去了意义。在成百上千个维度里,“看看附近有谁”这个令人安心的直觉干脆失效,这正是k-NN在低维、整洁的问题上大放异彩,却在图像这类原始高维数据上黯然失色的原因之一。

这些都不会让k-NN过时——恰恰相反。它的核心技巧(找出相似项,照搬它们的答案)正是现代检索的运作方式:把事物转成嵌入向量,再到向量数据库中搜索最近邻。所以你在这里学到的这个朴素思想,会换一身行头,放大成今日最庞大系统的核心。

朴素贝叶斯:靠计数算出一个猜测

朴素贝叶斯从另一个角度切入:概率。它建立在贝叶斯定理之上,该定理告诉你如何翻转一个条件概率。我们想要P(类别 | 特征)——给定一封邮件所含的词,它是垃圾邮件的概率。贝叶斯定理把它改写成我们*能*从训练数据中数出来的东西:垃圾邮件中每个词出现的频率,以及垃圾邮件整体上有多常见。

难点在于一次性计算整个特征*组合*的概率——那需要多到不可能的数据量。于是朴素贝叶斯做出一个大胆而故意错误的假设:所有特征在给定类别的条件下相互独立。在垃圾邮件的例子里,它假装:一旦你已知这封邮件是垃圾邮件,“免费”这个词就完全不能告诉你“钱”是否也会出现。这让它可以把每个特征的概率分别相乘——把一个无望的联合估计变成寥寥几个简单的计数。

“朴素”二字正是算法在承认这个假设是错的——真实文本里的词显然是相关的。真正令人惊讶的事实是,这往往*无关紧要*。即便独立性假设被严重违反,得分最高的那个类别也常常仍是正确的,因为这些误差倾向于抬高分数,却不会翻转哪个类别胜出。这正是朴素贝叶斯至今仍是著名而强劲的文本分类基线的原因。

何时简单者胜出

人们很容易以为越大的模型总会赢,但没有免费午餐定理指出:没有任何单一方法能在所有问题上称霸。决定胜负的,是一种方法内建的假设——它的归纳偏置——与你数据真实形态之间的契合程度。朴素贝叶斯假设特征独立;k-NN假设邻近的点共享标签。当这些假设大致成立时,这些微小的模型就能匹敌甚至击败重得多的模型。

简单方法在具体情形中胜出:当你只有很少的带标签数据时(深度网络只会过拟合);当你需要在毫秒内、没有GPU的情况下给出答案时;当有人必须向监管者或客户*解释*这个决定时;或者当你只是需要一个基线来证明更花哨的模型对得起它的成本时。一个朴素贝叶斯垃圾邮件过滤器,或一个k-NN推荐器,一个下午就能上线,并能在一部手机上运行。

诚实的说法不是“简单对强大”,而是“契合对不契合”。从可能奏效的最廉价方案开始,妥善地度量它,再让数据告诉你复杂性是否值得。结果是“不值得”的次数,比新手以为的要多得多——而这份克制本身,正是功力的标志。