我在将 GEV 的右尾部拟合到我的实际分布时遇到问题。当我拟合曲线的选定部分时,我得到了错误的参数,因为它忽略了我想要只是尾巴的事实。我决定手动安装它,但它既不科学,也不可重现。对于我的问题,什么是明智的解决方案?
这是我的代码和情节,以及执行演示的照片。
from scipy.stats import genextreme
y_vals = df_edit[df_edit.index > 50]
plt.plot(y_vals.values)
c = -0.15
loc = 510
scale = 6.3
x_values_gev = np.linspace(loc - 150, loc + 150, 1000)
pdf_gev = genextreme.pdf(x_values_gev, c, loc=loc, scale=scale)
peak_y = np.max(pdf_gev)
scale_adjusted = scale * (0.2 / peak_y)
pdf_gev_adjusted = genextreme.pdf(x_values_gev, c, loc=loc, scale=scale_adjusted)
plt.plot(x_values_gev, pdf_gev_adjusted, label='GEV Density')
plt.plot(y_vals.rnd)
让我们构建一个 MCVE 来展示如何从分位数间选择回归。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats, optimize
首先,我们假设我们有一些法律(这是您的问题缺乏细节的地方,请随时更新您的问题以更好地描述该法律是如何发生的):
law = stats.skewnorm(a=-2., loc=550., scale=40.)
我们想要从分位数间选择中回归 GEV,首先我们构建临时模型:
def model(x, c, loc, scale):
return stats.genextreme(c=c, loc=loc, scale=scale).pdf(x)
然后我们创建一个函数来选择分位数并拟合模型:
def resample_and_fit(law, model, qmin=0.02, qmax=0.05, resolution=200):
xmin = law.ppf(qmin)
xmax = law.ppf(qmax)
xsample = np.linspace(xmin, xmax, resolution)
ysample = law.pdf(xsample)
popt, pcov = optimize.curve_fit(model, xsample, ysample, p0=[1., 2*law.mean(), law.std()])
return xsample, ysample, popt, pcov
现在我们可以将此函数应用于分位数间选择:
xlin = np.linspace(350., 650., 1000)
xsample1, ysample1, popt1, pcov1 = resample_and_fit(law, model, qmin=0.02, qmax=0.05)
yhat1 = model(xlin, *popt1)
xsample2, ysample2, popt2, pcov2 = resample_and_fit(law, model, qmin=0.95, qmax=0.98)
yhat2 = model(xlin, *popt2)
渲染如下: