实例:随机森林在乳腺癌数据上的调参

实例:随机森林在乳腺癌数据上的调参
使模型预测更好的特征
A. max_features:增加复杂度
原因:
增加max_features一般能提高模型的性能,因为在每个节点上,我们有更多的选择可以考虑。 然而,这未必完全是对的,因为它降低了单个树的多样性,而这正是随机森林独特的优点。 但是,可以肯定,你通过增加max_features会降低算法的速度。 因此,你需要适当的平衡和选择最佳max_features。
Auto/None :简单地选取所有特征,每颗树都可以利用他们。这种情况下,每颗树都没有任何的限制。
sqrt :此选项是每颗子树可以利用总特征数的平方根个。 例如,如果变量(特征)的总数是100,所以每颗子树只能取其中的10个。“log2”是另一种相似类型的选项。
0.2:此选项允许每个随机森林的子树可以利用变量(特征)数的20%。如果想考察的特征x%的作用, 我们可以使用“0.X”的格式。

B. n_estimators:
在利用最大投票数或平均值来预测之前,你想要建立子树的数量。 较多的子树可以让模型有更好的性能,但同时让你的代码变慢。 你应该选择尽可能高的值,只要你的处理器能够承受的住,因为这使你的预测更好更稳定。

C. min_sample_leaf:减小复杂度(还有max_depth、min_sample_split)
如果您以前编写过一个决策树,你能体会到最小样本叶片大小的重要性。 叶是决策树的末端节点。 较小的叶子使模型更容易捕捉训练数据中的噪声。 一般来说,我更偏向于将最小叶子节点数目设置为大于50。在你自己的情况中,你应该尽量尝试多种叶子大小种类,以找到最优的那个。

使模型训练更容易的特征
A. n_jobs:
这个参数告诉引擎有多少处理器是它可以使用。 “-1”意味着没有限制,而“1”值意味着它只能使用一个处理器

B. random_state:
此参数让结果容易复现。 一个确定的随机值将会产生相同的结果,在参数和训练数据不变的情况下。 我曾亲自尝试过将不同的随机状态的最优参数模型集成,有时候这种方法比单独的随机状态更好。

C. oob_score
这是一个随机森林交叉验证方法。 它和留一验证方法非常相似,但这快很多。 这种方法只是简单的标记在每颗子树中用的观察数据。 然后对每一个观察样本找出一个最大投票得分,是由那些没有使用该观察样本进行训练的子树投票得到。

  • n_estimators

    data=load_breast_cancer().data
    target=load_breast_cancer().target
    
    
    test_score=[]
    for i in range(0,100,10):
        rfc=RandomForestClassifier(random_state=90,
                                   n_jobs=-1,
                                   n_estimators=i+10)
        score = cross_val_score(rfc, data, target, cv=10).mean()
        test_score.append(score)
    print(max(test_score),(test_score.index(max(test_score))*10)+1)
    plt.figure(figsize=(10,5))
    plt.plot(range(0,100,10),test_score)
    plt.show()
    
    #cv:测试折数
    

在这里插入图片描述

  • 在确定好的范围内,进一步细化学习曲线
    在这里插入图片描述

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

调整n_estimators的效果显著,模型的准确率立刻上升了0.005。接下来就进入网格搜索,我们将使用网格搜索对 参数一个个进行调整。为什么我们不同时调整多个参数呢?原因有两个:1)同时调整多个参数会运行非常缓慢, 在课堂上我们没有这么多的时间。2)同时调整多个参数,会让我们无法理解参数的组合是怎么得来的,所以即便网格搜索调出来的结果不好,我们也不知道从哪里去改。在这里,为了使用复杂度-泛化误差方法(方差-偏差方 法),我们对参数进行一个个地调整。

  • 为网格搜索做准备,书写网格搜索的参数
    注意:
    1、有一些参数是没有参照的,很难说清一个范围,这种情况下我们使用学习曲线,看趋势从曲线跑出的结果中选取一个更小的区间,再跑曲线
    param_grid = {‘n_estimators’:np.arange(0, 200, 10)}
    param_grid = {‘max_depth’:np.arange(1, 20, 1)}
    param_grid = {‘max_leaf_nodes’:np.arange(25,50,1)}
    2、对于大型数据集,可以尝试从1000来构建,先输入1000,每100个叶子一个区间,再逐渐缩小范围有一些参数是可以找到一个范围的,或者说我们知道他们的取值和随着他们的取值,模型的整体准确率会如何变化,这 样的参数我们就可以直接跑网格搜索
    param_grid = {‘criterion’:[‘gini’, ‘entropy’]}
    param_grid = {‘min_samples_split’:np.arange(2, 2+20, 1)}
    param_grid = {‘min_samples_leaf’:np.arange(1, 1+10, 1)}
    param_grid = {‘max_features’:np.arange(5,30,1)}

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

    param_grid = {'max_depth':np.arange(1, 10, 1)}
    rfc=RandomForestClassifier(random_state=90,
                               n_estimators=29)
    gs=GridSearchCV(rfc,param_grid,cv=10)
    gs.fit(data,target)
    print(gs.best_params_)
    print(gs.best_score_)
    

    参数:n_job表示进程将使用计算机上的所有内核

    {'max_depth': 7}
    0.9630931458699473
    

    在这里,我们注意到,将max_depth设置为有限之后,模型的准确率下降了。限制max_depth,是让模型变得简 单,把模型向左推,而模型整体的准确率下降了,即整体的泛化误差上升了,这说明模型现在位于图像左边,即泛 化误差最低点的左边(偏差为主导的一边)。通常来说,随机森林应该在泛化误差最低点的右边,树模型应该倾向 于过拟合,而不是拟合不足。这和数据集本身有关,但也有可能是我们调整的n_estimators对于数据集来说太大, 因此将模型拉到泛化误差最低点去了。然而,既然我们追求最低泛化误差,那我们就保留这个n_estimators,除非 有其他的因素,可以帮助我们达到更高的准确率。
    当模型位于图像左边时,我们需要的是增加模型复杂度(增加方差,减少偏差)的选项,因此max_depth应该尽量 大,min_samples_leaf和min_samples_split都应该尽量小。这几乎是在说明,除了max_features,我们没有任何 参数可以调整了,因为max_depth,min_samples_leaf和min_samples_split是剪枝参数,是减小复杂度的参数。 在这里,我们可以预言,我们已经非常接近模型的上限,模型很可能没有办法再进步了。
    那我们这就来调整一下max_features,看看模型如何变化。

  • 调整max_feature

    param_grid = {"max_features":np.arange(5,30,1)}
    rfc=RandomForestClassifier(random_state=90,
                               n_estimators=29,
                               max_depth=7)
    gs=GridSearchCV(rfc,param_grid,cv=10)
    gs.fit(data,target)
    print(gs.best_params_)
    print(gs.best_score_)
    
    {'max_features': 9}
    0.9701230228471002
    

max_features是唯一一个即能够将模型往左(低方差高偏差)推,也能够将模型往右(高方差低偏差)推的参数。我 们需要根据调参前,模型所在的位置(在泛化误差最低点的左边还是右边)来决定我们要将max_features往哪边调。 现在模型位于图像左侧,我们需要的是更高的复杂度,因此我们应该把max_features往更大的方向调整,可用的特征 越多,模型才会越复杂。max_features的默认最小值是sqrt(n_features),因此我们使用这个值作为调参范围的 最小值。
网格搜索返回了max_features的最小值,可见max_features升高之后,模型的准确率降低了。这说明,我们把模型往右推,模型的泛化误差增加了。前面用max_depth往左推,现在用max_features往右推,泛化误差都增加, 这说明模型本身已经处于泛化误差最低点,已经达到了模型的预测上限,没有参数可以左右的部分了。剩下的那些误差,是噪声决定的,已经没有方差和偏差的舞台了。如果是现实案例,我们到这一步其实就可以停下了,因为复杂度和泛化误差的关系已经告诉我们,模型不能再进步了。调参和训练模型都需要很长的时间,明知道模型不能进步了还继续调整,不是一个有效率的做法。如果我们希望模型更进一步,我们会选择更换算法,或者更换做数据预处理的方式。但是在课上,出于练习和探索的目的,我们继续调整我们的参数,让大家观察一下模型的变化,看看我们预测得是否正确。依然按照参数对模型整体准确率的影响程度进行调参。

  • min_samples_leaf

    #调整min_samples_leaf param_grid={'min_samples_leaf':np.arange(1, 1+10, 1)}
    #对于min_samples_split和min_samples_leaf,一般是从他们的最小值开始向上增加10或20 #面对高维度高样本量数据,如果不放心,也可以直接+50,对于大型数据,可能需要200~300的范围 #如果调整的时候发现准确率无论如何都上不来,那可以放心大胆调一个很大的数据,大力限制模型的复杂度
    rfc = RandomForestClassifier(n_estimators=39
                                 ,random_state=90
                                )
    GS = GridSearchCV(rfc,param_grid,cv=10)
    GS.fit(data.data,data.target)
    GS.best_params_
    GS.best_score_
    

可以看见,网格搜索返回了min_samples_leaf的最小值,并且模型整体的准确率还降低了,这和max_depth的情 况一致,参数把模型向左推,但是模型的泛化误差上升了。在这种情况下,我们显然是不要把这个参数设置起来 的,就让它默认就好了。

  • n_samples_split

    #调整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)
    GS.best_params_
    GS.best_score_
    

和min_samples_leaf一样的结果,返回最小值并且模型整体的准确率降低了。

  • 最后尝试一下criterion

    #调整Criterion
    param_grid = {'criterion':['gini', 'entropy']}
    rfc = RandomForestClassifier(n_estimators=39
                                 ,random_state=90
                                )
    GS = GridSearchCV(rfc,param_grid,cv=10)
    GS.fit(data.data,data.target)
    GS.best_params_
    GS.best_score_
    
  • 调整完毕,总结出模型的最佳参数

    rfc = RandomForestClassifier(n_estimators=39,random_state=90)
    score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
    score
    score - score_pre
    
  • 总结
    在整个调参过程之中,我们首先调整了n_estimators(无论如何都请先走这一步),然后调整max_depth,通过 max_depth产生的结果,来判断模型位于复杂度-泛化误差图像的哪一边,从而选择我们应该调整的参数和调参的 方向。如果感到困惑,也可以画很多学习曲线来观察参数会如何影响我们的准确率,选取学习曲线中单调的部分来 放大研究(如同我n_estimators做的)。学习曲线的拐点也许就是我们一直在追求的,最佳复杂度对应的泛化误差最低点(也是方差和偏差的平衡点)。
    网格搜索也可以一起调整多个参数,大家只要有时间,可以自己跑一下,看看网格搜索会给我们怎样的结果,有时候,它的结果比我们的好,有时候,我们手动调整的结果会比较好。当然了,我们的乳腺癌数据集非常完美,所以只需要调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
    )

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值