随机森林 RandomForest

1、集成学习

集成学习(ensemble learning)可以说是现在非常火爆的机器学习方法了。它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务。也就是我们常说的“博采众长”。集成学习可以用于分类问题集成,回归问题集成,特征选取集成,异常点检测集成等等。在现在的各种算法竞赛中,随机森林,梯度提升树(GBDT),Xgboost等集成
算法的身影也随处可见。
更多关于集成学习的概念和公式推导这里不过多阐释,有兴趣可看这篇博客刘建平集成学习博客

1.1 Sklearn中的集成算法模块

类功能
ensemble.AdaBoostClassifier AdaBoost分类
ensemble.AdaBoostRegressor Adaboost回归
ensemble.BaggingClassifier 装袋分类器
ensemble.BaggingRegressor 装袋回归器
ensemble.ExtraTreesClassifier Extra-trees分类(超树,极端随机树)
ensemble.ExtraTreesRegressor Extra-trees回归
ensemble.GradientBoostingClassifier 梯度提升分类
ensemble.GradientBoostingRegressor 梯度提升回归
ensemble.IsolationForest 隔离森林(用于检测异常值)
ensemble.RandomForestClassifier 随机森林分类
ensemble.RandomForestRegressor 随机森林回归
ensemble.RandomTreesEmbedding 完全随机树的集成
ensemble.VotingClassifier 用于不合适估算器的软投票/多数规则分类器(如集成SVM)
ensemble.HistGradientBoostingRegressor 基于直方图的梯度增强回归树
ensemble.HistGradientBoostingClassifier 基于直方图的梯度增强分类树

2、随机森林 RandomForest

2.1 优缺点分析

RF的主要优点有:

  1. 训练可以高度并行化,对于大数据时代的大样本训练速度有优势。个人觉得这是的最主要的优点。
  2. 由于可以随机选择决策树节点划分特征,这样在样本特征维度很高的时候,仍然能高效的训练模型。
  3. 在训练后,可以给出各个特征对于输出的重要性。
  4. 由于采用了随机采样,训练出的模型的方差小,泛化能力强。
  5. 对于Boosting系列的Adaboost和GBDT, RF实现比较简单。
  6. 对部分特征缺失不敏感。

RF的主要缺点有:

  1. 某些噪音比较大的样本集上,RF模型容易陷入过拟合。
  2. 取值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果。

2.2 分类/回归

2.2.1 RandomForestClassifier

sklearn.ensemble.RandomForestClassifier(n_estimators=100, 
                                        criterion='gini', 
                                        max_depth=None, 
                                        min_samples_split=2,
                                        min_samples_leaf=1, 
                                        min_weight_fraction_leaf=0.0, 
                                        max_features='auto', 
                                        max_leaf_nodes=None, 
                                        min_impurity_decrease=0.0, 
                                        min_impurity_split=None, 
                                        bootstrap=True, 
                                        oob_score=False, 
                                        n_jobs=None, 
                                        random_state=None, 
                                        verbose=0, 
                                        warm_start=False, 
                                        class_weight=None, 
                                        ccp_alpha=0.0, 
                                        max_samples=None
                                       )

2.2.2RandomForestRegressor

sklearn.ensemble.RandomForestRegressor(n_estimators=100, 
                                       criterion='mse', 
                                       max_depth=None, 
                                       min_samples_split=2, 
                                       min_samples_leaf=1, 
                                       min_weight_fraction_leaf=0.0, 
                                       max_features='auto', 
                                       max_leaf_nodes=None, 
                                       min_impurity_decrease=0.0, 
                                       min_impurity_split=None, 
                                       bootstrap=True, 
                                       oob_score=False, 
                                       n_jobs=None, 
                                       random_state=None, 
                                       verbose=0, 
                                       warm_start=False, 
                                       ccp_alpha=0.0, 
                                       max_samples=None
                                      )

2.2.3 重要参数解释

参数 含义
n_estimators 基学习器的数量,n_estimators越大效果往往越好。到一定的数量再增大模型提升会很小,需要的计算量和内存也越大时间越长。
criterion 树做划分时对特征的评价标准。分类RF默认是基尼系数(“gini”),另一个标准是信息增益(“entropy”)。回归RF默认是mse,另一个是绝对值差mae。
max_features RF划分时考虑的最大特征数。默认值为总特征个数开平方取整,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
max_depth 决策树最大深度。一般来说数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。
min_samples_split 内部节点再划分所需最小样本数。这个值限制了子树继续划分的条件,如果某节点的样本数少于该值,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
min_samples_leaf 叶子节点最少样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量数量级非常大,则推荐增大这个值。
min_weight_fraction_leaf 叶子节点最小的样本权重。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
max_leaf_nodes 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
min_impurity_split 节点划分最小不纯度。这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。一般不推荐改动默认值1e-7
oob_score 即是否采用袋外样本来评估模型的好坏。默认识False。个人推荐设置为True,因为袋外分数反应了一个模型拟合后的泛化能力。
bootstrap 默认True,代表采用这种有放回的随机抽样技术。通常,这个参数不会被我们设置为False。

2.2.4 重要属性

属性 含义
estimators_ 输出包含单个决策树分类器的列表,是所有训练过的基分类器的集合
classes_ 输出一个数组(array)或者一个数组的列表(list), 结构为标签的数目(n classes)输出所有标签
feature_ importances_ 输出一个数组,结构为特征的数目(n features)返回每个特征的重要性,一般是 这个特征在多次分枝中产的信息增益的综合,也被称为”基尼重要性”(Gini Importance)
n_ classes_ 输出整数或列表,标签类别的数据
n_ features_ 在训练模型(ft)时使用的特征个数
n_ outputs_ 在训练模型(it)时输出的结果的个数
oob_ score_ 输出浮点数,使用袋外数据来验证模型效益的分数
oob_ decision function_ 根据袋外验证结果计 算的决策函数。如果n_ `estimators非常小, 那有可能在进行随机放回抽样的过程中没有数据掉落在袋外,在这种情况下,oob_ decision. _function 的结果会是NaN。

2.2.5 重要接口

接口 含义
apply (X[, check input]) 输入测试集或样本点, 返回每个样本被分到的叶节点的索引check input是接口apply的参数,输入布尔值,默认True,通常不使用
decision_ path(X[, check_input) 输入测试集或样本点, 返回树中的决策树结构,Check input同样是参数
fit() 不多说
get_ params(deep]) 布尔值,获取这个模型评估对象的参数。默认为True,表示返回此估计器的参数幷包含作为估算器的子对象。返回模型评估对象在实例化时的参数设置。
predict() 和fit中提供的训练集结构一致,不多说
predict_ log_ proba(X) 预测所提供的测试集X中样本点归属于各个标签的对数概率
predict proba(X[, check_input]) 预测所提供的测试集 X中样本点归属于各个标签的概率
score() 不多说
set_ params(**params) 可以为已经建立的评估器重设参数,返回重新设置的评估器本身

3、随机森林的调参

接下来以sklearn中的乳腺癌数据集来进行调参实例。

1.导入需要的库

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

2.导入数据集,探索数据

data = load_breast_cancer()
 
data
 
data.data.shape
 
data.target

3. 进行一次简单的建模,看看模型本身在数据集上的效果

交叉验证的分类默认scoring=‘accuracy’,你也可以换成其他的指标(后面会持续更新分类的评价指标)。

rfc = RandomForestClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,data.data,data.target,cv=10).mean()
 
score_pre

4. 随机森林调整的第一步:无论如何先来调n_estimators

我们将使用网格搜索对参数一个个进行调整。为什么我们不同时调整多个参数呢?原因有两个:

  1. 同时调整多个参数会运行非常缓慢;
  2. 同时调整多个参数,会让我们无法理解参数的组合是怎么得来的,所以即便网格搜索调出来的结果不好,我们也不知道从哪里去改。

在这里我们选择学习曲线,只有学习曲线,才能看见趋势。我个人的倾向是,要看见n_estimators在什么取值开始变得平稳,是否一直推动模型整体准确率的上升等信息。第一次的学习曲线,可以先用来帮助我们划定范围,我们取每十个数作为一个阶段,来观察n_estimators的变化如何引起模型整体准确率的变化。

scorel = []
for i in range(0,200,10):
    rfc = RandomForestClassifier(n_estimators=i+1,
                                 n_jobs=-1,
                                 random_state=90)
    score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
    scorel.append(score)
print(max(scorel),(scorel.index(max(scorel))*10)+1)
plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scorel)
plt.show()

5. 开始按照参数对模型整体准确率的影响程度进行调参,调整max_depth

param_grid = {'max_depth':np.arange(1, 20, 1)}
 
#   一般根据数据的大小来进行一个试探,乳腺癌数据很小,所以可以采用1~10,或者1~20这样的试探
#   但对于像digit recognition那样的大型数据来说,我们应该尝试30~50层深度(或许还不足够
#   更应该画出学习曲线,来观察深度对模型的影响
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)#网格搜索
GS.fit(data.data,data.target)
 
print(GS.best_params_)#显示调整出来的最佳参数
 
print(GS.best_score_)#返回调整好的最佳参数对应的准确率

6. 调整max_features

param_grid = {'max_features':np.arange(5,30,1)} 

rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
 
print(GS.best_params_)
 
print(GS.best_score_)

7.调整min_samples_leaf

param_grid={'min_samples_leaf':np.arange(1, 1+10, 1)}

rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
 
print(GS.best_params_)
 
print(GS.best_score_)

8.调整min_samples_split

param_grid={'min_samples_split':np.arange(2, 2+20, 1)}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
 
print(GS.best_params_)
 
print(GS.best_score_)

9.调参完毕,总结最佳参数

网格搜索也可以一起调整多个参数,如果有时间,电脑CPU,内存足够好可以自己跑一下,看看网格搜索会给我们怎样的结果,有时候,它的结果比我们的好,有时候,我们手动调整的结果会比较好。当然了,我们的乳腺癌数据集非常完美,所以
只需要调n_estimators一个参数就达到了随机森林在这个数据集上表现得极限。

rfc = RandomForestClassifier(n_estimators=68,
                             random_state=90,
                             criterion="gini",
                             min_samples_split=8,
                             min_samples_leaf=1,
                             max_depth=12,
                             max_features=2,
                             max_leaf_nodes=36
                             )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章