超参数优化器 - GridSearchCV(网格搜索)

为了在数据集上训练不同的模型并且选择性能最佳的模型,有时候虽然仍有改进的余地,因为我们不会肯定地说这个特定模型最合适解决手头的问题。因此,我们的目标是以任何可能的方式改进模型,影响这些模型性能的一个重要因素是它们的超参数,一旦我们为这些超参数找到合适的值,模型的性能就会显著提高。在本文中,将了解学习如何使用GridSearchCV找到模型超参数的最佳值。

1.什么是GridSerchCV?

​ 首先,让我们了解一下什么是GridSerchCV(网格搜索)?它是执行超参数调整以确定给模型的最佳值的过程。模型的性能很大程度上却决于超参数的值。但需注意的是,我们没有办法提前知道超参数的最佳值,一般有两个方法,一种并经验去调参,另一种是比较常见的情况,就是需要我们尝试所有可能的值来知道最佳值。

​ GridSearchCV 是 Scikit-learn(或sklearn)model_selection包中的一个函数。所以这里我们需要事先在自己计算机上安装Scikit-learn库。此函数有助于遍历预定义的超参数并使你的模型适合你的训练集,所以在最后我们可以从列出的超参数中选择最好的参数。

2.GridSerchCV是如何工作?

下面我将超参数的预定义值传递给GridSearchCV函数。

通过定义一个字典赋值给param_grid变量来实现这一点,在字典中提到了一个特定的超参数以及它可以选取的值。如下例子:

param_grid = {'C': [0.1, 1, 10, 100, 1000],  
   			  'gamma': [1, 0.1, 0.01, 0.001, 0.0001], 
   			  'kernel': ['rbf',’linear’,'sigmoid']}

这里的C、gamma和Kernels是SVM模型的一些超参数,除了上面列出的超参数,其余未列出的超参数将设置为其默认值。

GridSearchCV 尝试字典中传递的值的所有组合,并使用交叉验证方法评估每个组合的模型。因此,在使用此函数后,我们可以获得每种超参数组合的准确率/损失,我们可以选择性能最佳的组合。

3.如何使用GridSerchCV?

首先,看看GridSearchCV 函数的各种参数是什么:

sklearn.model_selection.GridSearchCV(estimator, param_grid,scoring=None,n_jobs=None, iid='deprecated', refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False) 

简要描述其中的一些参数,也可以自行到官网文档中找到这些参数:

1.estimator:传递要检查超参数的模型实例。
2.params_grid:保存要尝试的超参数的字典对象
3.scoring:要使用的评估指标,简单地传递有效的字符串/评估指标对象
4.cv:拥有的交叉验证数尝试每个选定的超参数集
5.verbose:可以将其设置为 1 以在将数据适合 GridSearchCV 时获得详细的打印输出
6.n_jobs:希望为此任务并行运行的进程数,如果它等于-1,它将使用所有可用的处理器。

现在,看看如何使用GriGdSearchCV 来提高我们模型的准确性。在下面的例子,我将训练模型两次,第一次不使用GridSearchCV ,第二次将使用GridSearchCV 为例子中的数据集找到超参数的最佳值。

在这个例子中使用威斯康星州乳腺癌(诊断)数据集,直接从Scikit-learn库导入。

  • 不使用GridSearchCV的例子:
# 导入本文三个例子所需要到的相关库包
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,mean_squared_error
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV

# 加载数据集并将其拆分为训练集和测试集
dataset = load_breast_cancer()
X = dataset.data
Y = dataset.target
X_train, X_test, y_train, y_test = train_test_split(
                                X,Y,test_size = 0.30, random_state = 101)
# 不使用GridSearchCV在上训练模型
model = SVC()
model.fit(X_train, y_train)

# 训练结果
y_pred = model.predict(X_test)

# 使用分类指标classification_report - 构建显示主要分类指标的文本报告
report = classification_report(y_test, y_pred)
print(report)
####################################### 输出结果如下:####################################### 
"""
              precision    recall  f1-score   support

           0       0.95      0.85      0.90        66
           1       0.91      0.97      0.94       105

    accuracy                           0.92       171
   macro avg       0.93      0.91      0.92       171
weighted avg       0.93      0.92      0.92       171
"""
# 输出结果详解:其中列名 每个标签类的精度、召回率、F1值、样本量
# F1分数,是统计学中用来衡量二分类模型精确度的一种指标。F1分数可以看作是模型精确率和召回率的一种调和平均,它的最大值是1,最小值是0。
# accuracy表示准确率,也即正确预测样本量与总样本量的比值
# marco avg表示宏平均,表示所有类别对应指标的平均值
# weighted avg表示带权重平均,表示类别样本占总样本的比重与对应指标的乘积的累加和
  • 使用GridSearchCV的例子(SVM)
# 定义参数范围
param_grid = {
    'C': [0.1, 1, 10, 100], # 正则化参数
    'gamma': ['scale', 'auto'],  # 核系数
    'kernel': ['linear'],  #内核函数(线性核'linear'、多项式核'poly'、高斯核'rbf'、核函数'sigmoid')
}
# 拟合网格搜索模型
grid.fit(X_train, y_train)
# 打印调整后的最佳参数
print(grid.best_params_)
grid_y_pred = grid.predict(X_test)
# 打印报告
print(classification_report(y_test, grid_y_pred))
####################################### 输出结果如下:####################################### 
"""
Fitting 5 folds for each of 8 candidates, totalling 40 fits
[CV 2/5] END ..............C=0.1, gamma=scale, kernel=linear; total time=   0.0s
[CV 1/5] END ..............C=0.1, gamma=scale, kernel=linear; total time=   0.0s
...
[CV 4/5] END ...............C=100, gamma=auto, kernel=linear; total time=  13.0s
{'C': 100, 'gamma': 'scale', 'kernel': 'linear'}
              precision    recall  f1-score   support

           0       0.97      0.91      0.94        66
           1       0.94      0.98      0.96       105

    accuracy                           0.95       171
   macro avg       0.96      0.95      0.95       171
weighted avg       0.95      0.95      0.95       171
"""
  • 使用GridSearchCV的例子(随机森林分类器RandomForestClassifier)
param_grid = {
    'max_depth': range(1, 10), # 树的最大深度
    'n_estimators': range(1,200,10), # 森林中的树木数量
}
grid = GridSearchCV(RandomForestClassifier(),
                    param_grid,
                    refit=True, # 当refit=True估计器是分类器时才可用
                    n_jobs=-1,  # n_jobs = -1 使用所有处理器
                    verbose=3,  # 详细程度,3最高,显示消息最多
                    )
# 拟合网格搜索模型
grid.fit(X_train, y_train)
#
# 打印调整后的最佳参数
print(grid.best_params_)
grid_y_pred = grid.predict(X_test)
#
# # 打印报告
print(classification_report(y_test, grid_y_pred))
####################################### 输出结果如下:####################################### 
"""
Fitting 5 folds for each of 180 candidates, totalling 900 fits
[CV 2/5] END ....................max_depth=1, n_estimators=1; total time=   0.0s
...
[CV 5/5] END ..................max_depth=9, n_estimators=191; total time=   0.3s
{'max_depth': 6, 'n_estimators': 181}
              precision    recall  f1-score   support

           0       0.94      0.94      0.94        66
           1       0.96      0.96      0.96       105

    accuracy                           0.95       171
   macro avg       0.95      0.95      0.95       171
weighted avg       0.95      0.95      0.95       171
"""

看完输出结果,可能就会认为{'C': 100, 'gamma': 'scale', 'kernel': 'linear'}SVM模型超参数的最佳值,事实上,这些超参数可能是我们正在处理的数据集的最佳值。但是对于不同的数据集,SVMRandomForestClassifier模型可以有不同的超参数使其最优。

总结

经过本文这么一边实践一边总结,从学习如何使用到深入了解如何找到模型的最佳超参数,从而使得模型获得更好的性能。


出处:

https://www.mygreatlearning.com/blog/gridsearchcv/#sh2

上一篇:剑指 Offer 47. 礼物的最大价值


下一篇:LeetCode.最小路径和(动态规划,状态压缩)