为何curve_fit对相同数据、相似拟合函数表现差异显著?
曲线拟合中符号修改导致拟合效果异常的问题
问题背景
- 使用
scipy.optimize.curve_fit训练回归模型,输入X为(95,3)的三维数组(95个样本,三个维度对应a0、a1、a2),目标是预测实值标签y(形状(95,)) - 初始拟合函数:
拟合后MAE约0.23,效果理想y = a3 * np.exp(a2 * (k1 * a1 + k0)) - 修改后的拟合函数:
按逻辑,新函数的最优k0、k1应是原结果的相反数,MAE也应保持一致,但实际MAE高达0.95左右,参数完全不符合预期y = a3 * np.exp((-1) * a2 * (k1 * a1 + k0))
复现代码
import numpy as np from scipy.optimize import curve_fit from sklearn.metrics import mean_absolute_error np.random.seed(42) def func_exp_linear(X, k0, k1): T = X[:, 0] # Temp t = X[:, 1] # time res_cl = X[:, 2] # res cl return res_cl * np.exp(t * (k0 + k1 * T)) def func_exp_linear_minus(X, k0, k1): T = X[:, 0] # Temp t = X[:, 1] # time res_cl = X[:, 2] # res cl return res_cl * np.exp((-1) * t * (k0 + k1 * T)) # 加载数据 with open('X.npy', 'rb') as f: X = np.load(f) with open('y.npy', 'rb') as f: y = np.load(f) # 拟合带负号的函数 popt_minus, pcov_minus = curve_fit(func_exp_linear_minus, X, y) y_hat_minus = func_exp_linear_minus(X, *popt_minus) MAE_minus = mean_absolute_error(y, y_hat_minus) print('添加负号后的MAE:', MAE_minus) # 拟合原函数 popt_original, pcov_original = curve_fit(func_exp_linear, X, y) y_hat_original = func_exp_linear(X, *popt_original) MAE_original = mean_absolute_error(y, y_hat_original) print('未添加负号的MAE:', MAE_original)
运行结果
添加负号后的MAE: 0.9278041290464241 未添加负号的MAE: 0.23378209064718086
问题原因与解决方案
原因
curve_fit默认使用的初始参数是[1, 1],修改函数符号后,最优参数实际是原参数的相反数(比如原参数为k0=-a、k1=-b,新函数的最优解应为k0=a、k1=b)。但优化器从[1,1]开始搜索时,容易陷入局部最优,或是因参数空间特性无法定位到真正的最优解,导致拟合效果极差。
解决方案
给带负号的函数指定初始参数p0,直接使用原函数最优参数的相反数:
# 先拟合原函数得到最优参数 popt_original, _ = curve_fit(func_exp_linear, X, y) # 用原参数的相反数作为新函数的初始值 popt_minus, pcov_minus = curve_fit(func_exp_linear_minus, X, y, p0=-popt_original) y_hat_minus = func_exp_linear_minus(X, *popt_minus) MAE_minus = mean_absolute_error(y, y_hat_minus) print('指定初始参数后,添加负号的MAE:', MAE_minus) print('原函数最优参数:', popt_original) print('新函数最优参数:', popt_minus)
修正后的效果
此时MAE会和原函数基本一致,新参数也会接近原参数的相反数,完全符合预期逻辑。
内容的提问来源于stack exchange,提问作者Zizhuo Meng
相关产品推荐
相关产品推荐

