注意
不再维护 Hyperopt 的开源版本。
在 16.4 LTS ML 之后,用于机器学习的 Databricks Runtime 中不包含 Hyperopt。 Azure Databricks 建议使用 Optuna 来进行单节点优化,或者使用 RayTune 来获得与已弃用的 Hyperopt 分布式超参数优化功能类似的体验。 详细了解如何在 Azure Databricks 上使用 RayTune。
此示例笔记本演示如何使用 Hyperopt 和 SparkTrials 将单机超参数优化缩放到Azure Databricks群集。 优化鸢尾花数据集上的 scikit-learn 的 SVM 分类器,首先生成单机 fmin() 工作流,然后将其在 Spark 计算节点上并行化,使用 MLflow 自动跟踪每个试验。
导入所需的包和加载数据集
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from hyperopt import fmin, tpe, hp, SparkTrials, STATUS_OK, Trials
# If you are running Databricks Runtime for Machine Learning, `mlflow` is already installed and you can skip the following line.
import mlflow
# Load the iris dataset from scikit-learn
iris = iris = load_iris()
X = iris.data
y = iris.target
第 1 部分。 单机 Hyperopt 工作流
下面是 Hyperopt 工作流中的步骤:
- 定义要最小化的函数。
- 在超参数上定义搜索空间。
- 选择搜索算法。
- 使用 Hyperopt
fmin()运行优化算法。
有关详细信息,请参阅 Hyperopt 文档。
定义要最小化的函数
在此示例中,我们使用支持向量机分类器。 目标是查找正则化参数 C的最佳值。
Hyperopt 工作流的大部分代码都位于目标函数中。 此示例使用 scikit-learn 中的支持向量分类器。
如果群集使用 Databricks Runtime 11.3 ML,请编辑支持向量分类器以采用位置参数 clf = SVC(C)。
def objective(C):
# Create a support vector classifier model
clf = SVC(C=C)
# Use the cross-validation accuracy to compare the models' performance
accuracy = cross_val_score(clf, X, y).mean()
# Hyperopt tries to minimize the objective function. A higher accuracy value means a better model, so you must return the negative accuracy.
return {'loss': -accuracy, 'status': STATUS_OK}
在超参数上定义搜索空间
有关定义搜索空间和参数表达式的详细信息,请参阅 Hyperopt 文档 。
search_space = hp.lognormal('C', 0, 1.0)
选择搜索算法
两个主要选择是:
-
hyperopt.tpe.suggest:Parzen 估算器树,一种贝叶斯方法,它以迭代和自适应方式选择新的超参数设置,以基于过去的结果进行探索 -
hyperopt.rand.suggest:随机搜索,这是一种非自适应方法,用于对搜索空间进行采样
algo=tpe.suggest
使用 Hyperopt 运行优化算法 fmin()
将 max_evals 设置为超参数空间中要测试的最大点数,即要拟合和评估的最大模型数。
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=16)
# Print the best value found for C
print("Best value found: ", argmin)
第 2 部分。 使用 Apache Spark 和 MLflow 进行分布式优化
若要分发调优,请在fmin()中添加一个额外的参数:一个名为TrialsSparkTrials的类。
SparkTrials 采用 2 个可选参数:
-
parallelism:要同时拟合和评估的模型个数。 默认值为可用的 Spark 任务槽数。 -
timeout:可以运行的最大时间(以秒fmin()为单位)。 默认值不是最长时间限制。
此示例使用 Cmd 7 中定义的非常简单的目标函数。 在这种情况下,函数运行得很快,启动 Spark 作业的开销在计算时间中占据主导地位,因此在分布式情况下,计算所需的时间更长。 对于典型的实际问题,目标函数更加复杂,使用 SparkTrails 来分配计算,比单机调优更快。
默认情况下启用自动 MLflow 跟踪。 若要使用它,如示例中所示,请先调用mlflow.start_run(),然后调用fmin()。
from hyperopt import SparkTrials
# To display the API documentation for the SparkTrials class, uncomment the following line.
# help(SparkTrials)
spark_trials = SparkTrials()
with mlflow.start_run():
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=16,
trials=spark_trials)
# Print the best value found for C
print("Best value found: ", argmin)
若要查看与笔记本关联的 MLflow 试验,请单击右上角笔记本上下文栏中的 “试验 ”图标。 在那里,可以查看所有运行。 若要查看 MLflow UI 中的运行,请单击 试验运行旁边的图标。
检查调整 C的效果:
- 选择生成的运行,然后单击“ 比较”。
- 在散点图中,为 X 轴选择 C ,为 Y 轴选择 损失 。
在笔记本的最后一个单元格中执行操作后,MLflow UI 应显示: