scipy.stats.sampling.

DiscreteAliasUrn#

класс scipy.stats.sampling.DiscreteAliasUrn(dist, *, область определения=None, urn_factor=1, random_state=None)#

Дискретный метод Alias-Urn.

Этот метод используется для выборки из одномерных дискретных распределений с конечной областью. Он использует вектор вероятностей размера \(N\) или функцией вероятностной массы с конечным носителем для генерации случайных чисел из распределения.

Параметры:
distarray_like или объект, опционально

Вероятностный вектор (PV) распределения. Если PV недоступен, экземпляр класса с pmf ожидается метод. Сигнатура PMF ожидается как: def pmf(self, k: int) -> float. т.е. он должен принимать целое число Python и возвращать число с плавающей точкой Python.

область определенияint, необязательный

Носитель PMF. Если вектор вероятностей (pv) недоступен, должна быть задана конечная область. Т.е. PMF должен иметь конечную поддержку. По умолчанию None. Когда None:

  • Если support метод предоставляется объектом распределения dist, используется для установки области определения распределения.

  • В противном случае предполагается, что носитель (0, len(pv)). Когда этот параметр передается в сочетании с вектором вероятности, domain[0] используется для перемещения распределения из (0, len(pv)) to (domain[0], domain[0]+len(pv)) и domain[1] игнорируется. См. Примечания и учебник для более подробного объяснения.

urn_factorfloat, опционально

Размер таблицы урны относительный к размеру вектора вероятностей. Он должен быть не меньше 1. Большие таблицы приводят к более быстрому времени генерации, но требуют более дорогой настройки. По умолчанию 1.

random_state{None, int, numpy.random.Generator,

numpy.random.RandomState, опционально

Генератор случайных чисел NumPy или seed для базового генератора случайных чисел NumPy, используемого для генерации потока равномерных случайных чисел. Если random_state равно None (или np.random), numpy.random.RandomState используется синглтон. Если random_state является int, новый RandomState используется экземпляр, инициализированный с random_state. Если random_state уже является Generator или RandomState экземпляр, тогда этот экземпляр используется.

Методы

rvs([size, random_state])

Выборка из распределения.

set_random_state([random_state])

Установить базовый генератор равномерных случайных чисел.

Примечания

Этот метод работает, когда доступен либо конечный вектор вероятностей, либо функция вероятности распределения. Если доступна только функция вероятности, то конечный область определения (support) PMF также должна быть задана. Рекомендуется сначала получить вектор вероятностей, вычислив PMF в каждой точке области определения, а затем использовать его вместо этого.

Если задан вероятностный вектор, он должен быть одномерным массивом неотрицательных чисел с плавающей запятой без каких-либо inf или nan значения. Также должен быть хотя бы один ненулевой элемент, иначе будет вызвано исключение.

По умолчанию вектор вероятностей индексируется, начиная с 0. Однако это можно изменить, передав domain параметр. Когда domain при использовании в комбинации с PV, это приводит к перемещению распределения из (0, len(pv)) to (domain[0], domain[0] + len(pv)). domain[1] игнорируется в этом случае.

Параметр urn_factor может быть увеличена для более быстрой генерации за счёт увеличения времени настройки. Этот метод использует таблицу для генерации случайных величин. urn_factor управляет размером этой таблицы относительно размера вектора вероятностей (или ширины носителя, если вектор вероятностей недоступен). Поскольку эта таблица вычисляется во время настройки, увеличение этого параметра линейно увеличивает время, необходимое для настройки. Рекомендуется держать этот параметр ниже 2.

Ссылки

[1]

Справочное руководство UNU.RAN, раздел 5.8.2, “DAU - (Discrete) Alias-Urn method”, http://statmath.wu.ac.at/software/unuran/doc/unuran.html#DAU

[2]

A.J. Walker (1977). An efficient method for generating discrete random variables with general distributions, ACM Trans. Math. Software 3, pp. 253-256.

Примеры

>>> from scipy.stats.sampling import DiscreteAliasUrn
>>> import numpy as np

Чтобы создать генератор случайных чисел с использованием вектора вероятностей, используйте:

>>> pv = [0.1, 0.3, 0.6]
>>> urng = np.random.default_rng()
>>> rng = DiscreteAliasUrn(pv, random_state=urng)

Генератор случайных чисел был настроен. Теперь мы можем использовать rvs метод для генерации выборок из распределения:

>>> rvs = rng.rvs(size=1000)

Чтобы проверить, что случайные величины следуют заданному распределению, можно использовать критерий хи-квадрат (как меру соответствия):

>>> from scipy.stats import chisquare
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> freqs
array([0.092, 0.292, 0.616])
>>> chisquare(freqs, pv).pvalue
0.9993602047563164

Поскольку p-значение очень высоко, мы не можем отвергнуть нулевую гипотезу о том, что наблюдаемые частоты совпадают с ожидаемыми частотами. Следовательно, мы можем безопасно предположить, что величины были сгенерированы из заданного распределения. Обратите внимание, что это проверяет корректность алгоритма, а не качество выборок.

Если PV недоступен, также можно передать экземпляр класса с методом PMF и конечной областью определения.

>>> urng = np.random.default_rng()
>>> class Binomial:
...     def __init__(self, n, p):
...         self.n = n
...         self.p = p
...     def pmf(self, x):
...         # note that the pmf doesn't need to be normalized.
...         return self.p**x * (1-self.p)**(self.n-x)
...     def support(self):
...         return (0, self.n)
...
>>> n, p = 10, 0.2
>>> dist = Binomial(n, p)
>>> rng = DiscreteAliasUrn(dist, random_state=urng)

Теперь мы можем выполнить выборку из распределения, используя rvs метод а также измеряет качество соответствия выборок:

>>> rvs = rng.rvs(1000)
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> obs_freqs = np.zeros(11)  # some frequencies may be zero.
>>> obs_freqs[:freqs.size] = freqs
>>> pv = [dist.pmf(i) for i in range(0, 11)]
>>> pv = np.asarray(pv) / np.sum(pv)
>>> chisquare(obs_freqs, pv).pvalue
0.9999999999999999

Чтобы проверить, что выборки были взяты из правильного распределения, мы можем визуализировать гистограмму выборок:

>>> import matplotlib.pyplot as plt
>>> rvs = rng.rvs(1000)
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> x = np.arange(0, n+1)
>>> fx = dist.pmf(x)
>>> fx = fx / fx.sum()
>>> ax.plot(x, fx, 'bo', label='true distribution')
>>> ax.vlines(x, 0, fx, lw=2)
>>> ax.hist(rvs, bins=np.r_[x, n+1]-0.5, density=True, alpha=0.5,
...         color='r', label='samples')
>>> ax.set_xlabel('x')
>>> ax.set_ylabel('PMF(x)')
>>> ax.set_title('Discrete Alias Urn Samples')
>>> plt.legend()
>>> plt.show()
../../_images/scipy-stats-sampling-DiscreteAliasUrn-1_00_00.png

Чтобы установить urn_factor, используйте:

>>> rng = DiscreteAliasUrn(pv, urn_factor=2, random_state=urng)

Это использует таблицу вдвое больше вектора вероятностей для генерации случайных величин из распределения.