机器学习(十三):超参数调优入门_枚举网格搜索

全文共8200余字,预计阅读时间约15~30分钟 | 满满干货,建议收藏!

在这里插入图片描述

一、简介

在机器学习中一个模型的表现往往受到它的参数设置影响

这就引出了一个问题,如何有效地找到一组最优的参数,以使模型表现达到最佳。这正是本文要探讨的主题:网格搜索(Grid Search)。

1.1 理解参数与超参数

影响机器学习建模结果的参数有两类,其一是参数,其二是超参数

参数的数值计算由一整套数学过程决定,在选定方法后,其计算过程基本不需要人工参与。因此经常说的模型调参,实际上是调整模型超参数。超参数种类繁多,而且无法通过一个严谨的数学流程给出最优解,因此需要人工参与进行调节。

以逻辑回归举例,其方程如下:

y = 1 1 + e − ( w T ⋅ x + b ) (1) y = \frac{1}{1 + e^{-(w^T \cdot x + b)}} \tag{1} y=1+e(wTx+b)1(1)

w w w 是一个向量,它包含了每个特征的权重,也就是模型的系数(coefficients)" 或 “权重”。 b b b 是一个常数,也就是模型的 “截距(intercept)” 或 “偏置项”。这些都是模型的参数,它们是在模型训练过程中通过数据学习得到的。

对于逻辑回归的超参数,借助Sklearn中的LogisticRegression来看一下:

image-20230706094909349

整理如下:

210

超参数是模型的一些配置选项,它们无法通过数据直接学习,而需要在开始训练模型前进行设定。如上图中的:

  • penalty:指定惩罚项的类型,如’l1’,‘l2’,‘elasticnet’,‘none’。决定正则化的类型
  • C:正则化强度的倒数,该值越小,模型的正则化强度就越大。正则化强度影响了模型复杂度,以及模型对训练数据的拟合程度。

在实践中,通常会尝试多组不同的超参数组合,然后选择表现最好的那一组作为模型的最终参数设置。这个过程叫做超参数调优或调参。手动进行这个过程往往很耗费时间和精力,尤其是当超参数的数量和可能的取值非常多时。为了更有效地进行调参,需要一种自动化的方法,这就是网格搜索的作用。

1.2 网格搜索解决的问题

网格搜索是一种自动化寻找最优超参数的方法。它会生成所有可能的参数组合,然后针对每一组参数训练模型并进行评估,最后选择表现最好的参数组合。

使用网格搜索,不再需要手动进行大量的尝试和调整。只需要提前设定好参数的取值范围和步长,网格搜索就会自动进行大量的尝试和评估,帮助找到最优的参数设置。

二、机器学习中的调参

2.1 手动调参与自动调参

调参就是去寻找一组最优参数, 以提高模型对未知数据的泛化能力,从而达到更好的预测或分类效果。合适的超参数可以使模型在偏差与方差之间达到良好的平衡,避免欠拟合和过拟合。

调参过程主要通过两种方式来进行:手动调参与自动调参

手动调参是指人工设定并调整超参数的过程,这种方式通常需要对问题和模型有深入理解,且过程耗时且效率低下,自动调参则是通过算法自动搜索最优超参数的过程,如网格搜索、随机搜索和贝叶斯优化等。

2.2 调参与模型过拟合、欠拟合的关系

模型的过拟合与欠拟合是由于模型复杂度与数据复杂度不匹配导致的。欠拟合是因为模型复杂度过低而无法捕捉到数据的复杂性,而过拟合是因为模型复杂度过高而学习到了数据中的噪声。调参就是为了找到一组使模型复杂度适合数据复杂性的超参数设定,从而避免过拟合和欠拟合。

2.3 交叉验证在调参中的定位

交叉验证是一种评估模型泛化性能的方法,它将数据集分为训练集和验证集,通过在训练集上训练模型,并在验证集上验证模型的性能。

在模型调参过程中,常常利用交叉验证来评估不同超参数设定下模型的性能,从而选择性能最好的超参数设定。

三、网格搜索过程

3.1 基本流程

机器学习的超参数众多,但能够对模型的建模结果产生决定性影响的超参数却不多

在大多数实践中,我们依赖于经验和实际需求来设定一部分超参数,如数据集的划分比例、交叉验证的折数等。然而,一些超参数,如正则化系数、特征衍生阶数等,需要进行更细致的调整。在这种情况下,通常采取的策略是搜索和枚举,也被称为网格搜索。

"搜索和枚举"意味着列出所有可能的参数选项,将多个不同参数的各种组合形成一个参数空间。在此参数空间内,尝试各种可能的参数组合,并用它们来训练模型。最终目标是找到一组使模型性能最优的超参数。

在这个过程中,有两个核心问题:一个是如何定义参数空间,另一个是如何选择能够反映模型泛化能力的评估指标

3.2 如何定义参数空间

构建网格搜索的参数空间实际上就是确定需要搜索的参数以及各个参数可能的取值范围。这个过程通常涉及到以下几个步骤:

  1. 确定需要搜索的参数:根据使用的模型和你的经验,确定哪些参数对模型的性能有重要影响。例如,在逻辑回归模型中,常见的需要调整的超参数包括正则化系数 C C C 和正则化类型 p e n a l t y penalty penalty
  2. 确定参数的取值范围:对于每一个需要搜索的参数,需要确定其可能的取值范围。取值范围可以是一个连续的区间,也可以是一个离散的集合。例如,正则化系数 C C C 的取值范围可以设定为 [ 0.001 , 0.01 , 0.1 , 1 , 10 , 100 ] [0.001, 0.01, 0.1, 1, 10, 100] [0.001,0.01,0.1,1,10,100]
  3. 生成参数网格:将每个参数的取值范围组合起来,生成参数网格。例如,如果 C C C 的取值范围是 [ 0.001 , 0.01 , 0.1 , 1 , 10 , 100 ] [0.001, 0.01, 0.1, 1, 10, 100] [0.001,0.01,0.1,1,10,100]penalty 的取值范围是 [ ′ l 1 ′ , ′ l 2 ′ ] ['l1', 'l2'] [l1,l2],那么参数网格就是这两个参数所有可能的组合。

比如:如果选择penalty参数和C来进行搜索调参,则这两个参数就是参数空间的不同维度,而这两个参数的不同取值就是这个参数空间中的一系列点,如(penalty=‘l1’, C=1)、(penalty=‘l1’, C=0.9)、(penalty=‘l2’, C=0.8)等等,就是这个参数空间内的一系列点,从中挑选组一个最优组合。

3.3 构建参数空间的思路

那需要带入哪些参数去构造这个参数空间呢?

调参的目的是为了提升模型的泛化能力,而保证泛化能力的核心是同时控制模型的经验风险和结构风险(既不让模型过拟合也不让模型前拟合),所以,调参的过程其实并不是很简单,依赖的是对于机器学习模型和数据的理解,有技巧,但技巧不多!

我仍然以逻辑回归举例:

思路:

在逻辑回归模型中,我们需要注意的主要参数包括特征衍生的相关参数和正则化的相关参数。

特征衍生的相关参数影响模型的复杂度和拟合程度。例如,多项式特征的阶数可以控制模型能拟合的复杂度。增大特征的阶数可以让模型有能力拟合更复杂的数据,但也可能导致过拟合。因此,在调参时,需要在欠拟合和过拟合之间寻找平衡,选择适当的特征衍生参数。

正则化的相关参数则是用来控制模型的过拟合倾向。逻辑回归中的正则化系数C和正则化类型penalty就是这种类型的参数。C值越小,模型的正则化程度越高,模型会更加简单,但可能会导致欠拟合;C值越大,模型的正则化程度越低,模型会更加复杂,但可能会导致过拟合。penalty可以选择L1或L2正则化,不同的正则化类型会影响模型的稀疏性和稳定性。

综上,在构造参数空间时,需要考虑到模型复杂度和防止过拟合这两方面的因素,并对特征衍生的相关参数和正则化的相关参数进行细致的调整,以寻找最优的模型配置。

3.4 评估指标的选择

常规的做法是在训练集中训练模型,然后计算训练误差和泛化误差,通过比较这两者来评估模型的过拟合或欠拟合程度(即模型的泛化能力),从而决定超参数的调整方式。

其实更严谨一点的做法是:需要将上述“通过对比训练误差和测试误差的差异,来判断过拟合还是欠拟合”的这个偏向主观的过程变成一个更加客观的过程,即我们需要找到一个能够基于目前模型建模结果的、能代表模型泛化能力的评估指标,这即是模型建模流程更加严谨的需要,同时也是让测试集回归其本来定位的需要。

通俗的理解上面这两段话:

在训练机器学习模型时,会有两个重要的误差指标,一是训练误差,即模型在训练数据上的误差;二是泛化误差,即模型在未知数据(通常是测试集或验证集)上的预测误差。训练误差反映了模型对训练数据的拟合程度,而泛化误差则反映了模型对未知数据的预测能力,也就是泛化能力。

在训练模型时,会试图通过调整模型的超参数来平衡训练误差和泛化误差,以防止模型过拟合或欠拟合。然而,通常不能直接观测到真实的泛化误差,只能通过测试集或验证集上的误差作为其估计。这就引入了一些主观因素,因为我们可能会基于测试集误差的大小和变化情况来判断模型的过拟合或欠拟合情况,从而决定如何调整超参数。这就是上文所说的“通过对比训练误差和测试误差的差异,来判断过拟合还是欠拟合”的过程。

但在一些更为严谨的情况下,我们不应只依赖这种主观的判断,而应该寻找一个更客观的评估指标,这个指标应该能够基于当前的模型训练结果,量化模型的泛化能力。这样,就可以基于这个指标,而不是仅仅依赖对训练误差和测试误差的主观判断,来调整超参数,使得模型建模的流程更加严谨。

而且,将测试集用于选择超参数可能会导致过度依赖测试集的结果,从而使测试集失去其原来的定位,即评估最终模型在未知数据上的性能。如果有了一个可以量化模型泛化能力的评估指标,就可以避免这个问题,使测试集回归其本来的定位。

因此,在超参数搜索过程中,选择一个恰当的评估指标是至关重要的。这个指标需要能够量化模型的预测性能,并可用于比较不同参数配置下模型的性能,从而指导我们找到最佳的超参数组合。

以下是一些常见的评估指标:

  1. 对于分类任务,常用的评估指标有精度(Accuracy)、查准率(Precision)、查全率(Recall)、F1分数(F1-score)、ROC曲线下的面积(AUC-ROC)等。
  2. 对于回归任务,常用的评估指标有均方误差(Mean Squared Error, MSE)、均方根误差(Root Mean Squared Error, RMSE)、平均绝对误差(Mean Absolute Error, MAE)、R平方等

  由于网格搜索本身就是一种优化过程,因此选取的评估指标最好是可以优化的,即最好有明确的最大化或最小化目标。例如,对于分类问题,精度、查准率、查全率、F1分数和AUC-ROC都是越大越好的指标,而对于回归问题,MSE、RMSE和MAE都是越小越好的指标。

3.5 为何需要交叉验证

交叉验证(Cross-validation)是一种用于评估机器学习模型预测性能的统计学方法,同时也是一种可用于超参数优化的方法。

其基本思想是将原始数据集划分成两部分,一部分用作训练集,另一部分用作验证集或测试集。最简单的形式是把数据集分为两部分,这被称为留出法(Holdout Method)。然而,为了减少因数据划分的随机性导致的估计偏差和方差,常常采用K折交叉验证(K-Fold Cross Validation)。

  • K折交叉验证:原始数据被随机划分为K个子集。然后对模型进行K次训练和验证,每次选取其中的一个子集作为测试集,剩下的K-1个子集作为训练集。然后将这K次验证的结果进行平均,作为模型的最终评估结果。

而为何要进行交叉验证,则主要原因是超参数的调整也需要同时兼顾模型的结构风险和经验风险,而能够表示模型结构风险的,就是不带入模型训练、但是能够对模型建模结果进行评估并且指导模型进行调整的验证集上的评估结果。

上述过程可以具体表示成如下步骤:

  • 在训练集中进行验证集划分(几折待定);
  • 带入训练集进行建模、带入验证集进行验证,并输出验证集上的模型评估指标;
  • 计算多组验证集上的评估指标的均值,作为该超参数下模型最终表现。

  因此,在大多数情况下,网格搜索(gridsearch)都是和交叉验证(CV)同时出现的,这也是为什么sklearn中执行网格搜索的类名称为GridSearchCV的原因。

四、实操:基于Scikit-Learn的网格搜索调参

4.1 官网说明

在sklearn的User Guide的3.2节中能看到关于网格搜索的相关内容。首先介绍官网给出的相关说明:

官网直达:Tuning the hyper-parameters of an estimator

image-20230706112618824

在Sklearn的官方文档中,定义了超参数(Hyper-parameters)是在模型训练过程中无法直接学习的参数,必须在建立模型时传入,这些超参数对模型的预测和计算性能有重大影响。

然后,还介绍了两种常用的参数搜索方法:网格搜索(GridSearchCV)和随机搜索(RandomizedSearchCV),其中网格搜索会对所有可能的参数组合进行穷举,而随机搜索则从参数空间中随机采样一定数量的参数进行搜索。这两种方法都有快速版本,即HalvingGridSearchCV和HalvingRandomSearchCV。

最终指出:一个完整的参数搜索包括:一个估计器(比如分类器或回归器)、一个参数空间、一个搜索或采样方法、一个交叉验证方案以及一个评分函数。

4.2 GridSearchCV的参数解释

官网直达:GridSearchCV

image-20230706113048462

在jupyter中导入看一下:

image-20230706113521836

详细解释如下:

212

整体来看,上面的主要参数分为三类,分别是核心参数、评估参数和性能参数。

  • 核心参数

性能参数,指的是涉及评估器训练(fit)的最核心参数:estimator参数和param_grid参数,同时也是实例化评估器过程中最重要的参数。

  • 评估参数

评估参数,指的是涉及到不同参数训练结果评估过程方式的参数,主要是scoring、refit和cv三个参数。这三个参数却是直接决定模型结果评估过程、并且对最终模型参数选择和模型泛化能力提升直观重要的三个参数。

  • 性能参数

性能参数,指的执行性能相关的参数,主要包括n_jobs和pre_dispatch参数两个,用于规定调用的核心数和一个任务按照何种方式进行并行运算。

4.3 使用LogisticRegression + GridSearchCV的基本流程

Step 1 : 加载数据,并划分训练集和测试集

from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=24,)

Step 2 :创建评估器

lr = LogisticRegression(max_iter=int(1e6), solver='saga')

Step 3: 构建搜索空间

参数空间字典的形式,字典的Key代表不同的参数,对应的Value则表示对应参数不同的取值范围,本实验使用的是LogicRegression模型,所以搜索空间要在LogicRegression模型的超参数中选择,可以这样查看某个模型的超参数:

image-20230707084547465

image-20230707084806183

params_grid = {'penalty': ['l1', 'l2'],
               'C':[1, 0.5, 0.1, 0.05, 0.01]
               }

但是注意一个问题:如果某个维度的参数取值对应一组新的参数,就需要创造多个参数空间(字典),然后将其封装在一个列表中,而该列表则表示多个参数空间的集成。

例如,对于逻辑回归来说,如果penalty参数中选择弹性网参数,则会衍生出一个新的参数l1_ratio,如果我们还想考虑penalty参数选取elasticnet参数,并且同时评估l1_ratio取不同值时模型效果,则无法将上述参数封装在一个参数空间内,因为当penalty取其他值时l1_ratio并不存在。image-20230707085350696

那就需要这样修改:

param_grid_en = [
    {'penalty': ['l1', 'l2'], 'C': [1, 0.5, 0.1, 0.05, 0.01]}, 
    {'penalty': ['elasticnet'], 'C': [1, 0.5, 0.1, 0.05, 0.01], 'l1_ratio': [0.3, 0.6, 0.9]}
]

这种情况很多,所以后续建模的时候要清楚该如何修改参数空间

Step 4:实例化网格搜索器

grid_search = GridSearchCV(estimator=lr,
                          param_grid=param_grid_en)

Step 5: 训练

通过fit方法完成评估器的训练,训练网格搜索评估器的过程本质上是在挑选不同的参数组合进行逻辑回归模型训练,训练完成后相关结果都保存在grid_search对象的属性中。

grid_search.fit(X_train, y_train)

image-20230707090031092
Step 6:模型评估

213

可以这样打印看一下:

# 打印交叉验证过程中的重要结果
print("cv_results_: ", grid_search.cv_results_)

# 打印最终挑选出的最优估计器
print("best_estimator_: ", grid_search.best_estimator_)

# 打印最优参数情况下,训练集的交叉验证的平均得分
print("best_score_: ", grid_search.best_score_)

# 打印最优参数组合
print("best_params_: ", grid_search.best_params_)

# 打印CV过程会对所有参数组合标号,该参数表示最优参数组合的标号
print("best_index_: ", grid_search.best_index_)

# 打印在最优参数下,计算模型得分的方法
print("scorer: ", grid_search.scorer_)

# 打印交叉验证的折数
print("n_splits_: ", grid_search.n_splits_)

image-20230707091240407

上述过程就是就是一个简单,但完整的网格搜索的调参过程。

五、结语

在这篇文章中,论述了机器学习中的超参数调优问题,特别是如何运用网格搜索和交叉验证来寻找最优的模型参数。通过阅读此文,你应该掌握了手动与自动调参的差异,调参与模型过拟合和欠拟合的关系,如何定义和构建参数空间,以及如何使用Scikit-Learn进行网格搜索。这些知识将帮助你更有效地优化机器学习模型的性能和泛化能力。

然而,对于复杂的参数空间,传统的网格搜索可能并不总是最高效的解决方案。因此,在接下来的两篇文章中,更深入地探索网格搜索的优化。首先,将介绍随机网格搜索(RandomizedSearchCV)和对半网格搜索(HalvingSearchCV)的工作原理以及在何种情况下应用这两种方法能够带来更高的效率。然后,在第三篇文章中,将介绍一种更先进的参数优化方法:贝叶斯优化。这种方法通过考虑先前评估的参数来指导参数空间的搜索,往往能够在更少的试验次数内找到优质的参数组合。

最后,感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!

期待与您在未来的学习中共同成长。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
XGBoost是一种用于机器学习的强大算法,它可以在分类和回归任务中获得很好的性能。但是,为了达到最佳性能,需要对其参数进行整。 以下是XGBoost中需要整的一些重要参数: 1. n_estimators:决定树的数量,也就是模型中的基本学习者数量。 2. max_depth:树的最大深度,过高的深度可能导致过度拟合。 3. learning_rate:控制每个基本学习器的权重更新步长。 4. subsample:每次训练模型时用于构建树的样本比例。 5. colsample_bytree:每次训练模型时用于构建树的特征比例。 6. gamma:控制当树分裂时,节点的最小损失减少量。 7. reg_alpha:L1正则化参数,用于控制模型的复杂度。 8. reg_lambda:L2正则化参数,用于控制模型的复杂度。 下面是一个简单的XGBoost参数示例: ```python import xgboost as xgb from sklearn.datasets import load_digits from sklearn.model_selection import GridSearchCV # 加载数据集 digits = load_digits() X, y = digits.data, digits.target # 定义参数范围 param_grid = {'n_estimators': [50, 100, 150], 'max_depth': [2, 3, 4], 'learning_rate': [0.01, 0.1, 0.5], 'subsample': [0.6, 0.8, 1.0], 'colsample_bytree': [0.6, 0.8, 1.0], 'gamma': [0, 0.1, 0.2], 'reg_alpha': [0, 0.1, 1], 'reg_lambda': [0, 0.1, 1]} # 定义分类器 xgb_model = xgb.XGBClassifier(objective='multi:softmax', num_class=10) # 定义网格搜索 grid_search = GridSearchCV(estimator=xgb_model, param_grid=param_grid, cv=5, n_jobs=-1) # 进行参数 grid_search.fit(X, y) # 输出最佳参数 print("Best parameters found: ", grid_search.best_params_) ``` 在上面的代码中,我们使用了网格搜索来寻找最佳参数。我们定义了一个参数范围字典,包含了所有需要整的参数及其可能的值。然后,我们定义了一个XGBoost分类器,并将其作为估计器传递给网格搜索。最后,我们用fit()方法来运行网格搜索,找到最佳参数组合。 总的来说,XGBoost是一种非常强大的机器学习算法,但是需要整一些重要的参数才能实现最佳性能。通过整这些参数,可以使XGBoost在分类和回归任务中获得更好的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小陈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值