剖析随机森林
写在前面
随机森林是在机器学习中比较常用,简单,效果又很好的学习算法。在上一篇博文中,我使用了随机森林来预测泰坦尼克号的幸存者,但是没有具体地调参数来使算法获得更好的性能。我觉得只有更好地理解算法的原理,才能从本质上知道参数该如何调比较好,所以写下这篇博文来记录随机森林的原理要点。
前提知识
Bootstrapping
Bootstrapping俗称“自助法”,常常在数据集较小的时候使用。给定包含N个样本的数据集D,我们从中有放回地抽取N个样本作为训练数据,因为每抽出一个,就放回去,所以最后的训练数据有重复的样本。
Bagging
Bagging是Bootstrapping Aggregation的缩写。意思是我们通过Bootstrapping获得T个大小为N的数据集,在每一个数据集上应用一个学习算法,算法可以是相同的,也可以是不同的,最后对这些产生的训练器进行投票表决的形式产生结果。
Decision Tree
决策树是比较简单,解释性很好的学习算法。整个算法就是自顶向下地生成一棵树,根据每个结点的划分依据不同的准则分为ID3(信息熵增益),C4.5(信息熵增益比),CART算法(平方误差,基尼指数)。详细地可以查看李航的《统计学习方法》一书。
Bagging的特点可以减少variance,Decision Tree的缺点就是容易过拟合,即large variance,随机森林可以把两者结合起来。
随机森林
算法
- 从训练集中用Bootstrap抽取出n个样本。
- 构建CART树,对于每一个节点分支,随机选择k个特征,选择最佳分割作为分支节点。
- 重复1,2两步T次,即建立了T个CART树。
- T个CART树构成了随机森林,采用多数表决的方式决定最后结果。
我们可以看到,随机森林的随机体现在使用Bootstrap随机收取样本,以及随机选择k个特征进行分支建立。
OOB
在Bagging这类方法中,我们使用Bootstrap来抽取N个样本,然后训练一个决策函数\(g_t\),对于那些在训练\(g_t\)时没有使用的数据称作\(g_t\)的out-of-bag(OOB)。如下所示:
对于一个样本\((x_n, y_n)\),它成为OOB的概率为:\((1-\frac{1}{N})^N\),如果N取很大,那么概率约等于\(\frac{1}{e}\),即大约有30%的数据不会被使用,联想到验证集,我们可以使用OOB作为验证集来使用。
在随机森林中我们没必要对每个\(g_t\),都使用它的OOB来验证,我们将使用OOB来验证整个的\(G\)。假设\(G_{n}^{-}\)中的树\(x_n\)为OOB,那么\(G_{n}^-(x)=avg(g_2,g_3,...,g_t)\),那么OOB的误差就是:
所以称\(E_{oob}\)为self-validation of RF。
有了\(E_{oob}\),我们就可以进行模型选择了,具体过程如下:
特征选择
我们的特征选择就是在原来的特征中去掉冗余的,不相关的。
好处:
- 有效率,更简单的假设,预测时间短
- 泛化性能好,移除了噪声
- 可解释
坏处:
- 如何获得新特征的计算量大,需要各种组合
- 可能对于选择的特征产生过拟合
- 缺少解释
决策树是个内建特征选择的模型。
对于选择特征,我们可以依据特征的重要性来进行选择。我们联想一下线性模型\(\sum_{i=1}^dw_ix_i\),\(w_i\)就代表了特征的重要性,那么在非线性模型的随机森林中该如何取得特征的重要性呢?
一个直观的想法是,如果对某一个特征我们随机填充一个值导致性能下降了,那么这个特征就是重要的。不能随随便便的使用随机值来代替某个特征,这样会改变这个特征的概率分布\(P(x_i)\),我们使用permutation test,即将所有数据的这个特征的值打乱。
那么得到特征的重要性可以如下表示:
对于打乱特征值后的performance,照理说我们需要重新validation一下,但是在随机森林中,我们有了OOB,那么可以省去这个步骤,我们改变一下特征重要性的计算公式:
这里的\(E_{oob}^{(p)}\)是将OOB打乱后计算的。