sklearn中RandomForest详解

文章目录

  • 随机森林基本原理
  • RandomForestClassifier
    • 参数说明
    • 实例
  • RandomForestClassifier

随机森林基本原理

随机森林是一种bagging算法。bagging是一种随机采样(bootsrap)算法,与boosting不同,bagging弱学习器之间没有依赖关系,bagging通过采样训练不同的模型,然后进行组合。随机森林通过采样训练不同的决策树模型,然后进行组合。

sklearn中RandomForest详解_第1张图片

注:注意到这和GBDT的子采样是不同的。GBDT的子采样是无放回采样,而Bagging的子采样是放回采样。

随机森林中的随机性表现在:(1)在随机森林中的每棵树都是根据训练集中的随机抽样的样本构建的。(2)在树的构造过程中拆分每个节点时,最好的切分点可能出现在所有的特征中也可能所有特征的一个特征子集中(子集大小为max_features)

这两个随机性是为了减少减少森林估计量的方差,单个决策树通常表现出较高的方差并且倾向于过度拟合。在森林中注入的随机性产生决策树,随机森林通过组合不同的树木得到预测的平均值,可以减小预测误差(方差),但略微增加偏差。

注:scikit-learn实现通过平均分类器的概率预测来组合分类器,而不是让每个分类器对单个分类投票。

优缺点:

(1) 训练可以高度并行化,对于大数据时代的大样本训练速度有优势

(2) 由于可以随机选择决策树节点划分特征,这样在样本特征维度很高的时候,仍然能高效的训练模型。

(3) 在训练后,可以给出各个特征对于输出的重要性

RandomForestClassifier

参数说明

随机森林分类,sklearn 中的接口如下:

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)

参数

参数 说明
n_estimators 决策树的个数,若n_estimators太小容易欠拟合,太大不能显著的提升模型,所以n_estimators选择适中的数值。必须设置
bootstrap 是否对样本集进行有放回抽样来构建树,默认值True。
oob_score 是否采用袋外样本来评估模型的好坏,默认false,推荐设置True。
max_features 构建决策树最优模型时考虑的最大特征数。默认是"auto",表示最大特征数是N的平方根;“log2"表示最大特征数是 ;"sqrt"表示最大特征数是 。如果是整数,代表考虑的最大特征数;如果是浮点数,表示对(N * max_features)取整。其中N表示样本的特征数。
max_depth 决策树最大深度。默认None,表示决策树在构建最优模型的时候不会限制子树的深度。如果模型样本量多,特征也多的情况下,推荐限制最大深度;若样本量少或者特征少,则不限制最大深度。
min_samples_leaf 叶子节点含有的最少样本。若叶子节点样本数小于min_samples_leaf,则对该叶子节点和兄弟叶子节点进行剪枝,只留下该叶子节点的父节点。整数型表示个数,浮点型表示取大于等于(样本数 * min_samples_leaf)的最小整数。min_samples_leaf默认值是1。
min_samples_split 节点可分的最小样本数,默认值是2。整数型和浮点型的含义与min_samples_leaf类似。
max_leaf_nodes 最大叶子节点数。int设置节点数,None表示对叶子节点数没有限制。
min_impurity_decrease 节点划分的最小不纯度。假设不纯度用信息增益表示,若某节点划分时的信息增益大于等于min_impurity_decrease,那么该节点还可以再划分;反之,则不能划分。
criterion 表示节点的划分标准。两种取值:entropy,默认"gini。"不纯度标准参考Gini指数,信息增益标准参考"entrop"熵。
min_samples_leaf 叶子节点最小的样本权重和。叶子节点如果小于这个值,则会和兄弟节点一起被剪枝,只保留叶子节点的父节点。默认是0,则不考虑样本权重问题。一般来说,如果有较多样本的缺失值或偏差很大,则尝试设置该参数值。
warm_start 默认为False,设置True为时,重用上一个调用的解决方案以适应并向集合添加更多估计量,否则,仅适应一个全新的森林
class_weight 默认无,{“ balanced”,“ balanced_subsample”}。
对于四分类问题,指定方式:[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}]而不是[{1:1}, {2:5}, {3:1}, {4:1}]。
max_samples 从X抽取以训练每个基本估计量的样本数。当bootstrap为True时,默认不指定,则抽取X.shape[0]样本。如果为int,则抽取max_samples样本。若为float,则抽取样本数max_samples * X.shape[0]max_samples(0, 1)
min_impurity_split float,默认=无。树木生长尽早停止的阈值。如果节点的杂质高于阈值,则该节点将分裂,否则为叶。
min_impurity_decrease float,默认值= 0.0。如果节点分裂导致杂质减少大于或等于该值,则该节点将分裂。
random_state 控制构建树时使用的样本的随机性(if bootstrap=True)和在每个节点上寻找最佳分割时要考虑的要素采样(if max_features < n_features )。

应通过设置树的max_depthmin_samples_leaf等参数值来控制树的复杂性和大小。每次分割时,特征总是随机排列的。因此,即使使用相同的训练数据,找到的最佳分割也可能会有所不同,max_features=n_features并且bootstrap=False,如果在最佳分割的搜索过程中枚举的几个分割的标准改进相同,则最佳分割也可能有所不同 。为了在拟合过程中获得确定性的行为,random_state必须进行修复。

属性中较为重要的是查看各个特征的重要性:feature_importances_

方法

方法 说明
decision_path(X) 返回森林中的决策路径。
fit(X,y) 根据训练集(X,y)建立森林。
predict(x) 预测X的类。
predict_proba(X) 预测X的类概率。

实例

以sklearn中的鸢尾花数据集为例进行说明。

1、加载必要的库

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn import metrics
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

2、加载并切分数据

X,y = load_iris(return_X_y=True)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=2020)

3、使用默认参数进行分类,查看分类结果

# 采用默认参数进行分类
rfc = RandomForestClassifier()
rfc.fit(X_train,y_train)

pred = rfc.predict(X_test)
print(metrics.classification_report(pred,y_test))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcDZCw5p-1594361567190)(随机森林.assets/image-20200710102456405.png)]

查看默认参数:

rfc.get_params(deep=True)

sklearn中RandomForest详解_第2张图片

4、进行简单的网格调参

# 调参
rfc = RandomForestClassifier()
parameters = {'n_estimators': range(30,80,10),'max_depth':range(3,10,2),
              'min_samples_leaf':[5,6,7],'max_features':[1,2,3]}

grid_rfc = GridSearchCV(rfc,parameters,scoring='f1_macro')

grid_rfc.fit(X,y)

grid_rfc.best_params_,grid_rfc.best_score_

在这里插入图片描述

5、用最优参数重新训练预测


rfc_param = RandomForestClassifier(n_estimators=50,max_depth=3,max_features=2,min_samples_leaf=7)
rfc_param.fit(X_train,y_train)

pred = rfc_param.predict(X_test)
print(metrics.classification_report(pred,y_test))

sklearn中RandomForest详解_第3张图片

可以看到准确率明显提升了。

6、查看特征重要性

# RandomForest 特征重要性
# 获取重要性
feat_important = rfc_param.feature_importances_
# 特征名
feat_name = load_iris().feature_names
plt.barh(range(len(feat_name)),feat_important,tick_label=feat_name)

sklearn中RandomForest详解_第4张图片

当数据集数目多,特征复杂时,建议分步调参。此处参考:scikit-learn随机森林调参小结

(1)首先对n_estimators进行网格搜索。

param_test1 = {'n_estimators':range(10,71,10)}
gsearch1 = GridSearchCV(estimator = RandomForestClassifier(min_samples_split=100,
                                  min_samples_leaf=20,max_depth=8,max_features='sqrt' ,random_state=10), 
                       param_grid = param_test1, scoring='roc_auc',cv=5)
gsearch1.fit(X,y)
gsearch1.best_params_

(2)对决策树最大深度max_depth和内部节点再划分所需最小样本数min_samples_split进行网格搜索。

param_test2 = {'max_depth':range(3,14,2), 'min_samples_split':range(50,201,20)}
gsearch2 = GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60, 
                                  min_samples_leaf=20,max_features='sqrt' ,oob_score=True, random_state=10),
   param_grid = param_test2, scoring='roc_auc',iid=False, cv=5)
gsearch2.fit(X,y)
gsearch1.best_params_

(3)对于内部节点再划分所需最小样本数min_samples_split,我们暂时不能一起定下来,因为这个还和决策树其他的参数存在关联。下面我们再对内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf一起调参。

param_test3 = {'min_samples_split':range(80,150,20), 'min_samples_leaf':range(10,60,10)}
gsearch3 = GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60, max_depth=13,
                                  max_features='sqrt' ,oob_score=True, random_state=10),
   param_grid = param_test3, scoring='roc_auc',iid=False, cv=5)
gsearch3.fit(X,y)
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

(4)最后我们再对最大特征数max_features做调参:

param_test4 = {'max_features':range(3,11,2)}
gsearch4 = GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60, max_depth=13, min_samples_split=120,
                                  min_samples_leaf=20 ,oob_score=True, random_state=10),
   param_grid = param_test4, scoring='roc_auc',iid=False, cv=5)
gsearch4.fit(X,y)
gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_

(5)用我们搜索到的最佳参数,我们再看看最终的模型拟合:

rf2 = RandomForestClassifier(n_estimators= 60, max_depth=13, min_samples_split=120,
                                  min_samples_leaf=20,max_features=7 ,oob_score=True, random_state=10)
rf2.fit(X,y)
print rf2.oob_score_

RandomForestClassifier

随机森林回归与随机森林分类十分相似,唯一的区别在于参数:criterion,取值情况为:{“mse”, “mae”}, default=”mse”

下面时波斯顿房价预测的例子:

from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt


X,y = load_boston(return_X_y=True)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=2020)


# 采用默认参数进行回归
rfr = RandomForestRegressor()
rfr.fit(X_train,y_train)

pred = rfr.predict(X_test)
print(metrics.mean_squared_error(pred,y_test))

查看特征重要性:

# RandomForest 特征重要性
# 获取重要性
feat_important = rfr.feature_importances_
# 特征名
feat_name = load_boston().feature_names
plt.barh(range(len(feat_name)),feat_important,tick_label=feat_name)

sklearn中RandomForest详解_第5张图片

你可能感兴趣的:(sklearn,决策树,随机森林模型)