目录
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
可以结合之前使用过的数据集,来试试这一整套调参过程哟!
本期大功告成啦。