python - 为什么 curve_fit 对于 beta 函数拟合不收敛?

标签 python curve-fitting data-fitting model-fitting function-fitting

当我尝试将 beta 函数拟合到几个点时,我的 Python 代码出现了一个小问题。问题是解决方案不收敛(结果系数为nans),或者什么都不做(结果与我最初的猜测相同),或者它显然适合,但随后拟合与数据点完全不同。 我一直在阅读关于 beta 函数和关于 curve_fit 的类似帖子,因为这两个问题都在 stackoverflow 文献中讨论过,但我一直无法找到解决我所遇到的具体问题的方法,所以我想知道您能否给我一些想法。

我有一组点:

x = np.array([0.1, 0.3, 0.5, 0.7, 0.9, 1.1])
y = np.array([0.45112234, 0.56934313, 0.3996803 , 0.28982859, 0.19682153,
   0.]

然后我尝试使用 curve_fit 将它们与 gamma 函数拟合,如下所示:

from scipy.optimize import curve_fit
from scipy.special import gamma as gamma
def betafunc(x,a,b,cst):
    return cst*gamma(a+b) * (x**(a-1)) * ((1-x)**(b-1))  / ( gamma(a)*gamma(b) )
popt2,pcov2 = curve_fit(betafunc,x,y,p0=(0.5,1.5,0.5))

这就是我的问题所在,因为根据我最初的猜测,我得到 popt2=[nan,nan,nan]popt2=p0,或一些在绘制时根本不模拟数据的值。

我也知道 beta 函数适用于 0 < x < 1,所以我尝试重新缩放点,或者只删除数据的最后一个点,但这也不太好。向曲线拟合添加误差或如前所述,更改初始参数也无济于事。 我还认为这可能只是因为我有 3 个自由参数和 4 或 5 个点,但是,如图所示... enter image description here ,

...我已经安装了另一个配置文件(也使用三个免费参数),并且没有问题,所以我不明白为什么这个其他 beta 配置文件不起作用。非常感谢任何指导!

最佳答案

您的实现是针对 beta 分布的概率密度函数(而不是 beta 函数)。它在区间 0 <= x <= 1 内定义。因此,您的独立数据(x 坐标)必须完全在此区间内。您如何确保这一点取决于您尝试做的事情的更大背景。可能的方法包括修剪或映射到间隔的某些部分。

按照您的示例,以下(修剪)运行没有错误:

import numpy as np
from scipy.optimize import curve_fit
from scipy.special import gamma as gamma
def betafunc(x,a,b,cst):
    return cst*gamma(a+b) * (x**(a-1)) * ((1-x)**(b-1))  / ( gamma(a)*gamma(b) )

x = np.array( [0.1, 0.3, 0.5, 0.7, 0.9, 1.1])
y = np.array( [0.45112234, 0.56934313, 0.3996803 , 0.28982859, 0.19682153, 0.] )


popt2,pcov2 = curve_fit(betafunc,x[:-1],y[:-1],p0=(0.5,1.5,0.5))

print popt2
print pcov2

并产生结果:

[ 1.22624727  1.74192827  0.37084996]
[[ 0.03758865  0.04888083 -0.00132468]
 [ 0.04888083  0.09142608 -0.00309165]
 [-0.00132468 -0.00309165  0.00094766]]

这也(重新缩放 x)运行没有错误:

import numpy as np
from scipy.optimize import curve_fit
from scipy.special import gamma as gamma
def betafunc(x,a,b,cst,scale):
    x = x / scale
    return cst*gamma(a+b) * (x**(a-1)) * ((1-x)**(b-1))  / ( gamma(a)*gamma(b) )

x = np.array( [0.1, 0.3, 0.5, 0.7, 0.9, 1.1])
y = np.array( [0.45112234, 0.56934313, 0.3996803 , 0.28982859, 0.19682153, 0.] )

popt2,pcov2 = curve_fit(betafunc,x,y,p0=(0.5,1.5,0.5,1.1))

print popt2
print pcov2

并产生结果:

[ 1.37100253  2.36832069  0.32337175  1.16052822]
[[ 0.04972377  0.15943756 -0.00792804  0.02550767]
 [ 0.15943756  0.71001918 -0.04180131  0.14426687]
 [-0.00792804 -0.04180131  0.00312037 -0.00983075]
 [ 0.02550767  0.14426687 -0.00983075  0.0373759 ]]

请注意,在第二个示例中,x 范围缩放也是拟合变量之一。但它也可以由您的问题决定。这完全取决于您的上下文。

同样,哪种方法适合您使用,取决于数据来源的详细信息。您选择的方法应该在您尝试拟合的数据和您希望实现的目标的上下文中具有物理意义。

关于python - 为什么 curve_fit 对于 beta 函数拟合不收敛?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50680350/

相关文章:

python - 如何使用 scipy.optimize.curvefit 修复 PSD 拟合不良

python - 优化三对角系数矩阵的 A*x = B 解

python - sklearn 中评估指标(精度等)的意外行为

python - 如何使用 Django 从磁盘返回 Excel 作为 HttpResponse

python - SciPy leastsq 适合正弦波失败

python - 如何在 Python 中执行局部多项式拟合

python - 处理报纸中的文章异常

python - 如何使用一些常量片段在 Python 中进行分段线性拟合?

variables - gnuplot - 获取拟合参数错误,获取拟合输出值作为变量,将变量打印到屏幕

python - 用Python中的复杂函数拟合数据