Sklearn-RandomForest随机森林参数及实例
本⽂转载⾄
在scikit-learn中,RandomForest的分类类是RandomForestClassifier,回归类是RandomForestRegressor,需要调参的参数包括两部分,第⼀部分是Bagging框架的参数,第⼆部分是CART决策树的参数。
07,bootstrap=True, oob_score=False, n_jobs=1, random_state=None, verbose=0,warm_start=False, class_weight=None)
1. 参数解读
1. Bagging框架的参数
和GBDT对⽐,GBDT的框架参数⽐较多,重要的有最⼤迭代器个数,步长和⼦采样⽐例,调参起来⽐较
费⼒。但是RF则⽐较简单,这是因为bagging框架⾥的各个弱学习器之间是没有依赖关系的,这减⼩的调参的难度。换句话说,达到同样的调参效果,RF调参时间要⽐GBDT 少⼀些。下⾯我来看看RF重要的Bagging框架的参数,由于RandomForestClassifier和RandomForestRegressor参数绝⼤部分相同,这⾥会将它们⼀起讲,不同点会指出。
n_estimators: 也就是弱学习器的最⼤迭代次数,或者说最⼤的弱学习器的个数,默认是10。⼀般来说n_estimators太⼩,容易⽋拟合,n_estimators太⼤,⼜容易过拟合,⼀般选择⼀个适中的数值。对Random Forest来说,增加“⼦模型数”(n_estimators)可以明显降低整体模型的⽅差,且不会对⼦模型的偏差和⽅差有任何影响。模型的准确度会随着“⼦模型数”的增加⽽提⾼,由于减少的是整体模型⽅差公式的第⼆项,故准确度的提⾼有⼀个上限。在实际应⽤中,可以以10为单位,考察取值范围在1⾄201的调参情况。
对⽐,Random Forest的⼦模型都拥有较低的偏差,整体模型的训练过程旨在降低⽅差,故其需要较少的⼦模型(n_estimators 默认值为10)且⼦模型不为弱模型(max_depth的默认值为None);Gradient Tree Boosting的⼦模型都拥有较低的⽅差,整体模型的训练过程旨在降低偏差,故其需要较多的⼦模型(n_estimators默认值为100)且⼦模型为弱模型(max_depth的默认值为3)。
bootstrap:默认True,是否有放回的采样。
oob_score :默认识False,即是否采⽤袋外样本来评估模型的好坏。有放回采样中⼤约36.8%的没有被采样到的数据,我们常常称之为袋外数据(Out Of Bag, 简称OOB),这些数据没有参与训练集模型的拟合,因此可以⽤来检测模型的泛化能⼒。个⼈推荐设置为True,因为袋外分数反应了⼀个模型拟合后的泛化能⼒。对单个模型的参数训练,我们知道可以⽤cross validation(cv)来进⾏,但是特别消耗时间,⽽且对于随机森林这种情况也没有⼤的必要,所以就⽤这个数据对决策树模型进⾏验证,算是⼀个简单的交叉验证,性能消耗⼩,但是效果不错。
criterion: 即CART树做划分时对特征的评价标准,分类模型和回归模型的损失函数是不⼀样的。分类RF对应的CART分类树默认是基尼系数gini,另⼀个可选择的标准是信息增益entropy,是⽤来选择节点的最优特征和切分点的两个准则。回归RF对应的CART回归树默认是均⽅差mse,另⼀个可以选择的标准是绝对值差mae。⼀般来说选择默认的标准就已经很好的。
从上⾯可以看出, RF重要的框架参数⽐较少,主要需要关注的是 n_estimators,即RF最⼤的决策树个数。
1. RF决策树的参数
RF的决策树参数,它要调参的参数基本和GBDT相同,如下:
max_features: RF划分时考虑的最⼤特征数。可以使⽤很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑log2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑N−−√N个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分⽐,即考虑(百分⽐xN)取整后的特征数,其中N为样本总特征数。⼀般来说,如果样本特征数不多,⽐如⼩于50,我们⽤默认的"None"就可以了,如果特征数⾮常多,我们可以灵活使⽤刚才描述的其他取值来控制划分时考虑的最⼤特征数,以控制决策树的⽣成时间。
max_depth: 决策树最⼤深度。默认为"None",决策树在建⽴⼦树的时候不会限制⼦树的深度这样建树时,会使每⼀个叶节点只有⼀个类别,或是达到min_samples_split。⼀般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最⼤深度,具体的取值取决于数据的分布。常⽤的可以取值10-100之间。
min_samples_split: 内部节点再划分所需最⼩样本数,默认2。这个值限制了⼦树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进⾏划分。 默认是2.如果样本量不⼤,不需要管这个值。如果样本量数量级⾮常⼤,则推荐增⼤这个值。
min_samples_leaf:叶⼦节点最少样本数。 这个值限制了叶⼦节点最少的样本数,如果某叶⼦节点数⽬⼩于样本数,则会和兄弟节点⼀起被剪枝。 默认是1,可以输⼊最少的样本数的整数,或者最少样
本数占样本总数的百分⽐。如果样本量不⼤,不需要管这个值。如果样本量数量级⾮常⼤,则推荐增⼤这个值。
min_weight_fraction_leaf:叶⼦节点最⼩的样本权重和。这个值限制了叶⼦节点所有样本权重和的最⼩值,如果⼩于这个值,则会和兄弟节点⼀起被剪枝。 默认是0,就是不考虑权重问题。⼀般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很⼤,就会引⼊样本权重,这时我们就要注意这个值了。
max_leaf_nodes: 最⼤叶⼦节点数。通过限制最⼤叶⼦节点数,可以防⽌过拟合,默认是"None”,即不限制最⼤的叶⼦节点数。如果加了限制,算法会建⽴在最⼤叶⼦节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
min_impurity_split: 节点划分最⼩不纯度。这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均⽅差)⼩于这个阈值,则该节点不再⽣成⼦节点,即为叶⼦节点 。⼀般不推荐改动默认值1e-7。
上⾯决策树参数中最重要的包括最⼤特征数max_features, 最⼤深度max_depth, 内部节点再划分所需最⼩样本数min_samples_split 和叶⼦节点最少样本数min_samples_leaf。
splitter: 随机选择属性"random"还是选择不纯度最⼤"best"的属性,建议⽤默认 best。
presort:是否对数据进⾏预分类,以加快拟合中最佳分裂点的发现。默认False,适⽤于⼤数据集。⼩数据集使⽤True,可以加快训练。
是否预排序,预排序可以加速查最佳分裂点,对于稀疏数据不管⽤,Bool,auto:⾮稀疏数据则预排序,若稀疏数据则不预排序
1. 进⾏预测的⼏种常⽤⽅法
predict_proba(x):给出带有概率值的结果。每个点在所有label(类别)的概率和为1.
predict(x):直接给出预测结果。内部还是调⽤的predict_proba(),根据概率的结果看哪个类型的预测值最⾼就是哪个类型。
predict_log_proba(x):和predict_proba基本上⼀样,只是把结果给做了log()处理。
1. RandomForest调参实例
#导⼊需要的库
import pandas as pd
import numpy as np
semble import RandomForestClassifier
id_search import GridSearchCV
from sklearn import cross_validation, metrics
import matplotlib.pylab as pltvalidation框架
%matplotlib inline
#导⼊数据,顺便看看数据的类别分布
train= pd.read_csv('C:\\Users\\86349\\Desktop\\train_modified\\train_modified.csv')
target='Disbursed' # Disbursed的值就是⼆元分类的输出
IDcol= 'ID'
train['Disbursed'].value_counts()
#可以看到类别输出如下,也就是类别0的占⼤多数:
0 19680
1 320
Name:Disbursed, dtype: int64
#接着选择好样本特征和类别输出,样本特征为除去ID和输出类别的列
x_columns = [x for x lumns if x not in [target,IDcol]]
X = train[x_columns]
y = train['Disbursed']
#不管任何参数,都⽤默认的,拟合下数据看看
rf0 = RandomForestClassifier(oob_score=True, random_state=10)
rf0.fit(X,y)
b_score_
y_predprob = rf0.predict_proba(X)[:,1]
print "AUC Score (Train): %f" % _auc_score(y,y_predprob)
#输出如下:0.98005 AUC Score (Train): 0.999833
#可见袋外分数已经很⾼(理解为袋外数据作为验证集时的准确率,也就是模型的泛化能⼒),⽽且AUC分数也很⾼(AUC是指从⼀堆样本中随机抽⼀个,抽到正
#⾸先对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)
#输出结果如下:
([mean:0.80681, std: 0.02236, params: {'n_estimators': 10},
mean: 0.81600, std: 0.03275, params:{'n_estimators': 20},
mean: 0.81818, std: 0.03136, params:{'n_estimators': 30},
mean: 0.81838, std: 0.03118, params:{'n_estimators': 40},
mean: 0.82034, std: 0.03001, params:{'n_estimators': 50},
mean: 0.82113, std: 0.02966, params:{'n_estimators': 60},
mean: 0.81992, std: 0.02836, params:{'n_estimators': 70}],
{'n_estimators':60},
0.8211334476626017)
#这样我们得到了最佳的弱学习器迭代次数,接着我们对决策树最⼤深度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)
#输出如下:
([mean:0.79379, std: 0.02347, params: {'min_samples_split': 50, 'max_depth': 3},
mean: 0.79339, std: 0.02410, params:{'min_samples_split': 70, 'max_depth': 3},
mean: 0.79350, std: 0.02462, params:{'min_samples_split': 90, 'max_depth': 3},
mean: 0.79367, std: 0.02493, params:{'min_samples_split': 110, 'max_depth': 3},
mean: 0.79387, std: 0.02521, params:{'min_samples_split': 130, 'max_depth': 3},
mean: 0.79373, std: 0.02524, params:{'min_samples_split': 150, 'max_depth': 3},
mean: 0.79378, std: 0.02532, params:{'min_samples_split': 170, 'max_depth': 3},
mean: 0.79349, std: 0.02542, params:{'min_samples_split': 190, 'max_depth': 3},
mean: 0.80960, std: 0.02602, params:{'min_samples_split': 50, 'max_depth': 5},
mean: 0.80920, std: 0.02629, params:{'min_samples_split': 70, 'max_depth': 5},
mean: 0.80888, std: 0.02522, params:{'min_samples_split': 90, 'max_depth': 5},
mean: 0.80923, std: 0.02777, params:{'min_samples_split': 110, 'max_depth': 5},
mean: 0.80823, std: 0.02634, params:{'min_samples_split': 130, 'max_depth': 5},
mean: 0.80801, std: 0.02637, params:{'min_samples_split': 150, 'max_depth': 5},
mean: 0.80792, std: 0.02685, params:{'min_samples_split': 170, 'max_depth': 5},
mean: 0.80771, std: 0.02587, params:{'min_samples_split': 190, 'max_depth': 5},
mean: 0.81688, std: 0.02996, params:{'min_samples_split': 50, 'max_depth': 7},
mean: 0.81872, std: 0.02584, params:{'min_samples_split': 70, 'max_depth': 7},
mean: 0.81501, std: 0.02857, params:{'min_samples_split': 90, 'max_depth': 7},
mean: 0.81476, std: 0.02552, params:{'min_samples_split': 110, 'max_depth': 7},
mean: 0.81476, std: 0.02552, params:{'min_samples_split': 110, 'max_depth': 7}, mean: 0.81557, std: 0.02791, params:{'min_samples_split': 130, 'max_depth': 7}, mean: 0.81459, std: 0.02905, params:{'min_samples_split': 150, 'max_depth': 7}, mean: 0.81601, std: 0.02808, params:{'min_samples_split': 170, 'max_depth': 7}, mean: 0.81704, std: 0.02757, params:{'min_samples_split': 190, 'max_depth': 7}, mean: 0.82090, std: 0.02665, params:{'min_samples_split': 50, 'max_depth': 9},
mean: 0.81908, std: 0.02527, params:{'min_samples_split': 70, 'max_depth': 9},
mean: 0.82036, std: 0.02422, params:{'min_samples_split': 90, 'max_depth': 9},
mean: 0.81889, std: 0.02927, params:{'min_samples_split': 110, 'max_depth': 9}, mean: 0.81991, std: 0.02868, params:{'min_samples_split': 130, 'max_depth': 9}, mean: 0.81788, std: 0.02436, params:{'min_samples_split': 150, 'max_depth': 9}, mean: 0.81898, std: 0.02588, params:{'min_samples_split': 170, 'max_depth': 9}, mean: 0.81746, std: 0.02716, params:{'min_samples_split': 190, 'max_depth': 9}, mean: 0.82395, std: 0.02454, params:{'min_samples_split': 50, 'max_depth': 11}, mean: 0.82380, std: 0.02258, params:{'min_samples_split': 70, 'max_depth': 11}, mean: 0.81953, std: 0.02552, params:{'min_samples_split': 90, 'max_depth': 11}, mean: 0.82254, std: 0.02366, params:{'min_samples_split': 110, 'max_depth': 11}, mean: 0.81950, std: 0.02768, params:{'min_samples_split': 130, 'max_depth': 11}, mean: 0.81887, std: 0.02636, params:{'min_samples_split': 150, 'max_depth': 11}, mean: 0.81910, std: 0.02734, params:{'min_samples_split': 170, 'max_depth': 11}, mean: 0.81564, std: 0.02622, params:{'min_samples_split': 190, 'max_depth': 11}, mean: 0.82291, std: 0.02092, params:{'min_samples_split': 50, 'max_depth': 13}, mean: 0.82177, std: 0.02513, params:{'min_samples_spl
it': 70, 'max_depth': 13}, mean: 0.82415, std: 0.02480, params:{'min_samples_split': 90, 'max_depth': 13}, mean: 0.82420, std: 0.02417, params:{'min_samples_split': 110, 'max_depth': 13}, mean: 0.82209, std: 0.02481, params:{'min_samples_split': 130, 'max_depth': 13}, mean: 0.81852, std: 0.02227, params:{'min_samples_split': 150, 'max_depth': 13}, mean: 0.81955, std: 0.02885, params:{'min_samples_split': 170, 'max_depth': 13}, mean: 0.82092, std: 0.02600, params:{'min_samples_split': 190, 'max_depth': 13}], {'max_depth':13, 'min_samples_split': 110},
0.8242016800050813)
#已经取了三个最优参数,看看现在模型的袋外分数:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论