如何用scipy函数拟合曲线并限制参数范围

goqiplq2  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(154)

我尝试使用scipy.genextreme.fit将GEV拟合到一些数据,例如。

from scipy.stats import genextreme as gev
import numpy as np

# Generate some random data
data = np.random.normal(size=1000)

# Fit the data to a GEV distribution
params = gev.fit(data)

print(params)

如果我想拟合GEV并保持形状参数的值固定(例如0.5),我只需要做:

params = gev.fit(data,f0=0.5)

我实际上想要的是拟合GEV,并将形状参数的值保持在一定范围内(例如在-0.5和0.5之间)。我试过:

params = gev.fit(data,f0=[-0.5,0.5]) #Does not work

scipy可以指定拟合参数的范围吗?

lrpiutwd

lrpiutwd1#

我已经找到了一些关于如何使用scipy.optimize.minimize来做我想做的事情的答案
我从GEV生成随机数据,并使用“www.example.com”拟合它们scipy.stats.genextreme.fit,并比较我从scipy.optimize.minimize获得的4个不同边界的结果:

  • Bounds = unspecified(应等于None)
  • 边界=无(显式完成)
  • 边界设置为-inf到inf(实际上应该是无界的)
  • 边界设置为我想要的实际值(shape:[-0.5,0.5],loc:[-inf,inf],scale[0,inf]
import warnings
import numpy                                 as np
from   scipy.stats    import genextreme      as gev
from   scipy.optimize import minimize,Bounds
warnings.filterwarnings("ignore")

# Function to be minimized
def fun(x):
    return -np.sum(gev.logpdf(data, x[0], loc=x[1], scale=x[2]))

# Generate a random sample from a GEV distribution
c     = 0.25
loc   = 1
scale = 2
data = gev.rvs(c, loc=loc, scale=scale, size=10000)

################################
# Fitting the curve using "fit"#
################################
C,LOC,SCALE = gev.fit(data, method='mle')
print('%12s'%'Using fit:','[%.8f,%.8f,%.8f]'%(C,LOC,SCALE))

############################################################
# Fitting the curve using "minimize" (and different bounds)#
############################################################
# Define the initial guess for the parameters
x0 = np.array([-0, np.mean(data), 1 ])

# No specifying the  bounds (default should be None if I understood correctly)
res = minimize(fun,x0)
print('%12s'%'Unspecified:',res.x)

# Explicitely using None
bounds=None
res = minimize(fun, x0, bounds=bounds)
print('%12s'%'None:',res.x)

# Setting -infinity and +infinity (~ no bounds?)
bounds = Bounds([-np.inf,-np.inf,-np.inf],[np.inf,np.inf,np.inf],True)
res = minimize(fun, x0, bounds=bounds)
print('%12s'%'-inf to inf:',res.x)

# Setting bound on the shape parameter c:[0.5,0.5])
bounds = Bounds([-0.5,-np.inf,0],[0.5,np.inf,np.inf],True)
res = minimize(fun, x0, bounds=bounds)
print('%12s'%'My choice:',res.x)

输出如下所示:

Using fit: [0.24802565,0.99147038,1.99752719]
Unspecified: [0.24803505 0.99151589 1.99750206]
       None: [0.24803505 0.99151589 1.99750206]
-inf to inf: [0.         1.74141644 1.        ]
  My choice: [0.15475374 1.42297545 1.97813723]

因此,当Bounds未指定或设置为None时,我们得到的结果非常接近预期值(从fit获得),但在其他情况下(参数在指定范围内,但它们没有预期值)失败。为什么?
最后一点,如果我使用了一个负值的形状参数,例如:c=-0.25,“我的选择”现在产生与Unspecified和None相同的值:

Using fit: [-0.24485102  1.01219881  2.01972737]
Unspecified: [-0.24486353  1.01221328  2.01976429]
       None: [-0.24486353  1.01221328  2.01976429]
-inf to inf: [0.           2.81041857  1.        ]
  My choice: [-0.24486356  1.01221433  2.01976554]

相关问题