为何scipy.curve_fit与TI-84的幂律拟合参数结果存在差异?
幂律拟合结果差异的原因分析
你遇到的scipy curve_fit和TI-84 PwrReg的指数差异,核心原因是两种工具采用的拟合策略完全不同,具体分以下几点:
1. 拟合目标函数的本质区别
- scipy的
curve_fit默认使用非线性最小二乘法,直接最小化原始数据的残差平方和:$\sum (y_i - a x_ib)2$ - TI-84的
PwrReg默认是对数转换后的线性最小二乘法:先对x和y取对数,将幂律模型转换为线性模型$\ln y = \ln a + b \ln x$,再最小化对数空间的残差平方和:$\sum (\ln y_i - (\ln a + b \ln x_i))^2$
这两种方式的权重逻辑差异极大:原始空间的拟合会给y值大的点更高权重(比如你的数据点(0.117, 260.07),在原始拟合中残差平方的影响远大于对数空间),而对数转换后所有点的权重相对均衡。你数据里第一个点的y值远高于同x区间的其他点,这是指数差异的关键诱因。
2. 拟合算法与初始值的差异
- scipy的
curve_fit默认用Levenberg-Marquardt算法,初始参数默认是[1, 1],若数据非线性特征明显,可能收敛到局部最优解(不过你的数据用默认初始值结果稳定) - TI-84的
PwrReg可能采用了不同的初始值策略,比如先通过对数拟合得到初始参数,再做微调,或者直接固定输出对数线性拟合的结果。
3. 验证方法
你可以手动验证两种拟合方式的结果:
import numpy as np from scipy.optimize import curve_fit xdat = [0.117, 0.241, 0.782, 0.734, 1.275, 1.192, 1.483, 0.131, 0.279, 0.453, 1.128, 0.928, 2.197] ydat = [260.07, 85.82, 87.71, 124.57, 32.35, 80.5, 31.86, 55.36, 44.8, 27.28, 51.21, 53.77, 43.58] # 对数转换线性拟合 ln_x = np.log(xdat) ln_y = np.log(ydat) b, ln_a = np.polyfit(ln_x, ln_y, 1) a = np.exp(ln_a) print(f"对数拟合结果:a={a:.6f}, b={b:.6f}")
运行后会得到和TI-84几乎一致的结果(a≈52.24,b≈-0.31),直接验证了拟合策略的差异是核心原因。
如果需要让scipy的curve_fit得到和TI一致的结果,可以指定初始参数为对数拟合的结果;反之,若要让TI得到scipy的结果,需要确认TI是否支持非线性最小二乘的幂律拟合(大部分计算器默认都是对数转换法)。
内容的提问来源于stack exchange,提问作者TCB
相关产品推荐
相关产品推荐

