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

决策树与随机森林

决策树不过是一张由是/否问题组成的流程图,只是它由计算机从数据中学出来——直观,却危险地热衷于死记硬背。本篇带你认识驯服它的妙招:种出一整片森林,让众多树木投票表决。

一张机器自己写出的流程图

你已经认识了线性回归逻辑回归,它们在数据中画出一条笔直的分界线。而决策树走的是一条全然不同、却极其贴近人类直觉的路:它一连串地问是/否问题。“这位乘客年龄小于10岁吗?如果是,他坐的是三等舱吗?如果不是,……”——每一个回答都把你送往一根分支,直到抵达一片叶子,告诉你最终的猜测。这正是你可能会亲手画出来做决策的那张流程图,只不过这些问题是机器自己琢磨出来的。

它是怎么挑选这些问题的呢?贪心地,一次挑一个。在每个节点上,它扫描每一个特征、每一个可能的切分点,选出那个能让分出的各组尽可能纯净的切分——也就是说,每一组都明显偏向某一个标签。衡量这种“杂乱”的一种常见办法是信息熵:一个所有样本答案都相同的节点,熵为零;树要做的,就是不断切分,直到不纯度降下来。然后它在每个子节点里重复同样的事,越钻越深。

那棵把答案抄下来的树

麻烦就在这里。如果你放任一棵树一直切下去,它不会停手,直到每片叶子都完美纯净——常常是一个孤零零的训练样本独占一片叶子。到了那一步,这棵树并没有*学会*规律,而是把训练数据背了下来,给每个点都圈出一个量身定制的小盒子。这正是你之前读到过的过拟合,而且是最纯粹的形态:在见过的数据上完美无瑕,在任何新数据上却错得令人难堪。

一棵很深的单树正落在偏差—方差权衡的一个极端:它的偏差极小,方差却极大。只要改动几行训练数据,整棵树就可能重新塑形,长出截然不同的问题。这种不稳定,正是该让你提高警惕的症状——一个会随数据剧烈改变主意的模型,抓住的是噪声,而不是信号。

第一道防线是剪枝:让树提早收手(限制它的深度,或要求每片叶子至少容纳,比方说,20个样本),又或者先把它长满,再剪掉那些在留出数据上不值回票价的枝条。剪枝是用一点点训练准确率,换来好得多的泛化能力。它确实有帮助——但一棵孤树,无论修剪得多么用心,都很难与接下来要登场的东西较量。

群体的智慧:装袋法

有一个古老的观察:问一个专家,你可能得到大错特错的答案;问一千个,再把答案平均起来,误差就相互抵消了。一棵高方差的树,恰恰就是这样一位手抖的专家。于是,与其费力去稳住一棵树,我们不如拥抱它的晃动,把许多棵的结果平均起来。这正是集成学习的核心——把许多不完美的模型合成一个更强的整体。

可是,如果我们让每棵树都在同一份数据上训练,那不过是把同一棵树复制了一千遍——没有多样性,也就没有相互抵消。装袋法(bagging,即*自助聚合*,bootstrap aggregating)正是用来制造多样性的。对每一棵树,它都*有放回地*随机抽取训练样本的一部分——于是有些行出现了两次,有些则一次也没出现。这样每棵树看到的世界都略有不同,学到的问题也略有不同,犯的错误更是各不相同。

接着你把它们聚合起来:分类问题里,众树投票,多数获胜;回归问题里,你把它们的数值取平均。因为每棵树的误差指向随机、互不相关的方向,它们往往相互抵消——而它们共有的、真实的信号却彼此强化。背后的数学温和却有力:把许多独立的估计平均起来,能在不抬高偏差的前提下压低方差。群体,比其中任何一个声音都更沉稳。

随机森林额外的一招

随机森林就是把装袋法用在决策树上,再加上一味巧妙的额外配料。光靠装袋有一个隐藏的弱点:如果某个特征特别强势,几乎每棵树都会拿它来做第一刀切分,结果众树长得彼此相像——而相像的树会犯*相关的*错误,平均起来效果就差。森林打破了这种从众行为。

这一招是:在*每一次切分*时,每棵树都只被允许考虑特征的一个随机子集(常见的选法是取特征总数的平方根)。在某个节点上,一棵树或许被禁止使用那个最强势的特征,于是被逼着去发现第二好、第三好的问题。结果便是一片由真正*各异*的树组成的森林,它们的误差远没有那么相关——而正是这种去相关,让平均的效果好得出奇。

forest = []
for t in range(n_trees):
    rows  = sample_with_replacement(training_data)   # bagging
    tree  = grow_tree(rows, features_per_split=sqrt(F))  # random features
    forest.append(tree)

def predict(x):
    votes = [tree.predict(x) for tree in forest]
    return majority(votes)            # or mean(votes) for regression
随机森林一言以蔽之:许多棵树,每棵都长在一份自助抽样上,每次切分都从随机的一小撮特征里挑选——然后它们投票。

还有一份可爱的免费赠品:每棵树自助抽样时没被抽中的那些行(即*袋外*样本),天然就构成了这棵树的测试集。把森林在这些没见过的行上的准确率平均一下,几乎是白白地得到了一个诚实的误差估计,连单独划一份验证集都省了。

森林何时取胜——以及一句诚实的告诫

随机森林至今仍是监督学习中最可靠的主力之一,在面对杂乱的表格数据(混杂着数字与类别的电子表格)时,它依然是许多从业者的第一选择。它几乎不需要做特征缩放,对离群点和无关列毫不在意,哪怕用上几百棵树也很少过拟合,而且开箱即用、几乎不用调参。在充斥着大多数企业的结构化数据上,一片森林往往能与神经网络打成平手甚至胜出,所需的数据与功夫却只是后者的零头。

不过,对它的局限要诚实。森林牺牲掉了单棵树那份宝贵的可读性——你拿一张能解释的流程图,换来了一个数百成员的委员会。它还不擅长外推:因为每个预测都是训练叶子的平均,森林永远输出不了它见过的范围之外的值,所以它对平滑的趋势或真正的预测都很吃力。而对于知觉类数据——图像、音频、原始文本——信号藏在空间或序列结构之中,这条阶梯后面要讲的深度学习方法便会决定性地领先。