[机器学习]GBDT(调参)

582 阅读8分钟

1/总结

因为gbdt是boosting集成学习思想的算法。
从大的层面上讲:框架层面的参数
从小的层面上讲:决策树的参数

2/框架的参数调整

首先,我们来看boosting集成学习框架相关的重要参数。
由于GradientBoostingClassifier和GradientBoostingRegressor的参数绝大部分相同,
我们下面会一起来讲,不同点会单独指出。

1)n_estimators

   estimator英文意思是:估计器。
   最大迭代次数,也就是弱学习器的个数,也就是cart决策树的个数。
   一般来说n_estimators太小,容易欠拟合(学习得不够好),
   n_estimators太大,又容易过拟合(学习得太好了,细枝末节都学习到了,导致泛化能力不行)。
   一般选择一个适中的数值,默认是100。
   在实际调参的过程中,我们常常将n_estimators和参数learning_rate学习率一起考虑。
   

2)learning_rate

   即每个弱学习器的权重缩减系数,也称作步长
   取值范围为[0,1]。默认是1
   对于同样的训练集拟合效果,较小的步长意味着我们需要更多的弱学习器的迭代次数。
   通常我们用步长和迭代最大次数n_estimators一起来决定算法的效果。
   所以这两个参数n_estimators和learning_rate要一起调参。
   一般来说,可以从一个小一点的learning_rate开始调参
   一般我们从0.1开始
   

3)subsample

   子采样,取值为(0,1]。
   注意这里的子采样和随机森林RF不一样,随机森林使用的是有放回抽样,而这里是不放回抽样。
   如果取值为1,则全部样本都使用,等于没有使用子采样。
   如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。
   选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。
   推荐在[0.5, 0.8]之间,默认是1.0,即不使用子采样。
   

4)init

   即我们的初始化的时候的弱学习器,及f0(x)。
   如果不输入,则用训练集样本来做样本集的初始化分类回归预测。
   否则用init参数提供的学习器做初始化分类回归预测。
   一般用在我们对数据有先验知识,或者之前做过一些拟合的时候,如果没有的话就不用管这个参数了。
         

5)loss

   我们GBDT算法中的损失函数。分类模型和回归模型的损失函数是不一样的。
   
   对于分类模型:
       有"对数似然损失函数deviance""指数损失函数exponential"两者可以选择。
       默认是"对数似然损失函数deviance"。
       一般来说,推荐使用默认的"deviance"。
       它对二元分类和多元分类各自都有比较好的优化。
       而指数损失函数等于把我们带到了Adaboost算法

    对于回归模型: 有均方差"ls", 绝对损失"lad", Huber损失"huber"和分位数损失“quantile”。 默认是均方差"ls"。 一般来说,如果数据的噪音点不多,用默认的均方差"ls"比较好。 如果是噪音点较多,则推荐用抗噪音的损失函数"huber"。 而如果我们需要对训练集进行分段预测的时候,则采用“quantile”。

6)alpha:

   这个参数只有GradientBoostingRegressor有,及只有回归决策树用得到。
   当我们使用Huber损失"huber"和分位数损失“quantile”时,需要指定分位数的值。
   默认是0.9,如果噪音点较多,可以适当降低这个分位数的值。
   

3/决策树参数的调整

  这里我们再对GBDT的弱学习器(及cart决策树)的重要参数做一个总结。
  由于GBDT使用了CART回归决策树,因此它的参数基本来源于决策树类,
  也就是说,和DecisionTreeClassifier和DecisionTreeRegressor的参数基本类似。
  

1)max_features

  划分时考虑的最大特征数,假设我们有N个特征
  可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征。
  如果是"log2"意味着划分时最多考虑log2N个特征;
  如果是"sqrt"或者"auto"意味着划分时最多考虑根号下N个特征。
  如果是整数,代表考虑的特征绝对数。
  如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。
  一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

2)max_depth

  默认可以不输入,如果不输入的话,在构建决策树的时候不会限制树的深度。
  一般来说,数据少或者特征少的时候可以不管这个值。
  如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。
  常用的可以取值10-100之间。
  

3)min_samples_split

  节点再划分所需最小样本数
  这个值限制了节点继续划分的条件。
  如果某节点中的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。
  默认是2,如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

4)min_samples_leaf

  叶子节点最少样本数 
  这个值限制了叶子节点中最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。
  默认是1,可以输入最少的样本数的整
  叶子节点中样本太少,则说明叶子节点数会很多,这样可能导致过拟合。
      
      

5)min_weight_fraction_leaf

  叶子节点最小的样本权重和
  这个值限制了叶子节点中所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 
  默认是0,就是不考虑权重问题。
  一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
  

6)max_leaf_nodes

  最大叶子节点数
  通过限制最大叶子节点数,可以防止过拟合。
  默认是"None”,即不限制最大的叶子节点数。
  如果加了限制,算法会建立在最大叶子节点数内最优的决策树。
  如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

7)min_impurity_split

  节点划分最小不纯度
  这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。
  一般不推荐改动默认值1e-7

4/框架参数和决策树参数如何权衡

 1.先对提升框架内的迭代次数和学习率做调整,选一个较小的学习率,对迭代次数网格化调参。
    及先确定一个较小的learning_rate,
    然后再遍历多个n_estimators参数,
    最后找到一个最合格是组合。

 2.接下来对决策树调参,先一起调整max_depth和min_samples_split,根据输出的最优值将max_depth定下来,后续再调整最小划分样本数。

 3.再对内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf一起调参。看二者的最优值是否在边界上,如果在边界上,就进一步改变参数范围再网格化调参

 4.再对max_features和subsample进行网格化。

 5.最后可以通过,减小学习率,增大迭代次数,增加泛化能力,防止过拟合。保持两者的乘积基本不变,但步长设定过小,会导致拟合效果反而变差。
 
  learning_rate和n_estimators是需要互相权衡的参数,一般来说learning_rate较低时效果还都不错,我们只需要训练足够多的树就可以。
但是对于特定学习率,树的数量很大时,可能导致过拟合,如果调低学习率增加树的数量,又会引起计算时间的增长。 

因此可采用如下调整方式: 
    1.选择相对较小的学习率,一般默认0.1即可,不过有时根据问题不同可能选择0.05-0.2 
    2.选择对应该学习率的最优的树数目,要考虑运行效率,因为后面还要测试其他参数 
    3.调整生成树对应参数 
    4.调低学习率,增加树的数目,来得到更稳健的模型。
    

接下来,调整树参数,可以采用如下顺序: 
调整 max_depth 和 min_samples_split ;max_depth 取3-12,steps=2 ;min_samples_split取2-10,steps=2 

调整min_samples_leaf ;min_samples_leaf取2-10
调整max_features ;max_features取3-13,step=1 
调参顺序是我们在实践中要认真考虑的,应首先调对结果影响最大的参数,比如max_depth and num_samples_split。