Генерация случайных значений из боксплота - PullRequest
0 голосов
/ 01 мая 2020

У меня есть, скажем, существующий BoxPlot:

median: 5, 
q1: 2
q3: 6
5% percentile: 1
95% percentile: 2

Я хотел бы сгенерировать 1 000 000 случайных значений после этого распределения.

Есть ли способ сделать это?

Я могу генерировать искаженные нормальные распределения, поэтому другим способом было бы преобразовать значения boxplot в единицу из асимметричного распределения, но, учитывая, что плотность изменяется с изменением альфа, я понятия не имею, как начать в этом .

1 Ответ

1 голос
/ 01 мая 2020

Наиболее общий способ генерации случайного числа после распределения заключается в следующем:

  • Создание равномерного случайного числа, ограниченного 0 и 1 (например, random.random()).
  • Возьмите обратный CDF (обратная кумулятивная функция распределения) этого числа.

Результатом является число, следующее за распределением.

В вашем случае у вас уже есть хороший Идея о том, как выглядит обратный CDF (ICDF(x)), поскольку он определяется уже несколькими вашими параметрами следующим образом:

  • ICDF (0,05) = 5-й процентиль
  • ICDF (0,25 ) = 1-й квартиль
  • ICDF (0,5) = медиана
  • ICDF (0,75) = 3-й квартиль
  • ICDF (0,95) = 95-й процентиль

Однако вы не определили минимальное и максимальное значения, которые бы соответствовали ICDF (0) и ICDF (1) соответственно; Таким образом, вы должны были бы оценить их. Затем вы можете заполнить недостающие точки обратного CDF путем интерполяции. Простейшим примером является линейная интерполяция, но другие более сложные примеры включают в себя подгонку кривой или сплайна к точкам обратного CDF, таким как сплайн Катмулла-Рома.

С другой стороны, если у вас есть доступ к базовому В точках данных, а не просто в виде графика, есть другие методы , которые вы можете использовать. Примеры включают оценки плотности ядра , гистограммы или регрессионные модели (особенно для данных временных рядов). См. Также Генерация случайных данных на основе существующих данных .


Ниже приведены примеры:

import numpy
import scipy.interpolate as intrp
# Generate 100 random values based on 5 percentiles, 
# minimum, and maximum
interp=intrp.interp1d([0.05,0.25,0.5, 0.75,0.95],[mn,p5,q1,p50,q3,p95,mx])
values=interp(numpy.random.random(size=100))
# Generate 100 random values based on 5 percentiles,
# extrapolating at ends
interp=intrp.interp1d([0.05,0.25,0.5, 0.75,0.95],
  [p5,q1,p50,q3,p95],fill_value="extrapolate")
values=interp(numpy.random.random(size=100))
...