背景
在机器学习和深度学习的模型构建过程中,超参数调优是不可忽视的一步,然而,面对庞大而复杂的参数空间,手动调参往往耗时费力,难以快速找到最优解,Optuna 作为一款高效的自动化超参数优化框架,不仅能够快捷地支持多种优化算法,如贝叶斯优化、随机搜索、遗传算法等,还允许用户灵活选择或自定义优化策略,以满足多样化的调优需求,更重要的是,Optuna 还具备直观的可视化功能,使得调参过程清晰可见,帮助实时监控和分析每一步的优化效果,提升调优的效率与体验
接下来通过 XGBoost 回归模型的案例,展示如何利用 Optuna 实现高效、可视化的自动化调参,从而助力模型性能的提升
代码实现
数据读取整理
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel('2024-11-9-公众号Python机器学习AI.xlsx')
from sklearn.model_selection import train_test_split, KFold
X = df.drop(['待预测变量Y'],axis=1)
y = df['待预测变量Y']
# 划分训练集和测试集
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 然后将训练集进一步划分为训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X_temp, y_temp, test_size=0.125, random_state=42) # 0.125 x 0.8 = 0.1
读取数据集,将数据集分为训练集、验证集和测试集,测试集占整体的20%,而验证集占10%
利用Optuna实现XGBoost的自动调参与模型优化
import optuna # 导入Optuna库,用于超参数优化
from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error
from optuna.visualization import plot_optimization_history, plot_contour, plot_param_importances, plot_parallel_coordinate, plot_edf # 导入Optuna的可视化工具,用于绘制优化历史、参数重要性等
# 定义目标函数,用于Optuna的优化
def objective(trial):
# 定义模型的超参数搜索空间,Optuna会在此范围内进行参数采样
params = {
# 'n_estimators':模型中要构建的决策树的数量
# 值越高,模型拟合越充分,但计算开销也更大。一般较低的值适合快速迭代和避免过拟合
'n_estimators': trial.suggest_categorical('n_estimators', [50, 100, 200, 300]), #离散的类别选择范围
# 'max_depth':控制每棵树的深度,以防止过拟合。较高的深度会增加模型复杂性
'max_depth': trial.suggest_int('max_depth', 3, 15, step=1), #整数范围
# 'learning_rate':学习率决定每棵树对最终预测的贡献。较小的学习率通常需要更大的'n_estimators'来充分学习
'learning_rate': trial.suggest_loguniform('learning_rate', 0.01, 0.3), # 对数均匀分布的连续浮点数范围
# 'subsample':表示每棵树随机选择的样本比例,通常用于减少过拟合
'subsample': trial.suggest_uniform('subsample', 0.5, 1.0), # 线性均匀分布的连续浮点数范围
# 'colsample_bytree':控制每棵树使用的特征比例,以增强模型的鲁棒性
'colsample_bytree': trial.suggest_uniform('colsample_bytree', 0.5, 1.0),
# 'gamma':控制是否允许分裂,越高的值会使算法更保守,帮助避免过拟合
'gamma': trial.suggest_uniform('gamma', 0, 5)
}
# 使用采样的参数创建XGBRegressor模型
model = XGBRegressor(**params, random_state=42)
# 使用训练数据拟合模型
model.fit(X_train, y_train)
# 使用验证集进行预测
y_pred = model.predict(X_val)
# 计算并返回均方误差(MSE),作为优化的目标
return mean_squared_error(y_val, y_pred)
# 创建Optuna的Study对象,并设置优化方向为“minimize”表示最小化均方误差
# 默认情况下,Optuna使用的优化算法是 TPE (Tree-structured Parzen Estimator),
# 这是一种贝叶斯优化方法,适合高效地探索超参数空间
study = optuna.create_study(direction="minimize")
# 运行优化,进行100次试验
study.optimize(objective, n_trials=100)
print("Best parameters:", study.best_params)
# 使用最佳参数重新训练模型
best_model = XGBRegressor(**study.best_params, random_state=42)
best_model.fit(X_train, y_train)
使用 Optuna 进行 XGBoost 回归模型的超参数自动优化,首先定义目标函数 objective,其中设置了 XGBoost 的几个关键超参数的搜索空间,如 n_estimators、max_depth、learning_rate 等,Optuna 在指定的范围内自动采样这些超参数,通过最小化验证集上的均方误差(MSE)来寻找最佳参数组合,最后,利用找到的最佳参数重新训练 XGBoost 模型,以实现性能的提升
需要强调的是,Optuna 默认采用贝叶斯优化中的 TPE算法,这是一种适合高效搜索超参数空间的概率模型算法,TPE 会根据之前的采样结果逐步缩小参数搜索范围,以更快找到最佳参数组合
除了贝叶斯优化,Optuna 还支持其他优化算法和策略,包括:
- 随机搜索:从超参数空间中随机采样参数,是一种简单且常用的优化方法,适合初步探索或计算资源有限的情况
- 网格搜索:在一个预设的参数网格中进行穷举搜索,虽然效率较低,但能保证找到参数的全局最优解,适用于小规模参数空间
- 多臂老虎机算法:在高效选择和探索之间进行平衡,适用于动态调优或参数变化的情况
- 基于进化的算法:如遗传算法,模拟生物进化,逐步优化超参数。适合复杂参数空间,但一般耗时较长
Optuna 支持高扩展性,允许用户根据需求选择或自定义优化算法,比如,要使用 CMA-ES 进行优化,只需将 sampler 参数设为 CmaEsSampler,具体实现如下:
from optuna.samplers import CmaEsSampler
# 创建 Optuna Study 对象,使用 CmaEsSampler 作为采样器
study = optuna.create_study(direction="minimize", sampler=CmaEsSampler())
Optuna参数优化过程可视化
优化历史图
fig1 = plot_optimization_history(study)
fig1.show()
优化历史图用于显示在每次试验(trial)中,目标函数的值如何变化,其具体作用如下:
- 跟踪优化进程:可以观察到每次试验后的目标函数值是否逐渐趋于收敛,即找到最优解的趋势
- 比较试验结果:显示每次试验的目标值,帮助我们识别出那些尝试过的最优参数组合
- 诊断模型表现:如果目标函数值没有收敛,说明超参数选择可能还可以进一步优化
图表中横轴表示试验的编号(即试验次数),纵轴表示每次试验得到的目标函数值,可以观察到优化过程在前期迅速降低目标值并逐渐接近收敛
等高线图
fig2 = plot_contour(study, params=['n_estimators', 'max_depth'])
fig2.show()
fig3 = plot_contour(study, params=['learning_rate', 'gamma'])
fig3.show()
等高线图,用于展示两个超参数之间的关系以及它们对目标函数的影响,其具体作用如下:
- 分析参数交互:展示两个参数的不同组合对目标函数值的影响,可以帮助了解这些参数之间的交互关系
- 寻找最佳参数区域:通过颜色的深浅可以识别出目标值最低的区域,从而更直观地找到可能的最佳参数组合
- 优化方向指导:为进一步优化参数提供方向,帮助决定哪些参数组合值得进一步探索
在这个等高线图中,交互参数分别在横轴和纵轴上,而颜色表示目标函数值的大小,颜色越深通常表示目标值越低
参数重要性图
fig4 = plot_param_importances(study)
fig4.show()
参数重要性图展示不同超参数对目标函数的影响程度,即每个参数在优化过程中对最终结果的贡献大小,其具体作用如下:
- 识别关键参数:可以快速发现哪些超参数对模型性能影响最大,帮助将精力集中在重要参数的调优上
- 优化优先级:参数的重要性排序能够为优化提供优先级指导,先调整重要性高的参数,以更高效地提升模型性能
- 简化模型:如果某些参数重要性较低,可以考虑在调参时忽略它们,从而简化模型并减少计算量
横轴表示参数的重要性得分,分数越高的参数对目标函数的影响越大
平行坐标图
fig5 = plot_parallel_coordinate(study)
fig5.show()
平行坐标图展示不同超参数取值组合与目标函数值之间的关系,使得可以在一张图中直观地观察各个参数对结果的影响,其具体作用如下:
- 参数影响分析:可以帮助识别不同超参数的取值如何影响目标函数,观察某些参数取值与低目标值之间的关系
- 发现最佳参数组合:通过观察不同参数组合对目标值的影响,有助于识别最优参数组合
- 多参数交互可视化:直观地展示多个参数的交互影响,特别适合高维超参数空间的分析
纵轴表示各个超参数的取值,目标函数值通常用颜色或线条的粗细来表示,颜色越深或线条越粗代表目标值越低,反之亦然
经验分布函数图
fig6 = plot_edf(study)
fig6.show()
经验分布函数图用于显示试验结果的分布情况,帮助了解优化过程中目标函数值的累积分布
- 查看试验效果:通过 EDF 图,可以观察试验中目标值的分布,识别试验结果的集中程度
- 评估优化收敛性:图中越陡峭的部分表示较多试验集中在较低的目标值附近,说明优化过程逐步收敛
- 目标值分布分析:帮助了解目标值的累积情况,从而评估参数调优效果
横轴表示目标函数的值,纵轴表示该目标值或更小值的累积比例,曲线越快上升到 1,说明试验较多集中在更优的目标值附近
在 Optuna 的参数优化过程中,各种可视化图表能够帮助我们更深入地分析和理解优化过程及其结果。优化历史图可以直观地展示每次试验的目标函数值变化,便于跟踪收敛进程;等高线图和平行坐标图可以揭示超参数之间的关系和交互影响,从而更高效地找到最佳参数组合;参数重要性图可以帮助识别关键参数,优化优先级,集中精力在重要参数的调优上;经验分布函数图则提供了目标值分布的累积信息,使能够评估试验结果的集中度和优化的收敛性
需要注意的是,由于许多优化算法(如 TPE 或 CMA-ES)带有随机性,每次运行的结果可能会有所不同,因此,为确保结果的稳定性,在多次运行后选择平均效果较好的参数组合,或在代码中设置固定的随机种子,可以减少结果的波动性,同时,Optuna 支持在线的实时 Web 仪表板,使用户能够更便捷地监控和分析优化过程
模型性能输出
from sklearn import metrics
# 预测
y_pred_train = best_model.predict(X_train)
y_pred_test = best_model.predict(X_test)
y_pred_train_list = y_pred_train.tolist()
y_pred_test_list = y_pred_test.tolist()
# 计算训练集的指标
mse_train = metrics.mean_squared_error(y_train, y_pred_train_list)
rmse_train = np.sqrt(mse_train)
mae_train = metrics.mean_absolute_error(y_train, y_pred_train_list)
r2_train = metrics.r2_score(y_train, y_pred_train_list)
# 计算测试集的指标
mse_test = metrics.mean_squared_error(y_test, y_pred_test_list)
rmse_test = np.sqrt(mse_test)
mae_test = metrics.mean_absolute_error(y_test, y_pred_test_list)
r2_test = metrics.r2_score(y_test, y_pred_test_list)
print("训练集评价指标:")
print("均方误差 (MSE):", mse_train)
print("均方根误差 (RMSE):", rmse_train)
print("平均绝对误差 (MAE):", mae_train)
print("拟合优度 (R-squared):", r2_train)
print("\n测试集评价指标:")
print("均方误差 (MSE):", mse_test)
print("均方根误差 (RMSE):", rmse_test)
print("平均绝对误差 (MAE):", mae_test)
print("拟合优度 (R-squared):", r2_test)
使用训练集和测试集的预测结果来计算模型的评价指标,包括均方误差 (MSE)、均方根误差 (RMSE)、平均绝对误差 (MAE) 和拟合优度 (R-squared)
预测结果可视化
创建一个训练集和测试集的真实值与预测值的对比散点图,并添加回归线和拟合优度文本, 代码与数据集获取:如需获取本文的源代码和数据集,请添加作者微信联系
🎁 赠书活动来啦! 🎁
支持知识分享,畅享学习乐趣!特别感谢清华出版社 对本次赠书活动的鼎力支持!即日起,只需
点赞、在看、转发 此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送清华出版社提供的《Origin科技绘图与数据分析》这本精彩书籍📚!
💡 赶快参与,一键三连,说不定你就是那位幸运读者哦!
往期推荐
复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性
复现 Nature 图表——基于PCA的高维数据降维与可视化实践及其扩展
复现Nature图表——基于PCA降维与模型预测概率的分类效果可视化
SCI图表复现:如何直观展示机器学习模型预测结果的准确性和一致性
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考