Python scipy曲线拟合错误:被零除

Python scipy曲线拟合错误:被零除,python,scipy,runtime-error,curve-fitting,Python,Scipy,Runtime Error,Curve Fitting,一段时间以来,我一直在尝试使用scipy.optimize.curve\u fit将函数拟合到某些数据: from __future__ import (print_function, division, unicode_literals, absolute_import) import numpy as np from scipy.optimize import curve_

一段时间以来,我一直在尝试使用scipy.optimize.curve\u fit将函数拟合到某些数据:

from __future__ import (print_function,
                    division,
                    unicode_literals,
                    absolute_import)
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as mpl
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,     20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
y = np.array([20.8, 20.9, 22.9, 25.2, 26.9, 28.3, 29.5, 30.7, 31.8, 32.9, 34.0, 35.3, 36.4, 37.5, 38.6, 39.6, 40.6, 41.6, 42.5, 43.2, 44.2, 45.0, 45.8, 46.5, 47.3, 48.0, 48.6, 49.2, 49.8, 50.4])
def f(x, a, b, c):
    return a/(1+b*x**c)
popt, pcov = curve_fit(f, x, y)
print(popt, np.sqrt(np.diag(pcov)), sep='\n')
但总会出现一个错误:

RuntimeWarning: divide by zero encountered in power
return a/(1+b*x**c)
也许有人能帮我避开它?
任何帮助都将不胜感激。干杯

您的x值从0开始。如果由于某种原因,参数
c
在计算过程中为负值,则您将计算0,并将其提升为负指数,即除以0:对于
p>0
,我们有

0**(-p) = 1/(0**p)
        = 1/0

好的,两个有用的技巧

首先,用一些非常小的数字替换你的
x
中的
0
,例如
1e-8
(不要笑,
R
中有一个核心包,实际上是这样做的,
写的,他的名字不会被说出,而且人们一直在使用它。)
实际上,我根本没有收到你的
运行时警告。我正在运行
scipy
0.12.0
numpy
1.7.1
。也许这取决于版本

但我们会得到一个非常糟糕的匹配:

In [41]: popt, pcov
Out[41]: (array([  3.90107143e+01,  -3.08698757e+07,  -1.52971609e+02]), inf)
因此,技巧2不是优化
f
函数,而是定义
g
函数:

In [38]: def g(x, a, b, c):
   ....:     return b/a*x**c+1/a
   ....:

In [39]: curve_fit(g, x, 1/y) #Better fit
Out[39]:
(array([ 19.76748582,  -0.14499508,   0.44206688]),
 array([[ 0.29043958,  0.00899521,  0.01650935],
        [ 0.00899521,  0.00036082,  0.00070345],
        [ 0.01650935,  0.00070345,  0.00140253]]))
我们现在可以使用得到的参数向量作为起始向量来优化
f()
。由于
曲线拟合
是一种非线性最小二乘法,因此不需要参数优化
g()
参数优化
f()
,但希望它会很接近。协方差矩阵当然是非常不同的

In [78]: curve_fit(f, x, y, p0=curve_fit(g, x, 1/y)[0]) #Alternative Fit
Out[78]:
(array([ 18.0480446 ,  -0.22881647,   0.31200106]),
 array([[ 1.14928169,  0.03741604,  0.03897652],
        [ 0.03741604,  0.00128511,  0.00136315],
        [ 0.03897652,  0.00136315,  0.00145614]]))
结果比较:


现在结果很好。

好的,我明白你的意思。您知道如何解决此问题并拟合数据吗?谢谢,我使用了
Numpy 1.7.1
Scipy 0.13.0
,虽然显示了错误消息,但没有得到创建的绘图。你完全正确,函数非常糟糕,因此
pcov
发散。我希望
numpy
向我显示
diag(pcov)
的平方根,以获得偏差,但在这种情况下,这是不可能的,这就是为什么我甚至没有得到那些不好的拟合值的原因。我现在用二次多项式拟合数据。很高兴它能工作。但是,如果原始函数对您非常重要,您仍然可以通过使用优化
g()
得到的参数来拟合原始函数(请参见新编辑)。现在协方差矩阵看起来很好。