机器学习-集成学习:随机森林(Random Forest)

 内容参考:https://github.com/NLP-LOVE/ML-NLP/tree/master/Machine%20Learning/3.1%20Random%20Forest​​​​​

略做修改 

0.集成学习

如果你随机向几千专家询问一个复杂的问题,然后汇总他们的回答,在许多情况下,你会发现,这个汇总的答案比最好的那个专家回答得要好。同样,如果你聚合一组预测器(比如分类器或者回归器)的预测,得到的预测结果也比最好的单个预测器要好,这种聚合一组预测器来进行预测的方法,称为集成学习。

例如,你可以训练一组决策树分类器,每一颗树都基于训练集不同的子集进行训练,在做预测时,你只需要获得所有树的预测,然后给出票数最多的类别作为预测结果。

机器学习-集成学习:随机森林(Random Forest)_第1张图片 常见的集成学习方法包括:bagging,Random-Forest,boosting,stacking等

1.什么是随机森林

1.1 Bagging思想

Bagging(bootstrap aggregating的缩写,bootstrap在统计学中是放回重新采用方法,采用时样本不放回就是pasting)。思想就是从总体样本当中随机取一部分样本进行训练,通过多次这样的结果,进行投票获取平均值作为结果输出,这就极大可能的避免了不好的样本数据,从而提高准确度。与直接在原始训练集上的单个预测器相比,集成学习的偏差相近,但方差更低。

Scikit-learn提供了一个简单的API,可用BaggingClassifier进行Bagging或者Pasting(或者BaggingRegressor用于回归)。以下代码训练一个包含500颗决策树分类器继承,每次随机从训练集中采用100个实例进行训练,然后放回(如果想使用pasting,只需设置设置bootstrap=False),参数n_jobs用来指示Scikit-learn用多少CPU内核来进行训练和预测(-1表示让Scikit-learn使用所有可用的内核)

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag_clf = BaggingClassifier(
    DecisionTreeClassifier(random_state=42), n_estimators=500,
    max_samples=100, bootstrap=True, n_jobs=-1, random_state=42)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)

下图比较了单个决策树和一个由500个决策树组成的bagging集成方法的决策边界,可以看出集成预测的泛化效果很可能比单独的决策树要更好一些,二者偏差相近,但是继承方法方差要更小(两边训练集上的错误数量差不多,但是集成的决策边界更加光滑)

机器学习-集成学习:随机森林(Random Forest)_第2张图片  

1.2 随机森林

上面提到的Bagging方法是先构建一个BaggingClassifier,然后将结果传输到DecisionTreeClassifier,还有一种方法是使用RandomForestClassifier。Random Forest(随机森林)是一种基于树模型的Bagging的优化版本(对回归任务,还有一个RandomForestRegressor)。一下代码为训练一个500颗树的随机森林分类器,每棵树限制未16个叶子结点。

from sklearn.ensemble import RandomForestClassifier

rnd_clf = RandomForestClassifier(n_estimators=500, max_leaf_nodes=16, n_jobs=-1, random_state=42)
rnd_clf.fit(X_train, y_train)

y_pred_rf = rnd_clf.predict(X_test)

而同一批数据,用同样的算法只能产生一棵树,这时Bagging策略可以帮助我们产生不同的数据集。Bagging策略来源于bootstrap aggregation:从样本集(假设样本集N个数据点)中重采样选出Nb个样本(有放回的采样,样本数据点个数仍然不变为N),在所有样本上,对这n个样本建立分类器(ID3\C4.5\CART\SVM\LOGISTIC),重复以上步骤m次,获得m个分类器,最后根据这m个分类器的投票结果,决定数据属于哪一类。

每棵树的按照如下规则生成:

  1. 如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本,作为该树的训练集;
  2. 如果每个样本的特征维度为M,指定一个常数m<随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;
  3. 每棵树都尽最大程度的生长,并且没有剪枝过程。

一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。

随机森林再树的生长上引入了更多的随机性:分裂节点不再是搜索最好的特征(信息增益最大),而是在一个随机生成的子特征集里搜索最好的特征。建立多颗这样的决策树,然后通过这几课决策树来投票,决定数据属于哪一类(投票机制有一票否决制、少数服从多数、加权多数)

2. 随机森林分类效果的影响因素

  • 森林中任意两棵树的相关性:相关性越大,错误率越大;
  • 森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。

减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。

3. 随机森林有什么优缺点

优点:

  • 在当前的很多数据集上,相对其他算法有着很大的优势,表现良好。
  • 它能够处理很高维度(feature很多)的数据,并且不用做特征选择(因为特征子集是随机选择的)。
  • 在训练完后,它能够给出哪些feature比较重要。
  • 训练速度快,容易做成并行化方法(训练时树与树之间是相互独立的)。
  • 在训练过程中,能够检测到feature间的互相影响。
  • 对于不平衡的数据集来说,它可以平衡误差。
  • 如果有很大一部分的特征遗失,仍可以维持准确度。

缺点:

  • 随机森林已经被证明在某些噪音较大的分类或回归问题上会过拟合。
  • 对于有不同取值的属性的数据,取值划分较多的属性会对随机森林产生更大的影响,所以随机森林在这种数据上产出的属性权值是不可信的。

4. 随机森林如何处理缺失值?

根据随机森林创建和训练的特点,随机森林对缺失值的处理还是比较特殊的。

  • 首先,给缺失值预设一些估计值,比如数值型特征,选择其余数据的中位数或众数作为当前的估计值
  • 然后,根据估计的数值,建立随机森林,把所有的数据放进随机森林里面跑一遍。记录每一组数据在决策树中一步一步分类的路径.
  • 判断哪组数据和缺失数据路径最相似,引入一个相似度矩阵,来记录数据之间的相似度,比如有N组数据,相似度矩阵大小就是N*N
  • 如果缺失值是类别变量,通过权重投票得到新估计值,如果是数值型变量,通过加权平均得到新的估计值,如此迭代,直到得到稳定的估计值。

其实,该缺失值填补过程类似于推荐系统中采用协同过滤进行评分预测,先计算缺失特征与其他特征的相似度,再加权得到缺失值的估计,而随机森林中计算相似度的方法(数据在决策树中一步一步分类的路径)乃其独特之处。

5. 什么是OOB?随机森林中OOB是如何计算的,它有什么优缺点?

OOB

上面我们提到,构建随机森林的关键问题就是如何选择最优的m,要解决这个问题主要依据计算袋外错误率oob error(out-of-bag error)。

bagging方法中Bootstrap每次约有1/3的样本不会出现在Bootstrap所采集的样本集合中,当然也就没有参加决策树的建立,把这1/3的数据称为袋外数据oob(out of bag),它可以用于取代测试集误差估计方法。

袋外数据(oob)误差的计算方法如下:

  • 对于已经生成的随机森林,用袋外数据测试其性能,假设袋外数据总数为O,用这O个袋外数据作为输入,带进之前已经生成的随机森林分类器,分类器会给出O个数据相应的分类
  • 因为这O条数据的类型是已知的,则用正确的分类与随机森林分类器的结果进行比较,统计随机森林分类器分类错误的数目,设为X,则袋外数据误差大小=X/O

优缺点

这已经经过证明是无偏估计的,所以在随机森林算法中不需要再进行交叉验证或者单独的测试集来获取测试集误差的无偏估计。

6. 随机森林的过拟合问题

  1. 你已经建了一个有10000棵树的随机森林模型。在得到0.00的训练误差后,你非常高兴。但是,验证错误是34.23。到底是怎么回事?你还没有训练好你的模型吗?

    答:该模型过度拟合,因此,为了避免这些情况,我们要用交叉验证来调整树的数量。

7. 代码实现

GitHub:Jupyter Notebook Viewer

你可能感兴趣的:(机器学习,数据分析,Python,机器学习,集成学习,随机森林)