2

当我尝试将 beta 函数拟合到几个点时,我的 Python 代码出现了一个小问题。问题是要么解决方案不收敛(结果系数为nans),要么什么都不做(结果与我最初的猜测保持一致),或者它显然是合适的,但是拟合与数据不相似点。我一直在阅读有关 beta 函数和 about 的类似帖子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.]

然后我尝试gamma使用以下功能使它们适合它们curve_fit

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个点的事实,但是,如图所示...... 在此处输入图像描述

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

4

1 回答 1

1

您的实现是针对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 范围缩放也是拟合变量之一。但它也可以由您的问题决定。这完全取决于您的上下文。

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

于 2018-06-04T13:40:48.130 回答