菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参

菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参

  • 菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参
    • 机器学习中调参的基本思想
      • 正确的调参思路
        • 泛化误差
        • 参数对泛化误差的影响
    • 实例:随机森林在乳腺癌数据上的调参
      • 随机森林调参第一步:无论如何先来调n_estimators
        • 学习曲线
      • 调max_depth
      • 调max_feature
      • 调min_samples_leaf
      • 调min_samples_split
      • 调criterion
      • 调整完毕,总结出模型的最佳参数

菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参

机器学习中调参的基本思想

高手的调参依赖于经验,这些经验来源于:
1)非常正确的调参思路和方法

2)对模型评估指标有深入理解

3)对数据的感觉和经验

4)洪荒之力

正确的调参思路

第一步是找目标:我们到底要优化什么

泛化误差

当模型在未知数据上表现糟糕时,我们说模型的泛化程度不够,泛化误差大。
菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参_第1张图片

通过上图我们发现模型的复杂度会影响泛化误差:

模型太简单和太复杂都会使得泛化误差变大分别是欠拟合和过拟合

树模型是天生的的复杂模型,对于树模型来说非常容易过拟合

同样的,对于以树模型作为基础的随机森林来讲,我们的调参目标就是减少模型的复杂度来降低泛化误差。

注意:
模型太复杂或者太简单,都会让泛化误差高,我们追求的是位于中间的平衡点

模型太复杂就会过拟合,模型太简单就会欠拟合

对树模型和树的集成模型来说,树的深度越深,枝叶越多,模型越复杂

树模型和树的集成模型的 目标,都是减少模型复杂度,把模型往图像的左边移动

参数对泛化误差的影响

影响力从高到低:
菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参_第2张图片

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

随机森林调参第一步:无论如何先来调n_estimators

学习曲线

"""
这里我们选择学习曲线,当然可以用网格搜索,但是只有学习曲线才能看清趋势

找到n_estimators取什么值得时候开始变得稳定

每间隔10个数运行一次,帮助我们划定范围
"""
score_list = []
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()
    score_list.append(score)
    
    
#print(max(score_list),(score_list.index(max(score))*10)+1)

plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),score_list)
plt.show()
print(max(score_list),(score_list.index(max(score_list))*10)+1)


"""
已经初步确定最高得分处在41左右

"""
score_list2 = []
for i in range(35,45):
    rfc = RandomForestClassifier(n_estimators=i
                                ,n_jobs=-1
                                ,random_state=90)
    score = cross_val_score(rfc,data.data,data.target,cv=10).mean()
    score_list2.append(score)

plt.figure(figsize=[20,5])
plt.plot(range(35,45),score_list2)
plt.show()

print(max(score_list2),score_list2.index(max(score_list2))+35)

0.9719568317345088 39
最后得到n_estimatos=39时候得到最大值

调max_depth

可以先用学习曲线划定范围,再进行网格搜索

这里直接进行网格搜索

param_grid = {'max_depth':np.arange(1,20,1)}
print(param_grid)
#一般根据数据的大小进行一个试探,乳腺癌数据很小,所以可以采用1到10,或者1到20这样试探
#但是对于像difit recognition这样的大型数据来说,我们应当尝试30到50层的深度(或许还不够)
#更应该画出学习曲线,来观察深度对模型的影响
rfc = RandomForestClassifier(n_estimators=39
                            ,random_state=90)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

#返回调整好的最佳参数对应的准确率
GS.best_score_``

#显示调整出来的最佳参数
GS.best_params_

得到最佳的max_depth

{‘max_depth’: 11}

调max_feature

可以先用学习曲线划定范围,再进行网格搜索

这里直接进行网格搜索

param_grid = {'max_feature':np.arange(5,30,1)}
"""
max_features是唯一一个既能将模型往左(低方差高偏差)推又能将模型往右(高方差低偏差)推的参数。
我们需要根据调参之前,模型所在的位置(泛化误差最低点左还是右)来决定我们要将max_feature推向哪里

这时位于图像左侧,我们需要更高的模型复杂度,需要把max_features调大

由于max_features的默认最小值是sqrt(n_features),因此我们是用这个值作为最小值

"""
rfc = RandomForestClassifier(n_estimators=39
                            ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)


GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_params_
GS.best_score_

调min_samples_leaf

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

rfc = RandomForestClassifier(n_estimators=39
                            ,random_state=90
                            )

GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_score_
GS.best_params_

调min_samples_split

param_grid = {'min_samples_split':np.arange(2,22,1)}

rfc = RandomForestClassifier(n_estimators=39
                            ,random_state=90
                            )

GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

GS.best_score_

GS.best_params_

调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_score_

GS.best_params_

调整完毕,总结出模型的最佳参数

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

#提升了多少
score-score_pre

你可能感兴趣的:(菜菜的机器学习sklearn实战-----从随机森林来看看机器学习调参)