目录

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

泛化误差

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

1. 导入需要的库

2. 导入数据集,探索数据

3. 进行一次简单的建模,看看模型本身在数据集上的效果

4. 随机森林调整第一步:先调n_estimators

5. 在确定好的范围内,进一步细化学习曲线

6. 为网格搜索做准备,书写网格搜索的参数

7. 按照参数对准确率的影响程度进行调参,首先调max_depth

8. 调整max_features

9. 调整min_samples_leaf

10. 调整min_samples_split

11. 调整criterion

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


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

调参思路:

第一步找准目标

对于随机森林,我们想要提升模型在未知数据上的准确率;

而机器学习中,衡量模型在位置数据上的准确率的指标,叫做泛化误差(Genelization error)

泛化误差

泛化误差受到模型的结构(复杂度)影响;

模型过于复杂,容易过拟合,泛化能力不够,泛化误差大;

模型太简单,容易欠拟合,拟合程度不够,泛化误差也会大;

模型的复杂度参数有什么关系呢:

对于树模型来说,树越多,深度越深,枝叶越多,模型越复杂;

随机森林是天生复杂度高的模型;

随机森林调参,都向着减少模型复杂度的目标;

参数

对模型在未知数据上的评估性能的影响

影响程度

n_estimators

将准确率提升至平稳,它上升不影响单个模型的复杂度

⭐⭐⭐⭐⭐

max_depth

默认最大深度,即最高复杂度,下降模型更简单

⭐⭐

min_samples_leaf

默认最小限制1,即最高复杂度,上升模型更简单

⭐⭐

min_samples_split

默认最小限制2,即最高复杂度,上升模型更简单

⭐⭐

max_features

默认auto,是特征总数的开平方,下降模型更简单,上升模型更复杂;

它是唯一既能让模型更简单也能让模型更复杂的参数


criterion

一般使用gini

看具体情况

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

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. 导入数据集,探索数据

data = load_breast_cancer()
data
data.data.shape
data.target

3. 进行一次简单的建模,看看模型本身在数据集上的效果

rfc = RandomForestClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,data.data
                            ,data.target,cv=10
                            ,scoring='accuracy').mean()
score_pre

4. 随机森林调整第一步:先调n_estimators

通过学习曲线,看n_estimators在什么取值变得平稳,帮助我们划定范围;

我们取每十个数作为一个阶段,来观察n_estimators的变化如何引起模型整体准确率的变化

scorel=[]
for i in range(1,201,10):
    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)

# list.index([object]) 返回这个object在列表list中的索引
# 意思是打印出最大交叉验证分数对应的n_estimators的取值
print(max(scorel),(scorel.index(max(scorel))*10))

plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scorel)
plt.show()

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)

# list.index([object]) 返回这个object在列表list中的索引
# 意思是打印出最大交叉验证分数对应的n_estimators的取值
# *解压,相当于把35-45中间的每个数都写出来
print(max(scorel),([*range(35,45)][scorel.index(max(scorel))]))

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

6. 为网格搜索做准备,书写网格搜索的参数

适合先用学习曲线来调的参数:

n_estimators;max_depth;max_leaf_nodes

直接有范围,适合用网格搜索来调的参数:

criterion;min_samples_split;min_samples_leaf;max_features

7. 按照参数对准确率的影响程度进行调参,首先调max_depth

param_grid={'max_depth':np.arange(1,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_

8. 调整max_features

param_grid={'max_features':np.arange(5,30,1)}

# max_features既能让模型往左(低方差高偏差),也能往右(高方差低偏差)
# 看一下前两步的分数变化如何,像我是从0.963->0.966效果变好
# 因此max_features可以适当提升复杂度,不行再回调
rfc = RandomForestClassifier(n_estimators=73,random_state=90)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

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

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

9. 调整min_samples_leaf

param_grid={'min_samples_leaf':np.arange(1,1+10,1)}
# min_samples_leaf & min_samples_split,一般是从最小值开始向上增加10或20
rfc = RandomForestClassifier(n_estimators=73,random_state=90)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

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

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

10. 调整min_samples_split

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

rfc = RandomForestClassifier(n_estimators=73,random_state=90)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

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

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

11. 调整criterion

param_grid={'criterion':['gini','entropy']}

rfc = RandomForestClassifier(n_estimators=73,random_state=90)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)

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

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

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

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

# 看看调前后的差别
score-score_pre


我的差别:0.0017857142857143904


可以结合之前使用过的数据集,来试试这一整套调参过程哟!

本期大功告成啦。