Обобщённое гиперболическое распределение#

Обобщенное гиперболическое распределение определяется как нормальная смесь дисперсии-среднего с обобщенным обратным гауссовским распределением в качестве смешивающего распределения. Характеристика «гиперболическое» относится к тому факту, что форма логарифма распределения вероятностей может быть описана как гипербола. Гиперболические распределения иногда называют полу-тяжелохвостыми, потому что их плотность вероятности убывает медленнее, чем «суб-гиперболические» распределения (например, нормальное распределение, чей логарифм вероятности убывает квадратично), но быстрее, чем другие распределения «экстремальных значений» (например, pareto распределение, чья логарифмическая вероятность уменьшается логарифмически).

Функции#

В литературе существуют различные параметризации; SciPy реализует «4-ю параметризацию» из 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\) if \(p \ge 0\)

  • \(|b| \le a\) if \(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})\).

Эта параметризация происходит из оригинального \((\lambda, \alpha, \beta, \delta, \mu)\) параметризация в Barndorff (1978) путем установки:

  • \(\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})\) имеет распределение Стьюдента (scipy.stats.t) с \(\nu\) степени свободы.

  • \(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)\) имеет распределение Лапласа (scipy.stats.laplace) для \(\delta \rightarrow 0\)

Примеры#

Полезно понимать, как параметры влияют на форму распределения. Хотя довольно просто интерпретировать смысл \(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)
[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