【问题标题】:Curve_fit not giving parameters to fit data correctlyCurve_fit 未提供参数以正确拟合数据
【发布时间】:2019-02-28 16:53:23
【问题描述】:

我有名为EV 的数据集,以及一个函数。该函数将 V 和 4 个参数作为输入。参数E0V0 应该是函数的最小值。

对于曲线拟合,我给出了参数的一些初始值。 E0V0 作为相应数据集的最小值给出。 B0 的理论值应该是 28,所以我给了它,我给了 B1 的随机值。

在曲线拟合之后,我尝试获取函数的最小值并找到E0V0。我得到的值似乎还可以。然后我绘制我的数据和定义的函数。 curve_fit 结果与我的数据不匹配。我认为问题出在配件部分,但我不确定。 EV 是我的实验结果,我知道它们没有任何关系。

代码如下:

from scipy.optimize import curve_fit
from scipy.optimize import fmin
import matplotlib.pylab as plt

V = np.array([9359.78033951, 10835.11571553, 12457.86763189, 14235.05592385, 16173.70042667, 18280.82097561, 20563.43740591, 23028.56955282, 25683.23725162, 28534.46033754, 31589.25864585])

E = np.array([12.73271364, 10.56261464, 8.21189843, 5.67853559, 3.18963332, 1.76136256,2.35816986,  5.01274293,  9.64990078, 16.22373202, 24.7102355])

E0 = min(E)
V0 = min(V)
print(V0,E0)

def func(V, E0, V0, B0, B1):
         return E0 + B0*V/B1 * (((V0/V)**B1)/(B1-1) + 1);

p0 = [E0, V0, 28, 100]    
params, param2 = curve_fit(func, V, E, p0)

V0_new = fmin(func, V0, args=(params[0], params[1], params[2], params[3]))
E0_new = func(V, params[0], V0_new, params[2], params[3])

for ii in range(len(V)):
plt.plot(V, E, '-k')
plt.plot(V[ii], func(V[ii], params[0], params[1], params[2], params[3]), 'or')

经过一些运行后,我开始收到此错误:

    ---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-14-ec759702af45> in <module>
      6 
      7 p0 = [E0, V0, 28, 100]
----> 8 params, param2 = curve_fit(func, V, E, p0)
      9 
     10 V0_new = fmin(func, V0, args=(params[0], params[1], params[2], params[3]))

/anaconda3/lib/python3.7/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
    753         cost = np.sum(infodict['fvec'] ** 2)
    754         if ier not in [1, 2, 3, 4]:
--> 755             raise RuntimeError("Optimal parameters not found: " + errmsg)
    756     else:
    757         # Rename maxfev (leastsq) to max_nfev (least_squares), if specified.

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1000.

现在我什至没有得到优化后的值。任何帮助表示赞赏。

编辑我以某种方式设法再次获得了这个数字。您会发现这些点与数据不符。

fig.png

Edit2我一直在运行脚本,有时我会收到这个错误,它不会给我任何参数...

Warning: Maximum number of function evaluations has been exceeded.

所以我需要解决这个最大评估问题,然后找到一种方法来获得正确拟合数据的正确参数。

【问题讨论】:

  • 我换数据集的时候还是一样的问题...

标签: python scipy


【解决方案1】:

curve_fit 中的数学运算最好在 numpy 数组而不是常规列表上进行。将代码的前几行更改为:

from scipy.optimize import curve_fit
from scipy.optimize import fmin
import numpy as np

V = np.array([9359.78033951, 10835.11571553, 12457.86763189, 14235.05592385, 16173.70042667, 18280.82097561, 20563.43740591, 23028.56955282, 25683.23725162, 28534.46033754, 31589.25864585])

E = np.array([12.73271364, 10.56261464, 8.21189843, 5.67853559, 3.18963332, 1.76136256,2.35816986,  5.01274293,  9.64990078, 16.22373202, 24.7102355])

您得到的错误是一系列函数调用fsolve -> _root_hybr 的结果,然后在循环达到最大数量时调用fortran minipack 例程。

我试图重现你的错误,但我得到的是:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-134dfaf77356> in <module>
     18 
     19 V0_new = fmin(func, V0, args=(params[0], params[1], params[2], params[3]))
---> 20 E0_new = func(V, params[0], V0_new, params[2], params[3])

<ipython-input-1-134dfaf77356> in func(V, E0, V0, B0, B1)
     12 
     13 def func(V, E0, V0, B0, B1):
---> 14          return E0 + B0*V/B1 * (((V0/V)**B1)/(B1-1) + 1);
     15 
     16 p0 = [E0, V0, 28, 100]

TypeError: can't multiply sequence by non-int of type 'numpy.float64'

将数组更改为 np.array 时不会出现此错误。

【讨论】:

  • 哦,抱歉,我实际上是从一个 txt 文件中获取数据,我只是将数据粘贴到这里,我的错……我会更正你所说的,但不幸的是,这不是错误。谢谢你的回答。
  • 当然。我只是认为根本原因可能是相同的,但根据系统/软件包版本等不同,错误的表现会有所不同。您是否使用 numpy 中的loadtxt 来生成输入?
  • 我使用的是 genfromtxt,但我只是编辑了问题,现在唯一的问题是我从 curve_fitting 得到的结果不适合我的数据。
  • 注意协方差数组(param2)元素都是inf。您从 B0 和 B1 的极端值开始,算法无法找到解决方案。更改: p0 = [E0, V0, -1, -1] 并且它可以工作
  • curve_fit 给了我值:E0, V0, B0, B1 = 4.37e+01, 1.87e+04, 4.87e-03, -1.215e+00
猜你喜欢
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 2021-01-31
  • 2017-03-17
  • 1970-01-01
  • 2016-08-03
  • 2021-11-05
  • 2012-11-02
相关资源
最近更新 更多