scipy curve_fit错误:除以零 [英] scipy curve_fit error: divide by zero encountered

查看:123
本文介绍了scipy curve_fit错误:除以零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间以来,我一直在尝试使用scipy.optimize.curve_fit使函数适合某些数据:

I've been trying to fit a function to some data for a while using scipy.optimize.curve_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)

也许有人能帮助我避免吗?
任何帮助将不胜感激。欢呼!

Maybe someone can help me to avoid it? Any help would be much appreciated. Cheers!

推荐答案

好的,两个有用的技巧。

Alright, two helpful tricks.

第一,将您的 x 中的 0 替换为非常小的数字,例如 1e-8 (别笑, R 中确实有一个核心程序,实际上是用的名字写的。,人们一直在使用它。)
实际上,我根本没有得到您的 RuntimeWarning 。我正在运行 scipy 0.12.0 numpy 1.7.1 。也许这取决于版本。

1st, replace 0 in your x with some really small number, such as 1e-8 (don't laugh, there is a core package in R actually does this, written by his name shall not be spoken and people use it all the time.) Actually I didn't get your RuntimeWarning at all. I am running scipy 0.12.0 and numpy 1.7.1. Maybe this is version dependent.

但是我们会遇到非常糟糕的情况:

But we will get a very bad fit:

In [41]: popt, pcov
Out[41]: (array([  3.90107143e+01,  -3.08698757e+07,  -1.52971609e+02]), inf)

因此,技巧2不是优化 f 函数,而是定义 g 函数:

So, trick 2, instead of optimizing f function, we define a g function:

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()的起始向量。由于 curve_fit 是非线性最小二乘法,因此参数优化 g()不必参数优化 f(),但希望它将关闭。当然,协方差矩阵是非常不同的。

We can now use the resulting parameter vector as starting vector to optimize f(). As curve_fit is a nonlinear least square method, parameter optimizes g() is not necessary the parameter optimizes f(), but hopefully it will be close. The covariance matrices are very different of course.

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]]))

结果比较:

现在效果很好。

这篇关于scipy curve_fit错误:除以零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆