Breiman在2001年提出了随机森林方法,是集成学习bagging类方法的一种,也是最早的集成学习算法之一。随机森林可以在绝大多数的数据集上表现出比单独的决策树更好的性能,同时随机森林本身也可以作为一种特征选择的方法。
一、随机森林原理
随机森林算法本质是对决策树算法的一种改进,将多个决策树合并在一起,每棵树的建立依赖于一个独立抽取的样品,森林中的每棵树具有相同的分布,分类误差取决于每一棵树的分类能力和它们之间的相关性。特征选择采用随机的方法去分裂每一个节点,然后比较不同情况下产生的误差。能够检测到的内在估计误差、分类能力和相关性决定选择特征的数目。单棵树的分类能力可能很小,但在随机产生大量的决策树后,一个测试样品可以通过每一棵树的分类结果经统计后选择最可能的分类。
自助采样法
基于自助采样法随机森林的构建过程为:
1.从原始训练集中使用Bootstraping方法随机有放回采样选出m个样本,共进行n_tree次采样,生成n_tree个训练集。
2.对于n_tree个训练集,我们分别训练n_tree个决策树模型。
3.对于单个决策树模型,假设训练样本特征的个数为n,那么每次分裂时根据信息增益/信息增益比/基尼指数选择最好的特征进行分裂。
4.每棵树都一直这样分裂下去,直到该节点的所有训练样例都属于同一类。在决策树的分裂过程中不需要剪枝。
5将生成的多棵决策树组成随机森林。对于分类问题,按多棵树分类器投票决定最终分类结果;对于回归问题,由多棵树预测值的均值决定最终预测结果。
注:随机森林不但对样本进行采样,也会对属性进行采样,即横竖采样,不过对属性的采样不再是自助采样法了,只是简单的按一定比例随机采样。
二、随机森林的特征选择
随机森林进行特征选择,得现有一个对特征好坏的度量。具体如下
2.1特征好坏衡量
对每一颗决策树,选择相应的袋外数据(out of bag,OOB)计算袋外数据误差,记为errOOB1。
所谓袋外数据是指,每次建立决策树时,通过重复抽样得到一个数据用于训练决策树,这时还有大约1/3的数据没有被利用,没有参与决策树的建立。这部分数据可以用于对决策树的性能进行评估,计算模型的预测错误率,称为袋外数据误差。
随机对袋外数据OOB所有样本的特征X加入噪声干扰(可以随机改变样本在特征X处的值),再次计算袋外数据误差,记为errOOB2。
假设森林中有N棵树,则特征X的重要性=∑(errOOB2-errOOB1)/N。这个数值之所以能够说明特征的重要性是因为,如果加入随机噪声后,袋外数据准确率大幅度下降(即errOOB2上升),说明这个特征对于样本的预测结果有很大影响,进而说明重要程度比较高。
2.2特征选择
在特征重要性的基础上,特征选择的步骤如下:
1.计算每个特征的重要性,并按降序排序。
2.确定要剔除的比例,依据特征重要性剔除相应比例的特征,得到一个新的特征集。
3.用新的特征集重复上述过程,直到剩下m个特征(m为提前设定的值)。
4.根据上述过程中得到的各个特征集和特征集对应的袋外误差率,选择袋外误差率最低的特征集。
三、sklearn 里的随机森林
sklearn里的随机森林库函数使用:
分类:
from sklearn.ensemble import RandomForestClassifier #分类器
print("DecisionTreesClassifier")
clf1 = RandomForestClassifier(n_estimators = 100) #训练100个基分类器
clf1.fit(traindata,trainlabel)
res = clf1.predict(testdata)
- 参数
- n_estimators
子树的数量,默认值10。子树的数量越多,模型性能更好,但同时运行变慢。如果处理器可以承受,可选择尽可能高的值,以达到预测效果更好更稳定的目的。
- criterion
衡量分裂质量的功能,默认值“GINI”。
可选项有基尼杂质的“gini”和信息增益的熵“entropy”。
- max_features
划分时考虑的最大特征数: 可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑log2Nlog2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑N−−√N个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
- max_depth
决策树最大深度默认可以不输入,即None,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。
- min_samples_split
内部节点再划分所需最小样本数,这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。默认是2。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
- min_samples_leaf
叶子节点最少样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
回归:
from sklearn.ensemble import RandomForestRegressor #回归器
print("DecisionTreesRegressor")
clf1 = RandomForestRegressor(n_estimators = 100) #训练100个基分类器
clf1.fit(traindata,trainlabel)
res = clf1.predict(testdata)