Вземане на проби от zipf разпространение в ограничен домейн

Бих искал да взема проби от разпространението на "zipf" от ограничен домейн.

Тоест, приемете, че домейнът е {1,...,N}, бих искал всеки елемент в домейна, i, да бъде избран с вероятност, пропорционална на i ** -a, където a е параметър на разпределението.

numpy предоставя zipf семплер (numpy.random.zipf), но не ми позволява да огранича домейна.

Как мога лесно да взема проби от такова разпространение?


Ако параметърът за разпределение, a, е по-голям от 1, мога да използвам семплера numpy чрез отхвърляне (и повторно вземане на проби) на всички проби, по-големи от N. Въпреки това, тъй като не ограничава обхвата на извадката, опитът да се използват по-малки стойности на a не работи.

Когато домейнът е ограничен, не би трябвало да има проблем да използвам такива as и това е, което ми трябва за моето приложение.


person R B    schedule 25.10.2015    source източник
comment
@unutbu - да, благодаря.   -  person R B    schedule 25.10.2015


Отговори (2)


Използвайки scipy.stats, можете да създадете персонализирано дискретно разпределение:

bounded_zipf = stats.rv_discrete(name='bounded_zipf', values=(x, weights))

Например,

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

N = 7
x = np.arange(1, N+1)
a = 1.1
weights = x ** (-a)
weights /= weights.sum()
bounded_zipf = stats.rv_discrete(name='bounded_zipf', values=(x, weights))

sample = bounded_zipf.rvs(size=10000)
plt.hist(sample, bins=np.arange(1, N+2))
plt.show()

дава въведете описание на изображението тук

person unutbu    schedule 25.10.2015

Ако представянето на проби е проблем, можете да приложите свой собствен метод за вземане на проби, базиран на вземане на проби с отхвърляне-инверсия. Ще намерите съответстваща реализация на Java тук.

person otmar    schedule 27.10.2015