如何在Sklearn回归中使用SwarmPackagePy?及萤火虫算法优化GPR超参数
如何用SwarmPackagePy的萤火虫算法优化Sklearn高斯过程回归(GPR)的超参数?
首先得明确一个关键问题:Sklearn的GPR模型对optimizer参数的要求和SwarmPackagePy里的算法接口不直接匹配——GPR需要的是一个符合特定签名的函数,而不是直接传入算法实例。所以咱们得先写一个适配函数,把萤火虫算法(FA)的逻辑包进去,让它能被GPR调用。
第一步:理解Sklearn GPR优化器的要求
GPR的optimizer函数需要满足这样的签名:
def optimizer(obj_func, initial_theta, bounds): # 实现优化逻辑 return optimized_theta, optimized_loss
参数说明:
obj_func:GPR传入的目标函数,也就是需要最小化的负对数边际似然initial_theta:核函数超参数的初始值数组bounds:每个超参数的上下界,是形状为(n,2)的数组(n是超参数数量)
返回值是优化后的超参数数组,以及对应的最小损失值。
第二步:封装萤火虫算法的适配函数
咱们把SwarmPackagePy的FA算法套进这个签名里,写一个适配函数:
import numpy as np import SwarmPackagePy as sp from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C def fa_optimizer(obj_func, initial_theta, bounds): # 提取超参数维度、上下界 dim = len(initial_theta) lower_bounds = bounds[:, 0] upper_bounds = bounds[:, 1] # 初始化萤火虫算法 # 这里的参数可以根据你的需求调整,比如种群大小、迭代次数 fa = sp.fa( n=50, # 种群规模 function=obj_func, # 直接用GPR传入的目标函数 lb=lower_bounds, ub=upper_bounds, dimension=dim, iteration=100, # 迭代次数,数值越大优化可能越充分但速度越慢 alpha=0.5, # 步长因子 beta0=1.0, # 初始吸引度 gamma=0.1, # 光吸收系数 theta=0.0, eta=0.1, interval=10 ) # 获取全局最优解 best_agent = fa.get_Gbest() optimized_theta = best_agent[:-1] # 前dim个元素是超参数 optimized_loss = best_agent[-1] # 最后一个元素是目标函数值 return optimized_theta, optimized_loss
第三步:把适配后的优化器用在GPR上
现在就可以像用默认优化器一样,把fa_optimizer传给GPR的optimizer参数了,举个完整的示例:
# 生成示例训练数据(你可以替换成自己的数据集) X = np.linspace(0, 10, 100).reshape(-1, 1) y = np.sin(X).ravel() + np.random.normal(0, 0.1, size=100) # 定义带超参数边界的核函数 # 这里用常数项+RBF核,每个超参数都设置了搜索范围 kernel = C(1.0, (1e-3, 1e3)) * RBF(1.0, (1e-2, 1e2)) # 创建GPR模型,使用萤火虫算法优化器 gp = GaussianProcessRegressor( kernel=kernel, alpha=1.5, optimizer=fa_optimizer, # 传入咱们的适配函数 n_restarts_optimizer=3 # 多次重启优化,避免陷入局部最优 ) # 拟合模型 gp.fit(X, y) # 查看优化结果 print("优化后的核参数:", gp.kernel_) print("最小负对数边际似然值:", gp.log_marginal_likelihood(gp.kernel_.theta))
一些注意事项
- SwarmPackagePy的FA默认是最小化目标函数,刚好和GPR需要最小化负对数边际似然的需求匹配,不用额外转换目标函数。
- FA的参数(比如种群大小、迭代次数)可以根据你的数据集规模和优化需求调整:迭代次数越多、种群越大,优化效果可能越好,但计算时间也会更长。
- 如果你之前用
tf.easom_function测试FA的动画,现在只需要把目标函数换成GPR传入的obj_func就行,适配函数已经帮咱们处理好了接口问题。
内容的提问来源于stack exchange,提问作者santobedi
相关产品推荐
相关产品推荐

