广义双曲分布#

广义双曲分布定义为具有广义逆高斯分布作为混合分布的正态方差均值混合。 “双曲” 的特征是指对数概率分布的形状可以用双曲线来描述。 双曲分布有时被称为半厚尾分布,因为它们的概率密度下降速度比“次双曲” 分布(例如正态分布,其对数概率以二次方下降)慢,但比其他“极值” 分布(例如帕累托分布,其对数概率以对数下降)快)。

函数#

文献中存在不同的参数化;SciPy 实现了 Prause (1999) 中的“第四参数化”。

\begin{eqnarray*} f(x, p, a, b) & = & \frac{(a^2 - b^2)^{p/2}} {\sqrt{2\pi}a^{p-0.5} K_p\Big(\sqrt{a^2 - b^2}\Big)} e^{bx} \times \frac{K_{p - 1/2} (a \sqrt{1 + x^2})} {(\sqrt{1 + x^2})^{1/2 - p}} \end{eqnarray*}

对于

  • \(x, p \in ( - \infty; \infty)\)

  • \(|b| < a\) 如果 \(p \ge 0\)

  • \(|b| \le a\) 如果 \(p < 0\)

  • \(K_{p}(.)\) 表示第二类修正贝塞尔函数,阶数为 \(p\) (scipy.special.kn)

上面的概率密度是在“标准化”形式中定义的。 要移位和/或缩放分布,请使用 \(\text{loc}\)\(\text{scale}\) 参数。 具体来说,\(f(x, p, a, b, \text{loc}, \text{scale})\) 等同于 \(\frac{1}{\text{scale}}f(y, p, a, b)\),其中 \(y = \frac{1}{\text{scale}}(x - \text{loc})\).

此参数化源于 Barndorff (1978) 中的原始 \((\lambda, \alpha, \beta, \delta, \mu)\) 参数化,方法是设置

  • \(\lambda = p\)

  • \(\alpha = \frac{a}{\delta} = \frac{\hat{\alpha}}{\delta}\)

  • \(\beta = \frac{b}{\delta} = \frac{\hat{\beta}}{\delta}\)

  • \(\delta = \text{scale}\)

  • \(\mu = \text{location}\)

的随机变量 scipy.stats.genhyperbolic 可以从上述提到的正态方差均值混合中有效地采样,其中 scipy.stats.geninvgauss 参数化为 \(GIG\Big(p = p, b = \sqrt{\hat{\alpha}^2 - \hat{\beta}^2}, \text{loc} = \text{location}, \text{scale} = \frac{1}{\sqrt{\hat{\alpha}^2 - \hat{\beta}^2}}\Big)\),因此:\(GH(p, \hat{\alpha}, \hat{\beta}) = \hat{\beta} \cdot GIG + \sqrt{GIG} \cdot N(0,1)\)

“广义” 的特征表明,该分布是几个其他概率分布的超类,例如

  • \(f(p = -\nu/2, a = 0, b = 0, \text{loc} = 0, \text{scale} = \sqrt{\nu})\) 具有自由度为 \(\nu\) 的学生 t 分布 (scipy.stats.t)。

  • \(f(p = 1, a = \hat{\alpha}, b = \hat{\beta}, \text{loc} = \mu, \text{scale} = \delta)\) 具有双曲分布。

  • \(f(p = - 1/2, a = \hat{\alpha}, b = \hat{\beta}, \text{loc} = \mu, \text{scale} = \delta)\) 具有正态逆高斯分布 (scipy.stats.norminvgauss)。

  • \(f(p = 1, a = \delta, b = 0, loc = \mu, \text{scale} = \delta)\) 对于 \(\delta \rightarrow 0\) 具有拉普拉斯分布 (scipy.stats.laplace)。

示例#

了解参数如何影响分布的形状很有用。 虽然解释 \(b\) 的意义作为偏度相当简单,但理解 \(a\)\(p\) 之间的区别并不那么明显,因为两者都影响分布的峰度。 \(a\) 可以解释为概率密度衰减的速度(其中 \(a > 1\) 渐近衰减比 \(log_e\) 快,反之亦然)或 - 等效地 - 作为对数概率双曲线渐近线的斜率(其中 \(a > 1\) 衰减比 \(|1|\) 快,反之亦然)。 \(p\) 可以看作是概率密度分布肩部的宽度(其中 \(p < 1\) 导致窄肩,反之亦然)或 - 等效地 - 作为对数概率双曲线的形状,对于 \(p < 1\) 是凸的,否则是凹的。

import numpy as np
from matplotlib import pyplot as plt
from scipy import stats

p, a, b, loc, scale = 1, 1, 0, 0, 1
x = np.linspace(-10, 10, 100)

# plot GH for different values of p
plt.figure(0)
plt.title("Generalized Hyperbolic | -10 < p < 10")
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        label = 'GH(p=1, a=1, b=0, loc=0, scale=1)')
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'red', alpha = 0.5, label='GH(p>1, a=1, b=0, loc=0, scale=1)')
[plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'red', alpha = 0.1) for p in np.linspace(1, 10, 10)]
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'blue', alpha = 0.5, label='GH(p<1, a=1, b=0, loc=0, scale=1)')
[plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'blue', alpha = 0.1) for p in np.linspace(-10, 1, 10)]
plt.plot(x, stats.norm.pdf(x, loc, scale), label = 'N(loc=0, scale=1)')
plt.plot(x, stats.laplace.pdf(x, loc, scale), label = 'Laplace(loc=0, scale=1)')
plt.plot(x, stats.pareto.pdf(x+1, 1, loc, scale), label = 'Pareto(a=1, loc=0, scale=1)')
plt.ylim(1e-15, 1e2)
plt.yscale('log')
plt.legend(bbox_to_anchor=(1.1, 1))
plt.subplots_adjust(right=0.5)

# plot GH for different values of a
plt.figure(1)
plt.title("Generalized Hyperbolic | 0 < a < 10")
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        label = 'GH(p=1, a=1, b=0, loc=0, scale=1)')
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'blue', alpha = 0.5, label='GH(p=1, a>1, b=0, loc=0, scale=1)')
[plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'blue', alpha = 0.1) for a in np.linspace(1, 10, 10)]
plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'red', alpha = 0.5, label='GH(p=1, 0<a<1, b=0, loc=0, scale=1)')
[plt.plot(x, stats.genhyperbolic.pdf(x, p, a, b, loc, scale),
        color = 'red', alpha = 0.1) for a in np.linspace(0, 1, 10)]
plt.plot(x, stats.norm.pdf(x, loc, scale),  label = 'N(loc=0, scale=1)')
plt.plot(x, stats.laplace.pdf(x, loc, scale), label = 'Laplace(loc=0, scale=1)')
plt.plot(x, stats.pareto.pdf(x+1, 1, loc, scale), label = 'Pareto(a=1, loc=0, scale=1)')
plt.ylim(1e-15, 1e2)
plt.yscale('log')
plt.legend(bbox_to_anchor=(1.1, 1))
plt.subplots_adjust(right=0.5)

plt.show()

参考文献#

实现:scipy.stats.genhyperbolic