Python-curve_fit和lmfit无法正常运行(错误拟合)

问题描述 投票:1回答:1

我正在尝试重现已知的拟合结果(在日记纸中报告):对数据应用弯曲幂律模型(BPL)。从下面的图A中可以看出,通过使用具有最佳最佳拟合参数的BPL,我能够重现结果。 (我已经有了数据,并且知道BPL功能和最佳拟合参数:0.03、2.3e-4、1.1、2.2、9.2e-3)。您可以使用下面的简短脚本轻松地绘制它。

import scipy.optimize as optimize
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from lmfit import Model

# the data can be found at the end of this post.
xx, yy = genfromtxt('the_data', unpack=True)

# the BPL function
def bendp(x, A, x_bend, allo, alhi, c):
  numer = A * x**-allo
  denom = 1 + (x/x_bend)**(alhi-allo)
  out = (numer/denom) + c
  return out


# The data in log scale (because this should be done in log scale)
plt.loglog(xx, yy, linewidth=0, marker='o', markersize=6)
# Test the best-fit parameters: A=0.03, x_bend=2.3e-4, allo=1.1, alhi=2.2, c=9.2e-3
plt.loglog(xx, bendp(xx, 0.03, 2.3e-4, 1.1, 2.2, 9.2e-3), linewidth=6)

Both axis: log-log scale

但是,当我使用curve_fit或lmfit模块时,我无法自行推导最佳拟合BPL参数。

# (continues from the above script)

# case-A
pp1, cv1 = optimize.curve_fit(bendp, xx, yy, maxfev=5000, p0=[0.01, 1e-2, 1., 2., 1e-2])
# case-B
pp2, cv2 = optimize.curve_fit(bendp, xx, yy, maxfev=5000, p0=[0.01, 1e-4, 1., 2., 1e-3])

# Check an example of the wrong curve_fits.
plt.loglog(xx, bendp(xx, *pp1), linewidth=10, alpha=0.7)

# Test with lmfit
mod = Model(bendp)
para = mod.make_params(A = 0.01, x_bend=1e-2, allo=1., alhi=2., c=1e-2)
result = mod.fit(yy, para, x=xx, nan_policy='omit')

# Check an example of the wrong lmfits.
plt.loglog(xx, result.best_fit, 'r', linewidth=5)

wrong

案例A返回,

OptimizeWarning: Covariance of the parameters could not be estimated(如果我省略了几个初始数据点,则拟合返回一些不错的结果,但仍与已知的最佳拟合结果有所不同)。编辑:现在,这次我刚刚发现了新的其他错误消息。(1)RuntimeWarning: overflow encountered in power(2)RuntimeWarning: invalid value encountered in power

案例B(初始猜测更接近最佳拟合参数),

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 5000.如果我将maxfev设置得更高,以考虑到此错误消息,则拟合将起作用,但会返回错误的结果(与最佳拟合结果相比,拟合度非常错误)。

我还尝试使用“ lmfit”来推导最佳拟合参数。但是,结果也是不正确的(与Plot-B中的错误拟合相同)。

所以,有人可以帮助我弄清楚为什么我不能重新推导最佳拟合参数吗?

ps.s。数据可以在这里找到:https://gofile.io/?c=t2tNbT

谢谢!

python curve-fitting covariance power-law loglog
1个回答
2
投票

我评论过:

由于您将数据绘制在对数-对数图上,您是否也适合对数(y)和对数(x)?由于您的y数据相差5或6阶大小,如果您不适合对数空间,则仅那些3或4个数据y值最高的点将很重要。

显然,这有点暗示。所以我会更直接:如果您要在对数空间中绘图,请在对数空间中进行拟合。

但是,您的模型很容易从negative**fraction和NaN生成复数,这无疑会导致所有拟合问题。始终打印出最适合的参数和协方差矩阵。

因此,您可能需要对参数施加限制(当然,我不知道您的模型是正确的还是实际上是您认为使用的“正确答案”的含义)。也许从这样的东西开始:

import matplotlib.pyplot as plt
from lmfit import Model
import numpy as np

# the data can be found at the end of this post.
xx, yy = np.genfromtxt('the_data', unpack=True)

# the BPL function
def bendp(x, A, x_bend, allo, alhi, c):
    numer = A * x**-allo
    denom = 1 + (x/x_bend)**(alhi-allo)
    out = (numer/denom) + c
    return  np.log(out)       ## <- TAKE THE LOG


mod = Model(bendp)
para = mod.make_params(A = 0.01, x_bend=1e-2, allo=1., alhi=2., c=1e-2)

# Note: your model is very sensitive # make sure A, x_bend, alhi, and c cannot be negative
para['A'].min = 0
para['x_bend'].min = 0
para['alhi'].min = 0
para['alhi'].max = 3
para['c'].min = 0


result = mod.fit(np.log(yy), para, x=xx) ## <- FIT THE LOG

print(result.fit_report())

plt.loglog(xx, yy, linewidth=0, marker='o', markersize=6)
plt.loglog(xx, np.exp(result.best_fit), 'r', linewidth=5)
plt.show()

希望有帮助...

© www.soinside.com 2019 - 2024. All rights reserved.