ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-02-27 18:59:30  阅读:275  来源: 互联网

标签:调参 模型 param score grid 随机 max best 森林


n_estimators :
森林中树木的数量,即基评估器(学习器)的数量
默认是100,n_estimators变大,模型更复杂, n_estimators变大,模型更简单;不影响单个模型的复杂度 

max_depth :
树的最大深度,超过最大深度的树枝都会被剪掉
默认最大深度,即最高复杂度,如果减小max_depth,就 
会向复杂度降低的方向调整,向图像的左边移动 

min_samples_leaf :
一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生
默认最小限制1,即最高复杂度。min_samples_leaf↑,降 低模型复杂度,向图像的左边移动

min_samples_split : 
一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝, 否则分枝就不会发生
默认最小限制2,即最高复杂度。min_samples_split↑,降 低模型复杂度,向图像的左边移动

max_features : 
max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,默认 值为总特征个数开平方取整
默认是特征总数的开平方,位于中间复杂度。 既可以向复杂度升高的方向,也可以向复杂度降低的方向调参。 max_features↓,模型更简单;图像左移; max_features↑,模型更复杂,图像右移max_features。 是唯一的既能够让模型更简单,也能够让模型更复杂的参数,所以在 调整这个参数的时候,需要考虑我们调参的方向

criterion  :
不纯度的衡量指标,有基尼系数和信息熵两种选择
一般使用gini

模型的复杂度与泛化误差的关系

泛化误差:来衡量模型在未知数据上的准确率的指标,叫做泛化误差 当模型在未知数据(测试集)
上表现糟糕时,我们说模型的泛化程度不够,泛化误差大,模型的效果不好。泛化误 差受到模型的结构(复杂度)影响。
看下面这张图,它准确地描绘了泛化误差与模型复杂度的关系,当模型太复杂,模型就会过拟合,泛化能力就不够,所以泛化误差大。
当模型太简单,模型就会欠拟合,拟合能力就不够,所 以误差也会大。只有当模型的复杂度刚刚好的才能够达到泛化误差最小的目标,我们追求的就是位于中间的平衡点。
1)对于随机森林而言,树的深度越深,枝叶越多,模型越复杂 
2)随机森林这样的树模型的目标,是减少模型复杂度,把模型往图像的左边移动

在这里插入图片描述

实例:随机森林在乳腺癌数据上的调参
1)导入基本的库和数据集

#导入相应的库

from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
#数据导入
data = load_breast_cancer()
X = data.data
y = data.target

2)什么参数也不调整,简单建模

#什么参数也不调整,简单建模,建立base line model
rfc = RandomForestClassifier(random_state=90)  #基线模型base_line model
base_score = cross_val_score(rfc, X, y, cv=10).mean()

base_score   # 0.9648809523809524

3)使用网格搜索对参数一个一个进行调试

# 使用网格搜索对参数一个一个进行调试
'''
1. 有一些参数是没有参照的,很难说清一个范围,这种情况下我们粗调,看趋势,再细调 
比如: 
param_grid = {'n_estimators':np.arange(0, 200, 10)} 
param_grid = {'max_depth':np.arange(1, 100, 10)} 
2. 有一些参数是可以找到一个范围的,或者说我们知道他们的取值和随着他们的取值,模型的整体准确率会如何变化, 
这样的参数我们就可以直接跑网格搜索 :
param_grid = {'min_samples_split':np.arange(2, 22, 1)} 
param_grid = {'min_samples_leaf':np.arange(1, 11, 1)} 
param_grid = {'max_features':np.arange(5,30,1)} 
param_grid = {'criterion':['gini', 'entropy']}
'''

4)先调n_estimators

# 先粗调n_estimators
scorel = []
param_grid = {'n_estimators':np.arange(1, 200, 10)}

rfc = RandomForestClassifier(n_jobs=-1,
                            random_state=90
                            )

gridsearch0 = GridSearchCV(rfc, param_grid=param_grid, cv=10)
gridsearch0.fit(X, y)
gridsearch0.best_score_, gridsearch0.best_params_  # (0.9631265664160402, {'n_estimators': 71})

best_score = gridsearch0.best_score_
#细调n_estimators

scorel = []
param_grid = {'n_estimators':np.arange(60, 80,1)}

rfc = RandomForestClassifier(n_jobs=-1,
                            random_state=90
                            )
gridsearch1 = GridSearchCV(rfc, param_grid=param_grid, cv=10)
gridsearch1.fit(X, y)

gridsearch1.best_score_, gridsearch1.best_params_, best_score # (0.9666353383458647, {'n_estimators': 73}, 0.9631265664160402)
best_score = gridsearch1.best_score_

5)调整max_depth

#调整max_depth
score1 = []
for i in range(1, 20, 1):
    rfc = RandomForestClassifier(
                          n_estimators=73,
                           n_jobs=-1,
                            random_state=90,
                            max_depth= i
                            )
    score = cross_val_score(rfc, X, y, cv = 10).mean()
    score1.append(score)
    
print(max(score1), score1.index(max(score1))+1) # 0.9666353383458647 8
print(best_score) # 0.9666353383458647
# 这次max_depth调整时没有提高精度的
在这里,我们注意到,设置max_depth之后,模型的准确率并未改变,这说明: 
1)剪枝之前的树深depth=8; 
2)限制max_depth<8,表示对模型进行了剪枝,一旦剪枝,就只会使得模型的准确度降低; 
3)说明模型目前处于欠拟合的状态。位于上述图像的左边; 
通常来说,随机森林应该在泛化误差最低点的右边,树模型应该倾向于过拟合,而不是拟合不足。
但也有可能是我们调整的n_estimators对于数据集来说太大,因此将模型拉到泛化误差最低点去了。 
当模型位于图像左边时,我们需要的是增加模型复杂度的选项,因此max_depth应该尽量大,min_samples_leaf和min_samples_split都应该尽量小。
这几乎是在说明,除了max_features,我们没有任何参数可以调整了,因为max_depth,min_samples_leaf和min_samples_split是剪枝参数,是减小复杂度的参数。 

6)试试调整min_samples_leaf有没有用,理论上说是无效的

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

gridsearch3 = GridSearchCV(rfc, param_grid=param_grid, cv=10)
gridsearch3.fit(X, y)
gridsearch3.best_score_, gridsearch3.best_params_, best_score
# (0.9666353383458647, {'min_samples_leaf': 1}, 0.9666353383458647)
# 验证确实是无效的

7)调整max_features

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

rfc = RandomForestClassifier(n_estimators=73,
                                 n_jobs=-1,
                                 random_state=90,
                                )

gridsearch4 = GridSearchCV(rfc, param_grid=param_grid, cv=10)
gridsearch4.fit(X, y)

gridsearch4.best_score_, gridsearch4.best_params_, best_score
# (0.9666666666666668, {'max_features': 24}, 0.9666353383458647)
best_score = gridsearch4.best_score_

8)最后调整Criterion

param_grid = {'criterion':['gini', 'entropy']}
rfc = RandomForestClassifier(n_estimators=73,
                                 n_jobs=-1,
                                 random_state= 90,
                                 max_features = 24
                                )

gridsearch5 = GridSearchCV(rfc, param_grid=param_grid, cv=10)
gridsearch5.fit(X, y)

gridsearch5.best_score_, gridsearch5.best_params_, best_score
# (0.9666666666666668, {'criterion': 'gini'}, 0.9666666666666668)

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

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

10)与基线模型进行比对

base_score, score
# (0.9648809523809524, 0.9666666666666668)

标签:调参,模型,param,score,grid,随机,max,best,森林
来源: https://blog.csdn.net/Amanda_python/article/details/114178784

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有