RatioUniforms#
- класс scipy.stats.sampling.RatioUniforms(pdf, *, umax, vmin, vmax, c=0, random_state=None)[источник]#
Генерация случайных выборок из функции плотности вероятности с использованием метода отношения равномерных распределений.
- Параметры:
- pdfcallable
Функция с сигнатурой pdf(x) которая пропорциональна функции плотности вероятности распределения.
- umaxfloat
Верхняя граница ограничивающего прямоугольника в u-направлении.
- vminfloat
Нижняя граница ограничивающего прямоугольника в направлении v.
- vmaxfloat
Верхняя граница ограничивающего прямоугольника в v-направлении.
- cfloat, опционально.
Параметр сдвига метода отношения равномерных величин, см. Примечания. По умолчанию 0.
- random_state{None, int,
numpy.random.Generator, numpy.random.RandomState, опциональноЕсли seed равно None (или np.random),
numpy.random.RandomStateиспользуется синглтон. Если seed является int, новыйRandomStateиспользуется экземпляр, инициализированный с seed. Если seed уже являетсяGeneratorилиRandomStateэкземпляр, тогда этот экземпляр используется.
Методы
rvs([size])Выборка случайных величин
Примечания
Дана одномерная функция плотности вероятности pdf и константа c, определяют множество
A = {(u, v) : 0 < u <= sqrt(pdf(v/u + c))}. Если(U, V)является случайным вектором, равномерно распределенным поA, затемV/U + cследует распределению согласно pdf.Вышеуказанный результат (см. [1], [2]) можно использовать для выборки случайных величин используя только PDF, т.е. инверсия CDF не требуется. Типичные выборы c равны нулю или мода pdf. Множество
Aявляется подмножеством прямоугольникаR = [0, umax] x [vmin, vmax]гдеumax = sup sqrt(pdf(x))vmin = inf (x - c) sqrt(pdf(x))vmax = sup (x - c) sqrt(pdf(x))
В частности, эти значения конечны, если pdf ограничена и
x**2 * pdf(x)ограничена (т.е. субквадратичные хвосты). Можно сгенерировать(U, V)равномерно наRи возвращаетV/U + cif(U, V)также находятся вAкоторый можно напрямую проверить.Алгоритм не изменяется, если заменить pdf на k * pdf для любой константы k > 0. Таким образом, часто удобно работать с функцией, пропорциональной функции плотности вероятности, отбрасывая ненужные нормировочные множители.
Интуитивно, метод работает хорошо, если
Aзаполняет большую часть ограничивающего прямоугольника так, что вероятность высока, что(U, V)лежит вAвсякий раз, когда он лежит вRпоскольку количество требуемых итераций становится слишком большим в противном случае. Чтобы быть более точным, заметим, что ожидаемое количество итераций для выборки(U, V)равномерно распределены наRтакой, что(U, V)также находится вAзадается отношениемarea(R) / area(A) = 2 * umax * (vmax - vmin) / area(pdf), где area(pdf) является интегралом от pdf (что равно единице, если используется функция плотности вероятности, но может принимать другие значения, если используется функция, пропорциональная плотности). Равенство выполняется, поскольку площадьAравно0.5 * area(pdf)(Теорема 7.1 в [1]). Если выборка не может сгенерировать ни одной случайной величины после 50000 итераций (т.е. ни один выбор не находится вA), возникает исключение.Если ограничивающий прямоугольник указан некорректно (т.е. если он не содержит
A), алгоритм выбирает из распределения, отличного от заданного pdf. Поэтому рекомендуется выполнить тест, такой какkstestв качестве проверки.Ссылки
[2]W. Hoermann и J. Leydold, «Generating generalized inverse Gaussian random variates», Statistics and Computing, 24(4), стр. 547–557, 2014.
[3]A.J. Kinderman и J.F. Monahan, "Генерация случайных величин на компьютере с использованием отношения равномерных отклонений", ACM Transactions on Mathematical Software, 3(3), стр. 257–260, 1977.
Примеры
>>> import numpy as np >>> from scipy import stats
>>> from scipy.stats.sampling import RatioUniforms >>> rng = np.random.default_rng()
Моделировать нормально распределённые случайные величины. В этом случае легко вычислить ограничивающий прямоугольник явно. Для простоты мы опускаем нормировочный множитель плотности.
>>> f = lambda x: np.exp(-x**2 / 2) >>> v = np.sqrt(f(np.sqrt(2))) * np.sqrt(2) >>> umax = np.sqrt(f(0)) >>> gen = RatioUniforms(f, umax=umax, vmin=-v, vmax=v, random_state=rng) >>> r = gen.rvs(size=2500)
K-S тест подтверждает, что случайные величины действительно нормально распределены (нормальность не отвергается на 5% уровне значимости):
>>> stats.kstest(r, 'norm')[1] 0.250634764150542
Экспоненциальное распределение предоставляет ещё один пример, где ограничивающий прямоугольник может быть определён явно.
>>> gen = RatioUniforms(lambda x: np.exp(-x), umax=1, vmin=0, ... vmax=2*np.exp(-1), random_state=rng) >>> r = gen.rvs(1000) >>> stats.kstest(r, 'expon')[1] 0.21121052054580314