\quad \quad 在集成学习简介中,简单的介绍了根据个体学习器学习方式不同划分的两大类集成学习方法,个体学习器间存在强依赖关系、必须串行生成的序列化方法,如Boosting;个体学习器间不存在强依赖关系、可同时生成的并行化方法,如Bagging。下面详细的说明一下Bagging 算法的进化版随机森林算法。
\quad \quad 随机森林(Random Forest, RF)可以看成是改进的Bagging算法,是一种灵活且易于使用的机器学习算法,即便没有超参数调优,也可以在大多数情况下得到很好的结果。它也是最常用的算法之一,因为它很简易,既可用于分类也能用于回归任务。
\quad \quad Rondom Forest 顾名思义,就是用随机的方式建立一个森林,森林里面由很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为哪一类。
\quad \quad 随机森林通过自助法(bootstrap)重采样技术,从原始训练样本集 N \large N N 中有放回地重复随机抽样 K \large K K 个样本生成新的训练样本集合,然后根据自助样本集生成 K \large K K 个分类树组成随机森林,新数据的分类结果按分类树投票多少形成的分数而定。其实质是对决策树算法的一种改进,将多个决策树合并在一起,每棵树的建立依赖于一个独立抽取的样品,森林中的每棵树具有相同的分布,分类误差取决于每一棵树的分类能力和它们的相关性。特征选择采用随机的方法去分裂每一个节点,然后比较不同情况下产生的误差。能够检测到的内在估计误差、分类能力和相关性决定选择特征的数目。单棵树的分类能力可能很小,但在随机产生大量的决策树后,一个测试样本可以通过每一棵树的分类结果经统计后选择最可能的分类。
\quad \quad 在建立每一棵决策树的过程中,有两点需要注意采样与完全分裂。
关于随机:
(1)训练每棵树时,从全部训练样本中选取一个子集进行训练(即bootstrap取样)。用剩余的数据进行评测,评估其误差;
(2)在每个节点,随机选取所有特征的一个子集,用来计算最佳分割方式。
算法流程:
(1)训练总样本的个数为N,则单棵决策树从N个训练集中有放回的随机抽取n个作为此单颗树的训练样本(bootstrap有放回取样)。
(2)令训练样例的输入特征的个数为M,m远远小于M,则我们在每颗决策树的每个节点上进行分裂时,从M个输入特征里随机选择m个输入特征,然后从这m个输入特征里选择一个最好的进行分裂。m在构建决策树的过程中不会改变。
注意:要为每个节点随机选出m个特征,然后选择最好的那个特征来分裂。
注意:决策树中分裂属性的两个选择度量:信息增益和基尼指数。
(3)每棵树都一直这样分裂下去,直到该节点的所有训练样例都属于同一类,不需要剪枝。由于之前的两个随机采样的过程保证了随机性,所以就算不剪枝,也不会出现over-fitting。
结果判定:
(1)目标特征为数字类型:取t个决策树的平均值作为分类结果。
(2)目标特征为类别类型:少数服从多数,取单棵树分类结果最多的那个类别作为整个随机森林的分类结果。
预测:
随机森林是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类,然后看看哪一类被选择最多,就预测这个样本为那一类。
说明:通过bagging有放回取样后,大约36.8%的没有被采样到的数据,我们常常称之为袋外数据。这些数据没有参与训练集模型的拟合,因此可以用来检测模型的泛化能力。
随机森林的三个主要超参数调整:
节点规模
随机森林不像决策树,每一棵树叶子节点所包含的观察样本数量可能十分少。该超参数的目标是生成树的时候尽可能保持小偏差
树的数量
在实践中选择数百棵树一般是比较好的选择
预测器采样的数量
一般来说,如果一共有 D \large D D 个预测器,那么可以在回归任务中使用 D 3 \large \tfrac{D}{3} 3D 个预测器作为采样数,在分类任务中使用 D \large \sqrt{D} D 个预测器作为抽样。
【sklearn.ensemble.RandomForestClassifier官方文档】
简单案例
from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.tree import DecisionTreeClassifier
seed = 1
X, y = make_blobs(n_samples=1000, n_features=6, centers=50, random_state=seed)
# 普通决策树
clf = DecisionTreeClassifier(max_depth=None, min_samples_split=2, random_state=seed)
scores = cross_val_score(clf, X, y)
print(scores.mean())
# 随机森林
clf = RandomForestClassifier(n_estimators=10, max_depth=None, min_samples_split=2, random_state=seed)
scores = cross_val_score(clf, X, y)
print(scores.mean())
# RF随机森林的变种
clf = ExtraTreesClassifier(n_estimators=10, max_depth=None, min_samples_split=2, random_state=seed)
scores = cross_val_score(clf, X, y)
print(scores.mean())
【sklearn.ensemble.RandomForestRegressor官方文档】
简单案例
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_regression
X, y = make_regression(n_features=4, n_informative=2,
random_state=0, shuffle=False)
regr = RandomForestRegressor(max_depth=2, random_state=0)
regr.fit(X, y)
print(regr.predict([[0, 0, 0, 0]]))
【优点】:
【缺点】:
参考资料:
1、《西瓜书》
2、https://blog.csdn.net/qq_38299170/article/details/103842151