我希望使用具有常数因子的幂律来拟合我的x和y数据。我的幂律模型是y(r)= F0 + F *(r)** alpha其中F0是常数。我的代码是,
x = [0.015000000000000001, 0.024999999999999998, 0.034999999999999996, 0.044999999999999998, 0.055, 0.065000000000000002, 0.075000000000000011, 0.085000000000000006, 0.094999999999999987, 0.125, 0.17500000000000002, 0.22500000000000003, 0.27500000000000002]
y= [5.6283727993522774, 4.6240796612752799, 3.7366642904247769, 3.0668203445969828, 2.5751865553847577, 2.0815063796430979, 1.7152655187581032, 1.4686235817532258, 1.2501921057958358, 0.80178306738561222, 0.43372429238424598, 0.26012305284446235, 0.19396186239328625]
def func(x,m,c,c0):
return c0 + x**m * c
coeff,var=curve_fit(func,x,y)
print coeff
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/scipy/optimize/minpack.py", line 511, in curve_fit
raise RuntimeError(msg)
RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800.
然后我改变了maxfev = 2000然后它给了我错误的系数值。如果我改变了,我的斜率m到(-m)func然后它给了我正确的答案,但我的斜率将是负的。有没有办法克服这个问题?
答案 0 :(得分:6)
问题在于curve_fit
是从缺省的猜测开始的,这些参数太差了(即,它们全部以1开始)。
相反,使用您对数据的了解进行粗略猜测:至少,您知道m
必须是负数(因为它是幂律)。因此,请尝试在m
处开始-1
。 (您可以在0
开始截距术语,在1
开始斜率术语,因为这些是合理的默认值。
def func(x,m,c,c0):
return c0 + x**m * c
coeff,var=curve_fit(func,x,y, p0=[-1, 1, 0])
这为您提供了正确的输出:
[-0.34815029 2.16546037 -3.4650323 ]
(请注意,您可以使用m
和0
之间的任意数字开始-9
,并且它仍会收敛到此结果。)
答案 1 :(得分:0)
根据X和Y之间差异的大小,查看您的数据,我们的想法是重新调整您的问题。
first post中详细介绍了一个例子。