超参数调优是算法中的一个常见且重要环节。贝叶斯优化是一种有效的超参数调优方法,它通过建立目标函数的概率模型并利用这个模型来选择下一个需要评估的参数来进行优化。本文将介绍如何使用贝叶斯优化进行多目标超参数调优。
贝叶斯优化是一种黑盒优化方法,它在每次迭代中都会平衡探索和利用的权衡,以找到最优解。针对贝叶斯优化原理就不多说了,网上很多优秀的解释。大致过程就是:
首先假设目标函数遵循高斯过程,并通过观察目标函数的值来更新这个假设。然后,它选择一个收益最大化的点作为下一个观察点。
在推荐系统中,往往模型是多目标的。以内容流为例,目标可以是:点击、时长、转发、评论、点赞、关注等等。而在实践中,一定会遇到的问题是:多目标融合公式内的超参数拍定。
简单一点,可以使用“拍脑袋(经验决策)+暴力搜参”。这种方式对于超参数较少或者业务迭代的初期很适用。但是如果超参数较多,暴力搜参再进行A/B实验往往会浪费大量的时间、流量。因此可以通过贝叶斯优化来辅助我们调参。
多目标常见的融合方式是幂乘,那么最简单的,超参数可以是各个目标的幂指数。
Score=\prod Predict_{i}^{α_{i}}
其中α_{i}为第i个目标的幂指数,Predict_{i}为第i个目标的模型预测值。那么α_{i}即是我们需要调整的超参数。
贝叶斯优化中,需要确定优化目标,即一个具体的数值。因此需要根据线上A/B实验的效果来决定reward函数,比如:
Reward=20∗Time+10∗Like+35∗CTR+10∗Share
这里有几点经验:
现在我们可以使用贝叶斯优化来寻找最优的超参数。具体步骤如下:
4. 在迭代完成后,贝叶斯优化器会返回一组最优的超参数。
这里需要注意的是,线上A/B实验观察的时候,尽可能的保证数据置信,比如实验组给较大流量或实验周期较长。根据自己的业务,一般3-7天可以得到相对置信的结论。
另外,最初的参数往往是人工经验拍定,差距可以大一些,作为第一轮调参进行A/B实验。
废话不多直接上代码:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from bayes_opt import BayesianOptimization, UtilityFunction
def black_box_function(x, y):
return (x - 1) ** 2 + y ** 2 - 1
optimizer = BayesianOptimization(
f=None,
pbounds={'x': (-3, 3), 'y': (-3, 3)},
verbose=2,
random_state=1,
allow_duplicate_points=True
)
utility = UtilityFunction(kind="ucb", kappa=2.5, xi=0.0)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# Evaluate the black_box_function on a meshgrid
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
x, y = np.meshgrid(x, y)
z = black_box_function(x, y)
# Plot the surface
ax.plot_surface(x, y, z, cmap='viridis', alpha=0.3)
# Optimization loop
explored_points = []
for _ in range(12):
next_point = optimizer.suggest(utility)
target = black_box_function(**next_point)
optimizer.register(params=next_point, target=target)
explored_points.append((next_point['x'], next_point['y'], target))
print(next_point, target)
# Plot all explored points after the optimization loop
for i in range(1, len(explored_points)):
x_values = [explored_points[i-1][0], explored_points[i][0]]
y_values = [explored_points[i-1][1], explored_points[i][1]]
z_values = [explored_points[i-1][2], explored_points[i][2]]
ax.plot(x_values, y_values, z_values, c='red', marker='o', markersize=5, linewidth=1)
plt.show()
print(optimizer.max)
线上A/B实验和demo类似,只要把观测值离线手动算好来代替black_box_function的输出塞进来就行了。
代码参考链接:https://github.com/bayesian-optimization/BayesianOptimization
指标 | 提升效果 |
---|---|
A指标 | +**% 正向显著 |
B指标 | +**% 正向显著 |
C指标 | +**% 正向显著 |
D指标 | +**% 正向显著 |
E指标 | -**% 负向显著 |
最后放一下业务真实的线上指标,ABCD四个指标均有效提升,E指标负向显著。中间调过好几轮,一直会存在指标置换的情况无法避免,最后评估完置换是可以接受的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。