Scipy.optimize.least_squares结果随输入顺序变化的原因咨询
最小二乘优化因输入顺序不同得到不同结果的原因
我在运行以下代码时发现,交换输入Y和T的顺序后,最小二乘优化的结果完全不同。按道理最小二乘优化不应该受数据点顺序影响,想知道具体原因。
代码示例
import numpy as np from scipy.optimize import least_squares def dummy_func(Y, T): # Define fn to optimize def func(X): tau = X[0] C1 = X[1] C2 = X[2] C3 = X[3] C4 = X[4] L0 = X[5] S1 = X[6] exp_tt1 = np.exp(- T / tau) f1 = (1 - exp_tt1) / (T / tau) f2 = 2 * f1 - exp_tt1 * (T / tau) f3 = 3 * f2 - exp_tt1 * (T / tau) ** 2 f4 = 4 * f3 - exp_tt1 * (T / tau) ** 3 f5 = 5 * f4 - exp_tt1 * (T / tau) ** 4 y_hat = L0 + S1 * f1 + C1 * f2 + C2 * f3 + C3 * f4 + C4 * f5 errs = Y - y_hat return errs return func # starting point and boundaries initial_params = np.array([ 10, 0, 0, 0, 0, 100, 0]) bounds_lower = np.array([ 3, -500, -1e3, -100, -15, 0, -1e3]) bounds_upper = np.array([ 15, 500, 1e3, 100, 15, 1e5, 1e3]) # inputs Y = np.array([5, 6, 7]) T = np.array([1, 1.5, 1.6]) # Get min function min_fn = dummy_func(Y, T) # Fit res = least_squares(min_fn, initial_params, bounds=(bounds_lower, bounds_upper), ftol=1e-3, loss="linear", verbose=0) # swap items 1 and 2 T_swap = T.copy() Y_swap = Y.copy() ix1 = 1 ix2 = 2 T_swap[[ix1, ix2]] = T[[ix2, ix1]] Y_swap[[ix1, ix2]] = Y[[ix2, ix1]] # Get min function min_fn_swap = dummy_func(Y_swap, T_swap) # Fit res_swap = least_squares(min_fn_swap, initial_params, bounds=(bounds_lower, bounds_upper), ftol=1e-3, loss="linear", verbose=0) print(f"same results? {all(res.x == res_swap.x)} \n res.x: {res.x} \nres_swap.x: {res_swap.x}")
运行输出
same results? False res.x: [ 3.00001277 310.88942015 300.69037515 -40.34027084 -9.85586819 43.96214131 -290.54867755] res_swap.x: [ 10.28332721 86.26342455 -67.14921168 8.76243152 0.51657765 93.50701816 -133.10992102]
原因分析
1. 参数边界约束触发局部最优
你给优化问题添加了明确的参数上下限(bounds),这会让原本可能只有全局最优的最小二乘问题,变成存在多个局部最优解的约束优化问题。当数据点顺序改变时,优化算法的迭代搜索路径会发生偏移,最终收敛到不同的局部极小值——无约束的最小二乘问题结果不受顺序影响,但带约束的情况完全不同。
2. 目标函数强非线性特性
你的目标函数包含指数项exp(-T/tau),以及通过递推生成的f1-f5,属于强非线性模型。非线性优化问题本身就容易存在多个局部最优,数据点顺序的变化会改变误差项的组合方式,进而改变参数的梯度信息,引导算法走向不同的局部最优解。
3. 优化停止精度设置较宽松
你设置的ftol=1e-3精度较低,算法可能在还未收敛到全局最优(或同一个局部最优)时就提前终止。加上初始参数固定,数据顺序改变后搜索方向不同,很容易得到差异明显的结果。
4. 数据点对参数的敏感度差异
每个数据点对参数的影响程度不同:比如不同T值对应的exp(-T/tau)变化率差异很大,交换数据点后,不同参数的梯度贡献会改变,算法的迭代方向也随之变化,最终收敛到不同的解。
验证建议
- 去掉边界约束(删除
bounds参数)重新运行,两次结果应该一致,可验证边界是核心影响因素。 - 提高收敛精度(比如设置
ftol=1e-8),增加迭代次数,观察是否能收敛到相同结果。 - 尝试不同的初始参数,查看结果的稳定性。
内容的提问来源于stack exchange,提问作者Mth Clv
相关产品推荐
相关产品推荐

