使用随机搜索和网格搜索进行超参数优化

机器学习模型具有必须设置的超参数,以便将模型定制到您的数据集。

通常,超参数对模型的一般影响是已知的,但如何为给定数据集最佳地设置超参数以及相互作用的超参数组合是一个挑战。通常有配置超参数的一般启发式或经验法则。

一个更好的方法是客观地搜索模型超参数的不同值,并选择一个子集,使其结果是模型在给定数据集上取得最佳性能。这称为**超参数优化**或超参数调优,并且在 scikit-learn Python 机器学习库中可用。超参数优化的结果是一组表现良好的超参数,您可以使用它们来配置您的模型。

在本教程中,您将发现 Python 中机器学习的超参数优化。

完成本教程后,您将了解:

  • 超参数优化对于充分利用机器学习模型至关重要。
  • 如何配置用于分类任务的随机搜索和网格搜索超参数优化。
  • 如何配置用于回归任务的随机搜索和网格搜索超参数优化。

让我们开始吧。

Hyperparameter Optimization With Random Search and Grid Search

使用随机搜索和网格搜索进行超参数优化
照片由 James St. John 提供,部分权利保留。

教程概述

本教程分为五个部分;它们是:

  1. 模型超参数优化
  2. 超参数优化 Scikit-Learn API
  3. 分类超参数优化
    1. 分类随机搜索
    2. 分类网格搜索
  4. 回归超参数优化
    1. 回归随机搜索
    2. 回归网格搜索
  5. 关于超参数优化的一些常见问题

模型超参数优化

机器学习模型具有超参数。

超参数是选择或配置点,允许机器学习模型针对特定任务或数据集进行自定义。

  • 超参数:由开发人员指定的模型配置参数,用于指导特定数据集的学习过程。

机器学习模型也有参数,这些参数是通过在训练数据集上训练或优化模型来设置的内部系数。

参数与超参数不同。参数是自动学习的;超参数是手动设置的,以帮助指导学习过程。

有关参数和超参数之间区别的更多信息,请参阅教程

通常,超参数对模型具有普遍已知的影响,但对于给定数据集如何最佳设置超参数尚不清楚。此外,许多机器学习模型具有一系列超参数,它们可能以非线性方式相互作用。

因此,通常需要搜索一组超参数,这些超参数能使模型在数据集上获得最佳性能。这称为超参数优化、超参数调优或超参数搜索。

优化过程涉及定义搜索空间。可以将其视为一个 n 维体积,其中每个超参数代表一个不同的维度,维度的尺度是超参数可能取的值,例如实值、整数值或类别值。

  • 搜索空间:要搜索的体积,其中每个维度代表一个超参数,每个点代表一个模型配置。

搜索空间中的一个点是每个超参数值具有特定值的向量。优化过程的目标是找到一个向量,该向量在学习后能使模型的性能达到最佳,例如最大准确率或最小错误。

可以使用一系列不同的优化算法,尽管最简单也是最常用的两种方法是随机搜索和网格搜索。

  • 随机搜索。将搜索空间定义为超参数值的有界域,并在此域中随机采样点。
  • 网格搜索。将搜索空间定义为超参数值的网格,并评估网格中的每个位置。

网格搜索非常适合抽查通常已知性能良好的组合。随机搜索非常适合发现和获取您凭直觉猜不到的超参数组合,尽管它通常需要更多的时间来执行。

有时会使用更高级的方法,例如贝叶斯优化和进化优化。

现在我们对超参数优化有了了解,让我们看看如何在 Python 中使用这种方法。

超参数优化 Scikit-Learn API

scikit-learn Python 开源机器学习库提供了用于调整模型超参数的技术。

具体来说,它提供了用于随机搜索的 RandomizedSearchCV 和用于网格搜索的 GridSearchCV。这两种技术都使用交叉验证来评估给定超参数向量的模型,因此每个类的名称都有“CV”后缀。

这两个类都需要两个参数。第一个是要优化的模型。这是模型的一个实例,其中包含要优化的超参数值。第二个是搜索空间。它被定义为一个字典,其中名称是模型超参数的参数,值是离散值或在随机搜索情况下要采样的值分布。

这两个类都提供了一个“cv”参数,允许指定整数折数(例如 5)或配置好的交叉验证对象。我建议定义和指定一个交叉验证对象,以获得对模型评估的更多控制,并使评估过程清晰明了。

对于分类任务,我建议使用 RepeatedStratifiedKFold 类,对于回归任务,我建议使用 RepeatedKFold 类,并指定合适的折数和重复次数,例如 10 折和 3 次重复。

这两个超参数优化类还提供了一个“scoring”参数,它接受一个字符串来指示要优化的指标。

该指标必须是最大化指标,意味着更好的模型会产生更高的分数。对于分类,这可能是“accuracy”。对于回归,这是一个负误差度量,例如“neg_mean_absolute_error”(均方绝对误差的负值),其中接近零的值表示模型预测误差较小。

您可以在此处查看内置评分指标列表

最后,可以通过指定“n_jobs”参数为一个整数,代表系统核心数(例如 8),来并行进行搜索,例如使用所有 CPU 核心。或者,您可以将其设置为 -1,自动使用系统中的所有核心。

定义完成后,通过调用 `fit()` 函数并提供用于通过交叉验证训练和评估模型超参数组合的数据集来执行搜索。

运行搜索可能需要几分钟或几个小时,具体取决于搜索空间的大小和硬件的速度。您通常会希望根据您有多少时间来调整搜索,而不是搜索的可能性。

搜索结束后,可以通过类属性访问所有结果。也许最重要的属性是观察到的**最佳分数**和获得最佳分数的**超参数**。

一旦您知道能获得最佳结果的超参数集,您就可以定义一个新模型,设置每个超参数的值,然后用所有可用数据拟合模型。然后可以使用该模型对新数据进行预测。

现在我们对 scikit-learn 中的超参数优化 API 有了了解,让我们看一些实际的例子。

分类超参数优化

在本节中,我们将使用超参数优化来为声纳数据集发现一个表现良好的模型配置。

声纳数据集是一个标准的机器学习数据集,包含 208 行数据,60 个数值输入变量和一个具有两个类值的目标变量,例如二元分类。

使用重复分层 10 折交叉验证和三次重复的测试框架,朴素模型可以达到约 53% 的准确率。表现最佳的模型在该测试框架上可以达到约 88% 的准确率。这提供了该数据集的预期性能范围。

该数据集涉及预测声纳回波是否指示岩石或模拟水雷。

无需下载数据集;我们将在工作示例中自动下载它。

下面的示例下载数据集并汇总其形状。

运行此示例将下载数据集并将其拆分为输入和输出元素。正如预期的那样,我们可以看到有 208 行数据和 60 个输入变量。

接下来,让我们使用随机搜索来为声纳数据集找到一个好的模型配置。

为了保持简单,我们将重点关注一个线性模型,即逻辑回归模型,以及该模型常用的超参数。

分类随机搜索

在本节中,我们将探讨逻辑回归模型在声纳数据集上的超参数优化。

首先,我们将定义要优化的模型,并为不进行优化的超参数使用默认值。

我们将使用重复分层 k 折交叉验证(三次重复,10 折)来评估模型配置。

接下来,我们可以定义搜索空间。

这是一个字典,其中名称是模型的参数,值是从中抽样的分布。我们将优化模型的 `solver`、`penalty` 和 `C` 超参数,其中 solver 和 penalty 类型使用离散分布,而 C 值使用 1e-5 到 100 的对数均匀分布。

对数均匀分布对于搜索惩罚值很有用,因为我们通常探索不同数量级的数值,至少在第一步是这样。

接下来,我们可以用所有这些元素定义搜索过程。

重要的是,我们必须通过“n_iter”参数设置要从搜索空间中抽样的迭代次数或样本数。在本例中,我们将它设置为 500。

最后,我们可以执行优化并报告结果。

将这些结合起来,完整的示例列在下面。

运行示例可能需要一分钟。之所以快,是因为我们使用了较小的搜索空间和拟合和评估速度快的模型。在优化过程中,您可能会看到一些关于无效配置组合的警告。这些警告可以安全地忽略。

在运行结束时,将报告最佳分数和实现最佳性能的超参数配置。

您特定的结果会因优化过程的随机性而有所不同。尝试运行示例几次。

在这种情况下,我们可以看到最佳配置的准确率约为 78.9%,这还可以,并且还列出了实现该分数所使用的 `solver`、`penalty` 和 `C` 超参数的具体值。

接下来,让我们使用网格搜索来为声纳数据集找到一个好的模型配置。

分类网格搜索

使用网格搜索非常类似于将其用于分类。

主要区别在于搜索空间必须是离散的网格才能进行搜索。这意味着,而不是为 `C` 使用对数均匀分布,我们可以指定对数尺度的离散值。

此外,`GridSearchCV` 类不接受迭代次数,因为我们只评估网格中的超参数组合。

将这些结合起来,用于声纳数据集的逻辑回归配置的网格搜索的完整示例列在下面。

运行示例可能需要一点时间。之所以快,是因为我们使用了较小的搜索空间和拟合和评估速度快的模型。同样,您可能会在优化过程中看到一些关于无效配置组合的警告。这些警告可以安全地忽略。

在运行结束时,将报告最佳分数和实现最佳性能的超参数配置。

您特定的结果会因优化过程的随机性而有所不同。尝试运行示例几次。

在这种情况下,我们可以看到最佳配置的准确率约为 78.2%,这也还可以,并且还列出了实现该分数所使用的 `solver`、`penalty` 和 `C` 超参数的具体值。有趣的是,结果与通过随机搜索得到的结果非常相似。

回归超参数优化

在本节中,我们将使用超参数优化来为汽车保险数据集发现一个表现最佳的模型配置。

汽车保险数据集是一个标准的机器学习数据集,包含 63 行数据,1 个数值输入变量和 1 个数值目标变量。

使用重复分层 10 折交叉验证和 3 次重复的测试框架,朴素模型可以实现约 66 的平均绝对误差(MAE)。表现最佳的模型在该测试框架上可以实现约 28 的 MAE。这提供了该数据集的预期性能范围。

该数据集涉及根据不同地理区域的索赔数量预测总索赔金额(以瑞典克朗千计)。

无需下载数据集,我们将在实际示例中自动下载。

下面的示例下载数据集并汇总其形状。

运行示例会下载数据集并将其拆分为输入和输出元素。正如预期的那样,我们可以看到有 63 行数据,其中包含 1 个输入变量。

接下来,我们可以使用超参数优化来为汽车保险数据集找到一个好的模型配置。

为了保持简单,我们将重点关注一个线性模型,即 线性回归模型,以及该模型常用的超参数。

回归随机搜索

配置和使用回归的随机搜索超参数优化过程与用于分类非常相似。

在这种情况下,我们将配置线性回归实现的重要超参数,包括 `solver`、`alpha`、`fit_intercept` 和 `normalize`。

我们将对除 `alpha` 参数(这是一个惩罚项)之外的所有参数在搜索空间中使用离散值分布,对于 `alpha` 参数,我们将像上一节对逻辑回归的 `C` 参数那样使用对数均匀分布。

回归与分类的主要区别在于评分方法的选择。

对于回归,性能通常使用误差来衡量,误差是最小化的,零表示模型技能完美。scikit-learn 中的超参数优化过程假定一个最大化分数。因此,提供了每个误差度量的负值版本。

这意味着大的正误差变成大的负误差,好的性能是接近零的大的负值,而完美技能是零。

解释结果时可以忽略负 MAE 的符号。

在这种情况下,我们将使用平均绝对误差(MAE),可以通过将“scoring”参数设置为“neg_mean_absolute_error”来获得该误差的最大化版本。

将这些结合起来,完整的示例列在下面。

运行示例可能需要一点时间。之所以快,是因为我们使用了较小的搜索空间和拟合和评估速度快的模型。在优化过程中,您可能会看到一些关于无效配置组合的警告。这些警告可以安全地忽略。

在运行结束时,将报告最佳分数和实现最佳性能的超参数配置。

您特定的结果会因优化过程的随机性而有所不同。尝试运行示例几次。

在这种情况下,我们可以看到最佳配置的 MAE 约为 29.2,非常接近模型中的最佳性能。然后我们可以看到实现此结果的具体超参数值。

接下来,让我们使用网格搜索来为汽车保险数据集找到一个好的模型配置。

回归网格搜索

作为网格搜索,我们不能定义要采样的分布,而是必须定义一个离散的超参数值网格。因此,我们将 `alpha` 参数指定为对数 10 尺度的值范围。

网格搜索对于回归而言,需要像我们对随机搜索那样指定“scoring”。

在这种情况下,我们将再次使用负 MAE 评分函数。

将以上内容整合起来,下面列出了针对汽车保险数据集的线性回归配置的网格搜索完整示例。

运行此示例可能需要一分钟。它之所以快速,是因为我们使用了较小的搜索空间和较快的模型进行拟合和评估。同样,在优化过程中,您可能会看到有关无效配置组合的一些警告。这些警告可以安全地忽略。

在运行结束时,将报告最佳分数和实现最佳性能的超参数配置。

您特定的结果会因优化过程的随机性而有所不同。尝试运行示例几次。

在本例中,我们可以看到最佳配置达到了约 29.2 的 MAE,这与我们在上一节中使用随机搜索取得的结果几乎相同。有趣的是,超参数也几乎相同,这提供了一个很好的确认。

关于超参数优化的一些常见问题

本节将解决有关超参数优化的一些常见问题。

如何选择随机搜索和网格搜索?

根据您的需求选择方法。我建议从网格搜索开始,如果时间允许,再进行随机搜索。

网格搜索适用于对已知通常效果良好的超参数值进行小型快速搜索。

随机搜索适用于发现新的超参数值或超参数组合,通常能获得更好的性能,尽管可能需要更多时间来完成。

如何加快超参数优化速度?

请确保将“n_jobs”参数设置为您机器上的核心数。

之后,还有其他建议,包括

  • 在数据集的小样本上进行评估。
  • 探索较小的搜索空间。
  • 为交叉验证使用更少的重复和/或折。
  • 在更快的机器上执行搜索,例如 AWS EC2。
  • 使用评估速度更快的替代模型。

如何选择要搜索的超参数?

大多数算法都有一个子集超参数,它们对搜索过程的影响最大。

这些在算法的大多数描述中都有列出。例如,以下是一些算法及其最重要的超参数:

如果您不确定

  • 查阅使用该算法的论文以获取灵感。
  • 查阅 API 和算法文档以获取灵感。
  • 搜索所有超参数。

如何使用性能最佳的超参数?

定义一个新模型,并将模型的超参数值设置为搜索找到的值。

然后,在所有可用数据上拟合模型,并使用该模型开始对新数据进行预测。

这被称为准备最终模型。在此处查看更多信息

如何进行预测?

首先,拟合最终模型(上一个问题)。

然后调用 predict() 函数进行预测。

有关使用最终模型进行预测的示例,请参阅教程

您对超参数优化还有其他疑问吗?
在下面的评论中告诉我。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

教程

API

文章

总结

在本教程中,您了解了 Python 中的机器学习超参数优化。

具体来说,你学到了:

  • 超参数优化对于充分利用机器学习模型至关重要。
  • 如何配置用于分类任务的随机搜索和网格搜索超参数优化。
  • 如何配置用于回归任务的随机搜索和网格搜索超参数优化。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

发现 Python 中的快速机器学习!

Master Machine Learning With Python

在几分钟内开发您自己的模型

...只需几行 scikit-learn 代码

在我的新电子书中学习如何操作
精通 Python 机器学习

涵盖自学教程端到端项目,例如
加载数据可视化建模调优等等...

最终将机器学习带入
您自己的项目

跳过学术理论。只看结果。

查看内容

对“随机搜索和网格搜索的超参数优化”的 36 条回复

  1. William Smith 2020年9月18日 上午8:29 #

    难道没有比随机搜索和网格搜索更有效的方法吗?超参数调优本身显然是一个优化过程,而普通的优化过程并不搜索整个问题空间。

    这难道不是“探索”与“利用”权衡的典型案例吗,除了上面两种方法都没有利用?

    • Jason Brownlee 2020年9月18日 上午9:20 #

      是的,随机搜索是一个好的开始,贝叶斯优化很常见,或者任何基于群体的全局优化算法都可以使用,例如遗传算法或模拟退火。

  2. William Smith 2020年9月18日 上午8:34 #

    准随机数(例如 Sobol 序列)是否比伪随机数更可取?因为它可以更均匀地搜索问题空间。这在金融领域的蒙特卡洛方法中得到了广泛应用,原因就在于此。

    scikit-learn 是否实现了这一点?

    它们还可以实现提前停止——您可以查看已达到的解决方案的质量,并自行决定何时使用迄今为止最佳的解决方案,而无需(检查整个网格)或(指定固定的迭代次数)。

    • Jason Brownlee 2020年9月18日 上午9:21 #

      在大多数情况下,伪随机数就足够了。

  3. shaheen mohammed saleh 2020年9月18日 下午4:35 #

    在哪里可以准确地放置或应用达到此结果的特定超参数值?请解释这一步骤,非常感谢。

    • Jason Brownlee 2020年9月19日 上午6:48 #

      一旦该方法确定了导致最佳性能的超参数,您就可以使用这些超参数来确定最终模型,并在所有可用数据上拟合模型,为对新数据进行预测做好准备。

  4. Gökhan Göy 2020年9月24日 下午9:27 #

    我认为这是从头到尾最好的教程。简单、易用且出色!感谢这篇帖子。

  5. programmer_newby 2020年12月1日 下午11:06 #

    嗨,Jason!

    非常感谢您提供的详细概述!我目前正在使用 Keras 的 Sequential 模型,因为它似乎是一种简单的方法来获取具有已定义层和节点的神经网络架构。我猜由于这个模型不是 sklearn 的模型,所以我不能使用这里解释的优化方法?

    • Jason Brownlee 2020年12月2日 上午7:45 #

      不客气。

      您可以使用 for 循环手动对 Keras 超参数进行网格搜索。

      或者,您可以将您的模型包装在 scikit-learn 包装器中,并使用网格/随机搜索。

      博客上这两种方法都有示例,请尝试搜索一下。

  6. ola 2021年2月20日 上午11:03 #

    谢谢你,Jason!

    我可以使用深度学习算法进行网格搜索或随机搜索吗?
    或者是否有用于调整深度学习算法超参数的特定技术?

  7. sasan 2021年4月24日 上午5:20 #

    您好。非常感谢您精彩的教程。

    我有一个问题。在深度学习模型中,通过随机搜索和元启发式算法寻找超参数有什么区别?

    您能为我推荐一个教程吗?

    • Jason Brownlee 2021年4月24日 上午5:23 #

      不客气。

      区别在于,在某些问题上,某些算法可能比其他算法更快地找到更好的结果。

  8. Diego Hidalgo 2021年6月15日 上午5:56 #

    你好 Jason。
    您的网站上有非常精彩且有用的信息,恭喜!
    我正在使用 R 中的 RF。我使用了预测变量表来创建常规的树状图(欧氏距离和平均法),以便有一个图表来解释(或显示)样本组的接近程度或远近。您认为这有效或有意义吗?或者您认为最好只使用原始数据表来构建树状图?

    谢谢你,

    • Jason Brownlee 2021年6月15日 上午6:10 #

      也许可以与其他方法比较结果,如果它效果好/更好就使用它。

  9. govin 2021年8月24日 下午4:31 #

    在这里,有多少个 epoch 被指定?我的意思是,epoch 的数量是否在任何一行中指定?

    • Adrian Tam
      Adrian Tam 2021年8月25日 上午5:58 #

      您是指 n_iter 参数吗?

  10. Nathan 2021年12月13日 上午7:29 #

    我在网上看到,人们建议创建 3 个数据集——训练、验证和测试集。

    他们说要在验证集上执行超参数调优,否则您将面临数据泄漏的风险。在这里,您对整个数据集进行调优,这是否有效?

    关于仅在验证集上进行调优的其他建议是否不正确?为什么?

    谢谢!

  11. Diego Pardo 2021年12月17日 上午7:45 #

    您好,Jason!

    我有一个问题,这篇文章是否使用了标准化的方法来应用随机搜索?我正在寻找一种使用随机搜索的超参数优化方法,以标准化研究过程。

    您知道标准化的随机搜索方法吗?

    非常感谢,

    • Adrian Tam
      Adrian Tam 2021年12月19日 下午1:29 #

      在我看来,标准化是一种数据预处理技术,而随机搜索是用于超参数的。因此,它们应该无关。

    • James Carmichael 2021年12月21日 上午11:48 #

      你好 Diego…RandomSearchCV 和 GridSearchCV 技术都基于经过时间考验的方法,利用交叉验证。请遵循原始帖子中这两个的链接。另外,请查看“机器学习优化速成课程” - https://machinelearning.org.cn/optimization-for-machine-learning-crash-course/

      此致,

  12. Jack 2022年2月27日 下午10:27 #

    Jason,您好,感谢您的这篇文章。

    我有一个大型数据集,已分为训练、验证和测试数据集。

    使用整个训练数据集进行超参数调优,并使用整个验证数据集验证超参数性能,在计算上成本很高(耗时很长)。

    问题

    在这种情况下,使用一小部分训练和验证数据集并用它来调优超参数是否明智?如果可以,我应该使用哪种采样方法?

    谢谢你。

  13. Rodrigo 2022年4月2日 下午12:52 #

    伙计,我只想感谢您所做的工作。我们从您的文章中学到了很多东西。谢谢!

    • James Carmichael 2022年4月3日 上午10:33 #

      非常感谢 Rodrigo 的反馈!

  14. Lucas 2022年9月14日 上午8:10 #

    嗨,Jason,

    感谢您的文章!

    我仍然难以理解为什么随机搜索/网格搜索直接在整个数据集上运行,而不是仅在训练集上运行。我已查看了之前一个类似的问题,但那并没有帮助我澄清我的疑虑。我经常处理小型数据集,了解如何对这些小型数据集有效且正确地进行超参数优化非常有帮助。

    谢谢

  15. siera lotfi 2022年9月25日 上午7:48 #

    随机搜索和随机网格搜索是相同的吗?

    • James Carmichael 2022年9月26日 上午7:49 #

      你好 siera…是的,它们是相同的!

  16. amanda 2022年9月25日 下午9:42 #

    随机搜索和随机网格搜索是相同的吗?谢谢您的帮助

  17. christian 2022年12月1日 上午5:54 #

    你好 Jason,

    感谢您的文章。我们可以将相同的代码用于基于树的模型吗?

  18. marwa 2023年9月4日 上午3:42 #

    我正在处理一个大型数据集(47,000 个文档),用于文本分类。为了优化 SVM 的 C 值,最快且计算量最小的超参数优化方法是什么?我没有足够的资源。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。