作为一个合格的调参大侠,这个神器必须收入麾下!本文中,云朵君将和大家一起学习这个超强调参神器:Optuna,它透过调整适当的超参数来提高模型预测能力,可以和多个常用的机器学习演算法整合!掌握它,比赛都有底气了~
你是否曾经觉得模型有太多的超参数而感到厌烦吗?要从某一个演算法得到好的解必须要调整超参数,所谓的超参数就是控制训练模型的一组神秘数字,例如学习速率就是一种超参数。你永远不能事先知道 0~1 之间哪一个数字是最适合的,唯一的方法就是试错(trial and error)。那万一模型有多个超参数可以控制,岂不是就有成千上万种组合要慢慢尝试吗?
如果你有也这个问题,看这篇就对了!虽然你可能听过 Sklearn 的 GridSearchCV 网格搜索同样也是暴力的找出最佳参数,或是使用 RandomizedSearchCV 随机搜索指定超参数的范围并随机的抽取参数进?训练,其它们的共同缺点是非常耗时与占用机器资源。
这里我们要来介绍 Optuna 这个自动找超参数的方便工具,并且可以和多个常用的机器学习演算法整合。
Optuna 透过调整适当的超参数来提高模型预测能力,此方法最初于2019 发表于arxiv 的一篇论文Optuna: A Next-generation Hyperparameter Optimization Framework[1] 同时开源在GitHub[2]上免费提供大家使用。同时 Optuna 也是 2021 年 Kaggle 竞赛中最常见的模型调参工具。
下图所示是超参数优化器在整个算法学习过程中的位置。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/8e875b0971603891674944a54acdc0fe.png)
如上图所示,超参数调优器在模型外部,调优是在模型训练之前完成的。调整过程的结果是超参数的最佳值,然后将其馈送到模型训练阶段。
Optuna 是一个完全用 Python 编写的最先进的自动超参数调整框架。专为机器学习而设计,可以与 PyTorch、TensorFlow、Keras、SKlearn 等其他框架一起使用。
Optuna 使用一种称为运行时定义的 API,它可以帮助用户编写高度模块化的代码并动态构建超参数的搜索空间,我们将在本文后面学习。网格搜索、随机搜索、贝叶斯搜索和进化算法等不同的采样器,动找到最优超参数值。
通过调整函数(x-1)^2 + (y+3)^2 参数 x,y,使得其取得最小值。通过数学计算,很容易得到该函数在x=1 和y=-3 处达到最小值。
导入后,定义一个目标,返回想要最小化的函数。
在目标的主体中,我们定义要优化的参数,在这种情况下,简单和。参数是optuna的一个特殊Trial对象,它对每个超参数进行优化。
其中,它有一种方法,该方法采用超参数的名称和范围来寻找其最佳值。换句话说
几乎和做 GridSearch 的时候一样。
为了开始优化,我们从 Optuna 创建一个对象并将函数传递给它的方法:
非常接近,但没有你想要的那么接近。在这里,我们只进行了 100 次试验,如下所示:
Optuna 术语和约定的说明
在 Optuna 中,整个优化过程称为。例如,使用对数损失作为指标来调整 XGBoost 参数是一项研究:
- 通过指定超参数的一次试验来管理模型训练、评估和获得分数的所有单一执行。优化函数的一次执行称为试验。因此,这项研究是试验的集合。
- 管理和记录所有已执行的试验。该记录有助于我们了解最佳超参数并建议要搜索的下一个参数空间。整个优化过程是基于一个目标函数,即研究需要一个可以优化的函数。
定义目标特征
一项研究需要一个可以优化的功能。通常,此函数由用户定义,应命名并预期具有此签名:
Optuna 中的优化过程需要一个名为的函数,完成的每个超参数调整,在这个目标函数中,我们必须决定优化所基于的指标。试验对象是方法的输入,并返回一个分数。
- 包括作为字典搜索的参数网格
- 创建一个模型来尝试超参数组合集
- 将模型拟合到具有单个候选集的数据
- 使用此模型生成预测
- 根据用户定义的指标对预测进行评分并返回
研究中的每个试验都表示为类。此类是 Optuna 如何找到参数最佳值的关键。
定义搜索空间
通常,在目标函数中做的第一件事是使用内置的 Optuna 方法创建搜索空间。
在上述目标函数中,我们创建了一个随机森林超参数的小型搜索空间。搜索空间是一个普通的字典。要创建可能的值进行搜索,必须使用试验对象的函数。这些函数至少需要范围的超参数名称、最小值和最大值,以搜索分类超参数或可能的类别。为了使空间更小,并有额外的or参数。
创建研究对象
要开始研究,创建一个研究对象。
如果我们想要优化的指标是像ROC AUC或准确性这样的性能分数,那么我们将设置。否则,设置来最小化诸如 RMSE、RMSLE、log损失等损失函数。
然后调用的方法,传递目标函数名称和我们想要的试验次数:
Optuna 采样参数
Optuna 预设的超参数搜寻方法能有效地在短时间内往最佳的方向去寻找一组适合的参数。与 GridSearch 相比原本可能需要数小时的搜索空间在短短的几分钟内就可以获得不错的经果。并且有效的降低 loss。除了回归问题, Optuna 也能对分类问题进行超参数搜寻,官方的GitHub也有提供各种不同机器学习框架的写法。
TPESampler 为预设的超参数采样器。它试图透过提高最后一次试验的分数来对超参数候选者进行采样。除此之外 Optuna 提供了以下这几个参数采样的方式:
- : 与Sklearn 的采样方式相同。使用此方法时建议不要设定太大的范围。
- : 与Sklearn 的采样方式相同。
- : 全名Tree-structured Parzen Estimator sampler。预设采样方式。
- : 基于CMA ES 演算算法的采样器(不支援类别型的超参数).
如果需要替换采样参数的方式可以参考以下程式。
Optuna 中提供的不同采样器:
- 网格搜索:将每个超参数的搜索空间离散化。优化器为每个超参数配置启动学习,并在最后选择最佳配置。
- 随机搜索:对搜索空间进行随机采样,直到满足停止条件为止。
- 贝叶斯搜索:寻找最佳超参数的基于概率模型的方法
- 进化算法:利用适应度函数的值来寻找最佳超参数的元启发式方法。
Optuna进行超参数调优的优势:
①轻松集成且功能多:需要简单的安装,然后就可以开始使用了。可以处理广泛的任务并找到最佳调整的替代方案。
②即时动态搜索空间:熟悉的 Pythonic 语法,如条件和循环,用于自动搜索最佳超参数。
③最先进的算法:快速搜索大空间并更快地修剪没有希望的试验以获得更好和更快的结果。
④分布式优化:可以轻松并行化超参数搜索,而对原始代码几乎没有更改。
⑤良好的可视化:各种可视化功能也可用于直观地分析优化结果。
⑥ 支援大多数 ML 与 DL 的学习套件。例如: Sklearn、PyTorch、TensorFlow、 XGBoost、LightGBM、 CatBoost...等。
⑦ 高效的抽样和剪枝算法 通常,超参数优化框架的成本效益是通过搜索法寻找待评估参数和效率计算法从学习曲线计算待评估参数并识别待剔除参数的专长来衡量的。 对不利轨迹的消除表示为修剪或自动提前停止。
- 抽样方法有两种;(1) 关系抽样方法,处理参数之间的相互关系。(2) 独立抽样,单独采样每个参数,其中Optuna对两种抽样方法都是有效的。另外,Optuna 还有一个功能,允许用户部署自己定制的采样方法。
- 剪枝算法对于确保成本效益的“成本”因素至关重要,它分为两部分操作:(1)定期监控中间目标值,以及(2)暂停不符合预定义可能性的实验。
上下滑动查看更多源码
使用kaggle比赛数据集。
本次竞赛根据历史使用率和观测到的天气,跨四种能源类型构建这些反事实模型。该数据集包括三年来来自全球多个不同地点的一千多座建筑物的每小时仪表读数。
train.csv
- -- 建筑物元数据的外键。
- -- 仪表 ID 代码。读作。并非每座建筑都有所有仪表类型。
- -- 测量时间
- -- 目标变量。以千瓦时(或等价物)为单位的能耗。请注意,这是具有测量误差的真实数据,我们预计这将施加基线水平的建模误差。站点 0 的电表读数以 kBTU 为单位。
更多数据介绍请见文末。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/1a863680c2ac2537cf914dd7098c6ea1.png)
我们本次比赛的目标是预测建筑物的能源消耗。我们必须预测的 4 种能量类型是:
标签 | 能量类型 |
---|---|
0 | 电 |
1 | 冷冻水 |
2 | 蒸汽 |
3 | 热水 |
删除异常数据
![](https://ask.qcloudimg.com/http-save/yehe-8756457/7c6ae692c4c12667482397ece8ee0ab4.png)
日总使用量可视化
![](https://ask.qcloudimg.com/http-save/yehe-8756457/7fabd768a1185f95049c277d2d394ea9.png)
由图所示,2016 年 5 月中旬之前的数据看起来很奇怪,因为它位于图表的底部。究其原因是在 5 月 20 日之前的所有电表读数均为 0。合乎逻辑的做法是删除该时间段的数据。
site_id==0 都有哪些楼栋
![](https://ask.qcloudimg.com/http-save/yehe-8756457/81e999ca0e03b747caba8498d7a6eb1b.png)
从结果看,所有的数据都有。
因此做个筛选:
时序特征处理
本数据中有个重要的特征:timestamp,指定是测量仪表数据时的时间戳。
时间拆分
![](https://ask.qcloudimg.com/http-save/yehe-8756457/8360f451fbbd357cd7a26c55312b90aa.png)
描述性统计
首先根据建筑id,仪表id聚合,对仪表读书求和。计算每栋楼的能耗的各个统计值:均值、中值、最大值、最小值及方差等,并将所有统计值成一个总的统计表。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/dc6567d65e5b2dcd37ae4aa1b9085078.png)
将统计表与原训练表合并,得到每栋楼的每个仪表所读取到能耗总值及其统计值。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/269a17680ae6ea3c056d324fd32d9044.png)
缺失值处理
气象数据缺失值处理
气象数据(weather_train_df,来自尽可能靠近该站点的气象站的天气数据),表中有很多NaN 值,所以我们不能只去掉这些条目。我们将尝试通过插值数据来填充这些值。
在数值分析的数学领域,插值是一种估计,一种基于一组离散的已知数据点的范围构造(查找)新数据点的方法。 -- https://en.wikipedia.org/wiki/Interpolation
首先看几个样本数据:
![](https://ask.qcloudimg.com/http-save/yehe-8756457/3e0805dac573e5afde026df14749be91.png)
统计缺失值总数
气象数据训练和测试数据合并
![](https://ask.qcloudimg.com/http-save/yehe-8756457/4292c7e87fc2d0eef480cbee73185282.png)
![](https://ask.qcloudimg.com/http-save/yehe-8756457/cb9166c48502ce5632f947f2e1dbf72a.png)
![](https://ask.qcloudimg.com/http-save/yehe-8756457/603964c821bf1af50288a63cd9541ea6.png)
![](https://ask.qcloudimg.com/http-save/yehe-8756457/904eae5fda24a938a239edbb00bf2a7e.png)
特征衍生
通过滑动窗口,衍生一些时序特征。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/987c0d18c3bdc9d1b9e229c91ed7083f.png)
现在添加了滞后,我们将对 primary_use 列进行分类以减少合并时的内存。
在本节中,我们将学习如何使用 Optuna。但首先,将列分为分类特征和数值特征。
训练LightGBM模型
现在训练电表的LightGBM模型,获得最佳验证分数,并将此分数作为最终分数返回。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/224bf94504c7c6d8bdccd318bbbfba4b.png)
最重要参数概述
通常,大多数基于树的模型的超参数可以分为 4 类:
- 影响决策树结构和学习的参数
- 影响训练速度的参数
- 参数以获得更好的精度
- 对抗过拟合的参数
大多数时候,这些类别有很多重叠,提高一个类别的效率可能会降低另一个类别的效率。因此手动调参难以出色的完成这项任务。
函数具有核心训练代码并定义超参数。
接下来,我们将熟悉 “trial” 模块的内部工作原理。
这是使用 Optuna 与传统的定义并运行代码之间的比较:
![](https://ask.qcloudimg.com/http-save/yehe-8756457/56c4d500ba352a212f675a2ff210540f.png)
这就是按运行定义的优势。这使得用户更容易编写直观的代码来获取超参数,而不是预先定义整个搜索空间。
可以使用这些方法来获取超参数:
创建我们的主要训练函数了,我们放置了所有可能的超参数范围,并且该函数采用了一个试验对象,并且应该返回一个分数值。
进行"Study"和优化
在定义了目标函数并使用“”模块找到超参数后,就可以开始调优了。只需2行代码完成所有超参数调优。
由于的值是10,因此输出相当大。因此如下截图是最后一次trail的结果记录打印。
到目前为止,就完成了超参数调优了。
对无用的Trial进行剪枝是在optuna中一种先进而实用的技术。如果你不熟悉修剪是什么,可以理解为它是一种压缩ML搜索算法中的数据的技术,通过消除冗余和不重要的数据来分类实例,从而减少决策树的大小。
因此,剪枝可以提高最终分类器的复杂度,防止过拟合。Optuna提供了对多个流行ML框架的集成,用户可以使用它在超参数训练期间尝试修剪。例子:
- XGBoost:
- LightGBM:
- Chainer:
- Keras:
- TensorFlow
- tf.keras
- MXNet
这里可以详细了解这些集成的剪枝方法:optuna.integration[3]。
列举一个使用修剪创建目标函数的简单示例:
其中函数在函数基础上修改了模型训练参数:
Optuna 为我们提供了可视化训练和学习历史的选项,以确定具有最佳性能的超参数。最棒的是,所有这些可视化只需要 1 行代码!!!
Optuna 在同时也提供了可视化的套件:
- plot_optimization_history (可视化优化的过程)
- plot_intermediate_values (可视化学习的曲线)
- plot_slice (可视化个别参数)
- plot_contour (可视化参数间的彼此关系)
- plot_parallel_coordinate (可视化高维度中参数间的彼此关系)
- plot_param_importances (可视化参数对模型的重要程度)
- plot_edf (可视化验分布函数)
![](https://ask.qcloudimg.com/http-save/yehe-8756457/bc2203605afb5a5c10213f4b9a8c8fde.png)
调优的历史
可视化搜索历史让我们更好地了解超参数对我们模型的影响。我们还可以通过使用更窄的参数空间来进一步缩小搜索范围。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/d03e470c7a3b180313d684dc807e64dd.png)
所有不同的颜色显示每个试验的损失曲线。
切片图
![](https://ask.qcloudimg.com/http-save/yehe-8756457/33609a4d01a17e22c75ff1d62a324aeb.png)
等高线图
以目标值作为轮廓绘制参数对。
![](https://ask.qcloudimg.com/http-save/yehe-8756457/205ac632f8aba43e6b6afb91f49a7361.png)
平行坐标图
![](https://ask.qcloudimg.com/http-save/yehe-8756457/7d9351b5363b531030b99b0bb5909c30.png)
![](https://ask.qcloudimg.com/http-save/yehe-8756457/397559e3a1c194cb7a8bf4346910f46a.png)
绘制超参数重要性。从这张图我们可以发现eta(learning_rate) 学习速率是最为重要的。此外与对减少上无太大帮助。因此在下一次执行试验的时候可以考虑将无用的参数移除,并将重要的超参数范围加大取得更好的搜索结果。
创建 Optuna 研究并运行trial完整代码。
本文只是熟悉Optuna的开始,涵盖了有关如何调整 ML 模型的超参数的大部分基础知识。我们学习了 Optuna 库中使用的术语,例如trail和study。我们还学习了如何定义使用 Optuna 调整所必需的目标函数。
参考资料
[1]
Optuna: A Next-generation Hyperparameter Optimization Framework: https://arxiv.org/abs/1907.10902
[2]
GitHub: https://github.com/optuna/optuna
[3]
optuna.integration: https://optuna.readthedocs.io/en/stable/reference/integration.html