使用scipy least_squares(LM法)拟合数据时遇维度不匹配错误求助
解决scipy least_squares拟合NFW函数的广播错误
错误原因分析
你遇到的ValueError核心问题有两个:
- 参数顺序完全颠倒:
scipy.optimize.least_squares要求残差函数的第一个参数必须是待优化的参数数组(也就是你要解的r_s和delta_c),但你把自变量r放在了第一个位置,导致优化时把初始猜测的[5,50000](形状(2,))当成了r传入,和后续的R数组(形状(20,))无法广播运算。 - 残差函数逻辑错误:
least_squares需要的是模型预测值与真实值的残差(预测-真实),而非直接返回模型的计算结果。
修正后的代码
import numpy as np from scipy.optimize import least_squares np.seterr(divide='ignore') def nfw_residual(params, r, proftot): # params是待优化的参数数组,第一个元素是r_s,第二个是delta_c r_s, delta_c = params # 计算NFW模型的预测值(log10形式) pred = np.log10(delta_c * 127.5 / ((r/r_s) * (1 + r/r_s)**2)) # 返回残差:预测值 - 真实值 return pred - proftot # 原始数据 R = np.array([10., 13.3723382, 17.88194288, 23.91233878, 31.97639691, 42.75991937, 57.18001031, 76.46304359, 102.24896784, 136.73079658, 182.84104538, 244.50122949, 326.95533545, 437.21576207, 584.65970352, 781.82675534, 1045.48522765, 1398.05828227, 1869.53081686, 2500.00000668]) proftot = np.log10([2.86820475e-03, 5.65127564e-04, 2.58072307e-04, 1.19604185e-04, 5.72396406e-05, 2.80331317e-05, 1.38935580e-05, 6.87949343e-06, 3.33928154e-06, 1.57168352e-06, 7.33896604e-07, 3.09905078e-07, 9.48185811e-08, 1.61456370e-08, 1.71789382e-09, 1.69049246e-10, 1.67945764e-11, 1.67722875e-12, 3.81870305e-14, 0.00000000e+00]) # 处理proftot中的-inf值(log10(0)的结果),避免拟合异常 proftot = np.where(np.isinf(proftot), -15, proftot) initial_guess = np.array([5, 50000]) # 调用least_squares,args传入固定的自变量和真实值 result = least_squares(nfw_residual, initial_guess, method='lm', args=(R, proftot)) print("Optimized Parameters (r_s, delta_c):", result.x)
关键修改说明
- 重构残差函数:将待优化参数
params作为第一个输入,内部拆分出r_s和delta_c,再计算预测值与残差。 - 处理异常值:原数据中最后一个值是0,
log10(0)会得到-inf,这会干扰拟合,这里替换为-15(可根据实际情况调整)。 - 调整调用参数:
least_squares的args参数传入固定的自变量R和真实值proftot,确保优化过程中只调整r_s和delta_c。
内容的提问来源于stack exchange,提问作者Sam Jongman
相关产品推荐
相关产品推荐

