gpt4 book ai didi

python - Scipy 的 curve_fit 没有给出合理的结果

转载 作者:太空宇宙 更新时间:2023-11-03 14:24:35 25 4
gpt4 key购买 nike

我有一个简单的 x,y 数据集适合,至少乍一看是这样。问题是 scipy.optimize.curve_fit为其中一个拟合参数返回一个非常大的值,我不知道这在数学上是否正确,或者我拟合数据的方式是否有问题。

下图以蓝色显示了数据点和最佳拟合。使用的曲线(下面 MWE 中的 func)有四个参数 a, b, c, d 被拟合:

  • a 给出曲线达到一半最大值时的大约 x 值。
  • b 表示曲线稳定 处的x 值。此 func 值由 d 参数给出,即:func(b) = d
  • c 与原点处曲线的最大值有关:func(0) = c*constant + d
  • d 是曲线稳定的地方(图中黑线)。

b 参数是我遇到的问题(见问题结尾),它也是我对分配合理值感兴趣的参数.

enter image description here

MWE 显示正在拟合的函数和结果:

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

# Function to be fitted.
def func(x, a, b, c, d):
return c * (1 / np.sqrt(1 + (np.asarray(x) / a) ** 2) -
1 / np.sqrt(1 + (b / a) ** 2)) ** 2 + d

# Define x,y data.
x_list = [12.5, 37.5, 62.5, 87.5, 112.5, 137.5, 162.5, 187.5, 212.5, 237.5,
262.5, 287.5, 312.5, 337.5, 362.5, 387.5, 412.5, 437.5, 462.5, 487.5,
512.5]
y_list = [0.008, 0.0048, 0.0032, 0.00327, 0.0023, 0.00212, 0.00187,
0.00086, 0.00070, 0.00100, 0.00056, 0.00076, 0.00052, 0.00077, 0.00067,
0.00048, 0.00078, 0.00067, 0.00069, 0.00061, 0.00047]

# Initial guess for the 4 parameters.
guess = (50., 200., 80. / 10000., 6. / 10000.)

# Fit curve to x,y data.
f_prof, f_err = curve_fit(func, x_list, y_list, guess)

# Values for the a,b,c,d fitted parameters.
print f_prof

# Errors (standard deviations) for the fitted parameters.
print np.sqrt(f_err[0][0]), np.sqrt(f_err[1][1]), np.sqrt(f_err[2][2]),\
np.sqrt(f_err[3][3])

# Generate plot.
plt.scatter(x_list, y_list)
plt.plot(x_list, func(x_list, f_prof[0], f_prof[1], f_prof[2], f_prof[3]))
plt.hlines(y=f_prof[3], xmin=0., xmax=max(x_list))
plt.show()

我得到的结果是:

# a, b, c, d
52.74, 2.52e+09, 7.46e-03, 5.69e-04

# errors
11.52, 1.53e+16, 0.0028, 0.00042

b 参数有很大的值(value),也有很大的错误。通过查看图中绘制的数据,可以用肉眼估计 b 的值(即:x 值,其中数据集稳定) 应该在 x=300 左右。为什么我会得到如此大的 b 值及其错误?

最佳答案

我不知道这是有意还是错误,但在我看来,“b”与“a”和“d”密切相关,并且与自变量“x”没有“相互作用”。如果 b/a 足够大,您可以将 1/np.sqrt(1 + (b/a) ** 2)) ** 2 近似为 a/b,这样您的函数就变成了 c * function_of(x, a) - a/b + d

您的 'a' 和 'x' 值足够大,这变得非常接近 c*a/x - a/b + d。

正如 behzad.nouri 所指出的,与其他最小化器相比,curve_fit 可能稍微不稳定,并且总是最小化最小二乘法。但它确实返回完整的协方差矩阵,包括变量之间的相关性(f_err 的非对角线元素)。用这些!!

如果您确定“b”的值大约为 300,或者有兴趣在 fmin 和 levenberg-marquardt 算法之间轻松切换,您可能会发现 lmfit 包 (http://lmfit.github.io/lmfit-py/) 很有用。它允许您对参数设置界限,在拟合算法之间轻松切换,还可以对参数的置信区间进行更强力的探索。

关于python - Scipy 的 curve_fit 没有给出合理的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22581001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com