Вибірка з розподілу фон Мізеса-Фішера в Python?


14

Я шукаю простий спосіб вибірки з багатовимірного розподілу фон Мізеса-Фішера в Python. Я переглянув модуль статистики в scipy та модуль numpy, але лише знайшов однозначний розподіл фон Мізеса. Чи доступний код? Я ще не знайшов.

Мабуть, Вуд (1994) розробив алгоритм вибірки з розподілу vMF за цим посиланням , але я не можу знайти папір.

- edit Для точності мене цікавить алгоритм, який важко знайти в літературі (більшість робіт зосереджена на ). Насіннєву статтю (Wood, 1994), наскільки мені відомо, не можна знайти безкоштовно.S2


1
Вхід до scipy.stats.vonmisesможе бути схожим на масив, тому ви можете вказати розподіл як array. Дивіться цей приклад
правами було проведено

Дякую за вашу відповідь. Але, схоже, це скоріше продукт 1-D von Mises, ніж справжній nD von Mises-Fisher : K = vonmises.pdf([x,x], kappa=[[1],[10]]). 2-D vMF повинен мати лише один реальний як параметр. Ви згодні? κ
мік

Я шукаю алгоритм VM * спочатку в моделюванні розподілу фон Мізеса Фішера (Wood, 1994). Хтось?
мік

3
Я знайшов відповіді в цій темі тут справді корисними. Я надав трохи очищену функцію утиліти, щоб зробити це як частина цього пакета: https://github.com/clara-labs/spherecluster/blob/develop/spherecluster/util.py , для тих, хто все ще хоче генерувати це дані.
Яська

Відповіді:


11

Нарешті я це зрозумів. Ось моя відповідь.

Нарешті я поклав руки на спрямовану статистику (Mardia і Jupp, 1999) та на алгоритм вибору вибірки Ульріха-Вуда. Я розміщую тут те, що я зрозумів з нього, тобто мій код (в Python).

Схема вибірки відхилень:

def rW(n, kappa, m):
    dim = m-1
    b = dim / (np.sqrt(4*kappa*kappa + dim*dim) + 2*kappa)
    x = (1-b) / (1+b)
    c = kappa*x + dim*np.log(1-x*x)

    y = []
    for i in range(0,n):
        done = False
        while not done:
            z = sc.stats.beta.rvs(dim/2,dim/2)
            w = (1 - (1+b)*z) / (1 - (1-b)*z)
            u = sc.stats.uniform.rvs()
            if kappa*w + dim*np.log(1-x*w) - c >= np.log(u):
                done = True
        y.append(w)
    return y

Тоді бажана вибірка - , де є результатом схеми відбору вибірок відхилення, а рівномірно вибирається за гіперсферою.v1-ш2+шмкшv

def rvMF(n,theta):
    dim = len(theta)
    kappa = np.linalg.norm(theta)
    mu = theta / kappa

    result = []
    for sample in range(0,n):
        w = rW(n, kappa, dim)
        v = np.random.randn(dim)
        v = v / np.linalg.norm(v)

        result.append(np.sqrt(1-w**2)*v + w*mu)

    return result

І для ефективного вибірки цього коду, ось приклад:

import numpy as np
import scipy as sc
import scipy.stats

n = 10
kappa = 100000
direction = np.array([1,-1,1])
direction = direction / np.linalg.norm(direction)

res_sampling = rvMF(n, kappa * direction)

3
1
whuber

4

.

vSp-2мкvмкv1-ш2+шмк

import scipy.linalg as la
def sample_tangent_unit(mu):
    mat = np.matrix(mu)

    if mat.shape[1]>mat.shape[0]:
        mat = mat.T

    U,_,_ = la.svd(mat)
    nu = np.matrix(np.random.randn(mat.shape[0])).T
    x = np.dot(U[:,1:],nu[1:,:])
    return x/la.norm(x)

і замінити

v = np.random.randn(dim)
v = v / np.linalg.norm(v)

на прикладі мікрофона із закликом до

v = sample_tangent_unit(mu)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.