scipy.stats.vonmises_fisher#

scipy.stats.vonmises_fisher = object>[источник]#

Переменная фон Мизеса-Фишера.

The mu ключевое слово задает вектор среднего направления. Параметр kappa ключевое слово указывает параметр концентрации.

Параметры:
muarray_like

Среднее направление распределения. Должно быть одномерным единичным вектором нормы 1.

kappafloat

Параметр концентрации. Должен быть положительным.

seed{None, int, np.random.RandomState, np.random.Generator}, опционально

Используется для генерации случайных величин. Если seed является None, RandomState используется синглтон. Если seed является int, новый RandomState используется экземпляр, инициализированный с seed. Если seed уже является RandomState или Generator экземпляр, то этот объект используется. По умолчанию None.

Методы

pdf(x, mu=None, kappa=1)

Функция плотности вероятности.

logpdf(x, mu=None, kappa=1)

Логарифм функции плотности вероятности.

rvs(mu=None, kappa=1, size=1, random_state=None)

Генерировать случайные выборки из распределения фон Мизеса-Фишера.

entropy(mu=None, kappa=1)

Вычислить дифференциальную энтропию распределения фон Мизеса-Фишера.

fit(data)

Подогнать распределение фон Мизеса-Фишера к данным.

Смотрите также

scipy.stats.vonmises

Распределение Фишера фон Мизеса в 2D на окружности

uniform_direction

равномерное распределение на поверхности гиперсферы

Примечания

Распределение фон Мизеса-Фишера — это направленное распределение на поверхности единичной гиперсферы. Функция плотности вероятности единичного вектора \(\mathbf{x}\) является

\[f(\mathbf{x}) = \frac{\kappa^{d/2-1}}{(2\pi)^{d/2}I_{d/2-1}(\kappa)} \exp\left(\kappa \mathbf{\mu}^T\mathbf{x}\right),\]

где \(\mathbf{\mu}\) является средним направлением, \(\kappa\) параметр концентрации, \(d\) размерность и \(I\) модифицированная функция Бесселя первого рода. Как \(\mu\) представляет направление, оно должно быть единичным вектором или, другими словами, точкой на гиперсфере: \(\mathbf{\mu}\in S^{d-1}\). \(\kappa\) является параметром концентрации, что означает, что он должен быть положительным (\(\kappa>0\)) и что распределение становится более узким с увеличением \(\kappa\). В этом смысле обратное значение \(1/\kappa\) напоминает параметр дисперсии нормального распределения.

Распределение фон Мизеса-Фишера часто служит аналогом нормального распределения на сфере. Интуитивно, для единичных векторов полезной мерой расстояния является угол \(\alpha\) между ними. Это именно то, что делает скалярное произведение \(\mathbf{\mu}^T\mathbf{x}=\cos(\alpha)\) в функции плотности вероятности распределения Фишера-фон Мизеса описывает: угол между средним направлением \(\mathbf{\mu}\) и вектор \(\mathbf{x}\). Чем больше угол между ними, тем меньше вероятность наблюдать \(\mathbf{x}\) для этого конкретного среднего направления \(\mathbf{\mu}\).

В размерностях 2 и 3 используются специализированные алгоритмы для быстрой выборки [2], [3]. Для размерностей 4 и выше алгоритм отбраковки выборки, описанный в [4] используется. Эта реализация частично основана на пакете geomstats [5], [6].

Добавлено в версии 1.11.

Ссылки

[1]

Распределение фон Мизеса-Фишера, Википедия, https://en.wikipedia.org/wiki/Von_Mises%E2%80%93Fisher_distribution

[2]

Mardia, K., и Jupp, P. Направленная статистика. Wiley, 2000.

[3]

J. Wenzel. Численно устойчивая выборка распределения Фишера фон Мизеса на S2. https://www.mitsuba-renderer.org/~wenzel/files/vmf.pdf

[4]

Вуд, А. Моделирование распределения фон Мизеса-Фишера. Communications in statistics-simulation and computation 23, 1 (1994), 157-164. https://doi.org/10.1080/03610919408813161

[5]

geomstats, Github. MIT License. Accessed: 06.01.2023. geomstats/geomstats

[6]

Miolane, N. et al. Geomstats: Python-пакет для римановой геометрии в машинном обучении. Journal of Machine Learning Research 21 (2020). http://jmlr.org/papers/v21/19-027.html

Примеры

Визуализация плотности вероятности

Постройте плотность вероятности в трёх измерениях для увеличивающегося параметра концентрации. Плотность вычисляется с помощью pdf метод.

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.stats import vonmises_fisher
>>> from matplotlib.colors import Normalize
>>> n_grid = 100
>>> u = np.linspace(0, np.pi, n_grid)
>>> v = np.linspace(0, 2 * np.pi, n_grid)
>>> u_grid, v_grid = np.meshgrid(u, v)
>>> vertices = np.stack([np.cos(v_grid) * np.sin(u_grid),
...                      np.sin(v_grid) * np.sin(u_grid),
...                      np.cos(u_grid)],
...                     axis=2)
>>> x = np.outer(np.cos(v), np.sin(u))
>>> y = np.outer(np.sin(v), np.sin(u))
>>> z = np.outer(np.ones_like(u), np.cos(u))
>>> def plot_vmf_density(ax, x, y, z, vertices, mu, kappa):
...     vmf = vonmises_fisher(mu, kappa)
...     pdf_values = vmf.pdf(vertices)
...     pdfnorm = Normalize(vmin=pdf_values.min(), vmax=pdf_values.max())
...     ax.plot_surface(x, y, z, rstride=1, cstride=1,
...                     facecolors=plt.cm.viridis(pdfnorm(pdf_values)),
...                     linewidth=0)
...     ax.set_aspect('equal')
...     ax.view_init(azim=-130, elev=0)
...     ax.axis('off')
...     ax.set_title(rf"$\kappa={kappa}$")
>>> fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9, 4),
...                          subplot_kw={"projection": "3d"})
>>> left, middle, right = axes
>>> mu = np.array([-np.sqrt(0.5), -np.sqrt(0.5), 0])
>>> plot_vmf_density(left, x, y, z, vertices, mu, 5)
>>> plot_vmf_density(middle, x, y, z, vertices, mu, 20)
>>> plot_vmf_density(right, x, y, z, vertices, mu, 100)
>>> plt.subplots_adjust(top=1, bottom=0.0, left=0.0, right=1.0, wspace=0.)
>>> plt.show()
../../_images/scipy-stats-vonmises_fisher-1_00_00.png

При увеличении параметра концентрации точки становятся более скученными вокруг среднего направления.

Выборка

Извлечь 5 выборок из распределения, используя rvs метод, приводящий к массиву 5x3.

>>> rng = np.random.default_rng()
>>> mu = np.array([0, 0, 1])
>>> samples = vonmises_fisher(mu, 20).rvs(5, random_state=rng)
>>> samples
array([[ 0.3884594 , -0.32482588,  0.86231516],
       [ 0.00611366, -0.09878289,  0.99509023],
       [-0.04154772, -0.01637135,  0.99900239],
       [-0.14613735,  0.12553507,  0.98126695],
       [-0.04429884, -0.23474054,  0.97104814]])

Эти выборки являются единичными векторами на сфере \(S^2\). Для проверки вычислим их евклидовы нормы:

>>> np.linalg.norm(samples, axis=1)
array([1., 1., 1., 1., 1.])

Постройте 20 наблюдений, взятых из распределения фон Мизеса-Фишера для возрастающего параметра концентрации \(\kappa\). Красная точка выделяет среднее направление \(\mu\).

>>> def plot_vmf_samples(ax, x, y, z, mu, kappa):
...     vmf = vonmises_fisher(mu, kappa)
...     samples = vmf.rvs(20)
...     ax.plot_surface(x, y, z, rstride=1, cstride=1, linewidth=0,
...                     alpha=0.2)
...     ax.scatter(samples[:, 0], samples[:, 1], samples[:, 2], c='k', s=5)
...     ax.scatter(mu[0], mu[1], mu[2], c='r', s=30)
...     ax.set_aspect('equal')
...     ax.view_init(azim=-130, elev=0)
...     ax.axis('off')
...     ax.set_title(rf"$\kappa={kappa}$")
>>> mu = np.array([-np.sqrt(0.5), -np.sqrt(0.5), 0])
>>> fig, axes = plt.subplots(nrows=1, ncols=3,
...                          subplot_kw={"projection": "3d"},
...                          figsize=(9, 4))
>>> left, middle, right = axes
>>> plot_vmf_samples(left, x, y, z, mu, 5)
>>> plot_vmf_samples(middle, x, y, z, mu, 20)
>>> plot_vmf_samples(right, x, y, z, mu, 100)
>>> plt.subplots_adjust(top=1, bottom=0.0, left=0.0,
...                     right=1.0, wspace=0.)
>>> plt.show()
../../_images/scipy-stats-vonmises_fisher-1_01_00.png

Графики показывают, что с увеличением концентрации \(\kappa\) результирующие выборки центрированы ближе к среднему направлению.

Подбор параметров распределения

Распределение может быть подогнано к данным с использованием fit метод, возвращающий оцененные параметры. В качестве простого примера подгоним распределение к выборкам, взятым из известного распределения фон Мизеса-Фишера.

>>> mu, kappa = np.array([0, 0, 1]), 20
>>> samples = vonmises_fisher(mu, kappa).rvs(1000, random_state=rng)
>>> mu_fit, kappa_fit = vonmises_fisher.fit(samples)
>>> mu_fit, kappa_fit
(array([0.01126519, 0.01044501, 0.99988199]), 19.306398751730995)

Мы видим, что оценённые параметры mu_fit и kappa_fit очень близки к истинным параметрам.