为何SciPy minimize最小化SSE/RMSE时返回不同解且收敛失败?
问题解答
1. 为何SSE与RMSE的最优参数不同?
理论上,RMSE是SSE的单调变换:$RMSE = \sqrt{\frac{SSE}{N}}$($N$为样本数),单调变换不会改变函数的最小值位置,两者的最优参数本应完全一致。
实际结果不同的核心是数值稳定性问题:
- 使用SSE时,初始猜测的B=1会让$exp(1*x)$在x=100时产生极大值($e{100}≈2.688×10{43}$),导致$y_{pred}$与真实y的差值平方后直接溢出(对应你看到的
overflow encountered in square警告),生成无穷大(Inf)或无效值。 - 这种数值异常会干扰BFGS优化器的梯度计算(
invalid value encountered in subtract警告就是梯度计算失败的表现),使得优化器无法沿正确方向迭代,最终停留在远离真实值的局部点,而非真正的最小值点。 - RMSE通过开平方和除以样本数,将损失值的数量级大幅缩小,避免了数值溢出,优化器能更稳定地进行梯度计算和参数更新,因此更接近真实的最小值位置。
2. 为何优化无法收敛?
主要有两个关键原因:
- 初始猜测与真实参数差距过大:你的初始猜测
[1,1,1]和真实参数[-6.899, 0.0221, 9.909]偏差极大,尤其是B=1时,指数项爆炸式增长,直接导致损失函数出现数值溢出,优化器无法正常计算梯度和Hessian矩阵。 - 指数模型的参数空间病态:指数函数对参数B极度敏感,B的微小变化会导致$y_{pred}$发生巨大波动,这使得目标函数的Hessian矩阵条件数极高,BFGS这类依赖二阶信息的优化器难以稳定收敛,容易陷入数值精度问题(对应结果中的
Desired error not necessarily achieved due to precision loss提示)。
3. 为何RMSE结果更优?
RMSE的损失值范围更贴合数值计算的稳定区间:
- SSE的数值会随样本数和误差大小急剧增大,本案例中仅初始猜测下的SSE就会达到天文数字,直接触发浮点溢出,导致优化器失效。
- RMSE通过归一化(除以样本数)和开平方,将损失值压缩到合理范围,避免了溢出和无效值,优化器的梯度计算、参数更新过程都能正常进行,因此能更接近真实参数——尽管最终也未完全收敛,但结果远好于SSE。
修复建议
- 优化初始猜测:根据数据趋势手动调整初始值,比如固定C为数据均值(真实y的均值接近9.909),A设为负数(y初始值是A+C≈3,A≈-6.9),B设为小正数(比如0.02),避免指数项爆炸。
- 添加参数边界:给B设置合理上下界(比如
bounds=[(-20,0), (0,0.1), (5,15)]),防止优化过程中B出现极端值导致数值溢出。 - 使用更鲁棒的优化方法:比如L-BFGS-B(带边界的拟牛顿法)或信任域类方法(如
trust-constr),这类方法对数值不稳定的情况更鲁棒。
修正后的示例代码:
import numpy as np from scipy.optimize import minimize # Generate data A_true = -6.899 B_true = 0.0221 C_true = 9.909 x = np.linspace(0, 100, 101) y = A_true*np.exp(B_true*x) + C_true def loss_func(parameters, x, y): A, B, C = parameters y_pred = A*np.exp(B*x) + C SSE = np.sum((y - y_pred)**2) RMSE = np.sqrt(SSE / len(y)) return RMSE # 更合理的初始猜测 guess = [-7, 0.02, 10] # 添加参数边界 bounds = [(-20, 0), (0, 0.1), (5, 15)] sol = minimize(loss_func, guess, args=(x, y), method='L-BFGS-B', bounds=bounds) print("Optimized parameters:", sol.x) print("Success:", sol.success)
内容的提问来源于stack exchange,提问作者Matt J
相关产品推荐
相关产品推荐

