使用Scipy优化Scikit-learn高斯过程回归器RBF核时遇TypeError
解决Scipy trust_region_optimizer与高斯过程超参数优化的错误问题
咱们一步步拆解你遇到的问题,然后给出针对性的修复方案:
第一个错误:TypeError: unsupported operand type(s) for /: 'int' and 'function'
这个错误的核心是你直接用整数1除以函数对象obj_func,而不是除以函数执行后的返回值。1/obj_func这种写法是在操作函数本身,而非调用函数得到的对数边际似然值。你需要先调用obj_func拿到结果,再对结果取倒数。
第二个错误:ValueError:jac must be '2-point', '3-point', 'cs' or callable`
出现这个错误有两个关键原因:
- 你把
trust_region_optimizer的执行结果传给了GaussianProcessRegressor的optimizer参数,但这个参数需要接收的是函数对象(要在fit时才执行优化,而不是初始化时就跑一遍)。 scipy.optimize.least_squares要求目标函数返回残差数组,而高斯过程的目标函数返回的是标量值,这会导致内部计算jacobian时出错。
修复后的完整代码
import numpy as np from scipy.optimize import least_squares from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C def trust_region_optimizer(obj_func, initial_theta, bounds): # 包装目标函数:先调用obj_func拿到对数边际似然值,再取倒数并转成数组(满足least_squares的格式要求) def wrapped_func(theta): # 额外判断:避免obj_func返回0导致除以0的错误 log_likelihood = obj_func(theta) if log_likelihood == 0: raise ValueError("对数边际似然值为0,无法取倒数") return np.array([1 / log_likelihood]) # 转换bounds格式:least_squares要求bounds是(下限数组, 上限数组)的形式 lb, ub = zip(*bounds) trust_region_method = least_squares( wrapped_func, initial_theta, bounds=(np.array(lb), np.array(ub)), method='trf', # 显式指定jac计算方式,解决jac相关的报错 jac='2-point' ) # 返回优化后的参数和对应的函数值(取数组的第一个元素还原为标量) return (trust_region_method.x, trust_region_method.fun[0]) # 生成测试数据 X = np.random.random((10,4)) y = np.random.random((10,1)) # 定义核函数 kernel = C(1.0, (1e-5, 1e5)) * RBF(10.0) # 注意:这里optimizer参数传递的是函数对象本身,不是调用后的结果! gp = GaussianProcessRegressor( kernel=kernel, optimizer=trust_region_optimizer, alpha=1.2, n_restarts_optimizer=10 ) gp.fit(X, y) # 输出优化后的核参数 print("优化后的核参数:", gp.kernel_)
关键修复点说明
- 包装目标函数:用
wrapped_func先执行obj_func获取对数边际似然值,再取倒数并转为数组,满足least_squares对残差格式的要求。 - 正确传递optimizer:给
GaussianProcessRegressor的optimizer参数传入函数本身trust_region_optimizer,让它在fit阶段再触发优化逻辑。 - 调整bounds格式:把输入的bounds列表转换为
least_squares要求的(下限数组, 上限数组)形式。 - 指定jac计算方式:显式设置
jac='2-point',解决jacobian计算相关的错误。
内容的提问来源于stack exchange,提问作者santobedi
相关产品推荐
相关产品推荐

