机器学习-随机森林-调参的案例

一、随机森林-实例:随机森林在乳腺癌数据上的调参
1.1首先先了解一下调参的基本思想:
机器学习-随机森林-调参的案例
机器学习-随机森林-调参的案例

机器学习-随机森林-调参的案例
机器学习-随机森林-调参的案例
机器学习-随机森林-调参的案例
机器学习-随机森林-调参的案例
机器学习-随机森林-调参的案例
二、下面开始正是调参实例
2.1.导入相关库

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

2.2导入数据集,探索数据

data = load_breast_cancer()
data
data.data.shape
data.target
#可以看到,乳腺癌数据集有569条记录,30个特征,单看维度虽然不算太高,但是样本量非常少过拟合的情况可能存在

2.3.进行一次简单的建模

rfc = RandomForestClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,data.data,data.target,cv=10).mean()
score_pre
#这里可以看到,随机森林在乳腺癌数据上的表现本就还不错,在现实数据集上,基本上不可能什么都不调就看到95%以上的准确率

结果:0.96669259355284753
2.4. 随机森林调整的第一步:无论如何先来调n_estimators

"""
在这里我们选择学习曲线,可以使用网格搜索吗?可以,但是只有学习曲线,才能看见趋势
我个人的倾向是,要看见n_estimators在什么取值开始变得平稳,是否一直推动模型整体准确率的上升等信息
第一次的学习曲线,可以先用来帮助我们划定范围,我们取每十个数作为一个阶段,来观察n_estimators的变化如何
引起模型整体准确率的变化
"""
#####【TIME WARNING: 30 seconds】#####
scorel = []
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()
    scorel.append(score)
print(max(scorel),(scorel.index(max(scorel))*10)+1)#这里加1的原因在于n_estimators加了1的
plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scorel)
plt.show()
#list.index([object])
#返回这个object在列表list中的索引

这里主要是确定一个范围,然后再在一个范围内进行调参
2.5,、再进一步画学习曲线

scorel = []
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()
    scorel.append(score)
print(max(scorel),([*range(35,45)][scorel.index(max(scorel))]))
plt.figure(figsize=[20,5])
plt.plot(range(35,45),scorel)
plt.show()

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

"""
有一些参数是没有参照的,很难说清一个范围,这种情况下我们使用学习曲线,看趋势
从曲线跑出的结果中选取一个更小的区间,再跑曲线

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)}

 对于大型数据集,可以尝试从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)}
"""

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

#调整max_depth
param_grid = {'max_depth':np.arange(1, 20, 1)}
# 一般根据数据的大小来进行一个试探,乳腺癌数据很小,所以可以采用1~10,或者1~20这样的试探
# 但对于像digit 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_params_
GS.best_score_

机器学习-随机森林-调参的案例
2.8. 调整max_features

#调整max_features
param_grid = {'max_features':np.arange(5,30,1)}
"""
max_features是唯一一个即能够将模型往左(低方差高偏差)推,也能够将模型往右(高方差低偏差)推的参数。我
们需要根据调参前,模型所在的位置(在泛化误差最低点的左边还是右边)来决定我们要将max_features往哪边调。
现在模型位于图像左侧,我们需要的是更高的复杂度,因此我们应该把max_features往更大的方向调整,可用的特征
越多,模型才会越复杂。max_features的默认最小值是sqrt(n_features),因此我们使用这个值作为调参范围的
最小值。
"""
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_

机器学习-随机森林-调参的案例
2.9. 调整min_samples_leaf
2.10. 不懈努力,继续尝试min_samples_split
2.1111. 最后尝试一下criterion
方法是一样的这里不再一一详细说明了,此案例说明经过第一步的参数调整已经达到最佳复杂度了,不过一般情况为了更加准确可以多调介个参数俺看否会有score上升的情况。