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

36

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

Предположим, у меня есть только две данные, описывающие нормальное распределение: среднее и дисперсия . Я хочу использовать компьютер для случайной выборки из этого дистрибутива, чтобы я уважал эти две статистики.σ 2μσ2

Совершенно очевидно, что я могу справиться со средним значением, просто нормализовав значение около 0: просто добавьте к каждому семплу перед его выводом. Но я не вижу, как программно генерировать образцы, чтобы уважать .σ 2μσ2

Моя программа будет на обычном языке программирования; У меня нет доступа к статистическим пакетам.

Fixee
источник
У вашего языка есть генератор случайных чисел? Является ли этот генератор только из равномерного распределения, или он также может генерировать из нормального распределения?
ttnphns
@ttnphns: Практически каждый компьютерный язык поставляется с генератором случайных чисел. Они в подавляющем большинстве случаев являются однородными генераторами в некоторой конечной области.
Fixee

Ответы:

33

Если вы можете произвести выборку из заданного распределения со средним значением 0 и дисперсией 1, то вы можете легко выполнить выборку из преобразования масштаба расположения этого распределения, которое имеет среднее значение и дисперсию . Если является выборкой из среднего распределения 0 и дисперсии 1, то является выборкой со средним значением и дисперсией . Итак, все, что вам нужно сделать, это масштабировать переменную по стандартному отклонению (квадратный корень из дисперсии), прежде чем добавить среднее .μσ2x

σx+μ
μσ2σμ

Как вы на самом деле получаете симуляцию из нормального распределения со средним 0 и дисперсией 1 - это отдельная история. Интересно и интересно узнать, как реализовать такие вещи, но используете ли вы статистический пакет или язык программирования или нет, я рекомендую вам получить и использовать подходящую функцию или библиотеку для генерации случайных чисел. Если вы хотите получить совет о том, какую библиотеку использовать, вы можете добавить конкретную информацию о том, какой язык (языки) вы используете.

Редактировать: В свете комментариев, некоторых других ответов и того факта, что Fixee принял этот ответ, я приведу некоторые подробности о том, как можно использовать преобразования однородных переменных для получения нормальных переменных.

  • Одним из методов, уже упомянутых в комментарии VitalStatistix , является метод Бокса-Мюллера, который принимает две независимые однородные случайные величины и создает две независимые нормальные случайные величины. Аналогичный метод, позволяющий избежать вычисления двух трансцендентных функций sin и cos за счет еще нескольких симуляций, был опубликован в качестве ответа francogrex .
  • Совершенно общим методом является преобразование равномерной случайной величины обратной функцией распределения. Если равномерно распределено на [ 0 , 1 ], то Φ - 1 ( U ) имеет стандартное нормальное распределение. Хотя для Ф - 1 нет явной аналитической формулы , ее можно вычислить с помощью точных численных приближений. Текущая реализация в R (последнее, что я проверял) использует эту идею. Метод концептуально очень прост, но требует точной реализации Φ - 1 , которая, вероятно, не так широко распространена, как (другие) трансцендентные функцииU[0,1]
    Φ1(U)
    Φ1Φ1журнал , грех и соз .
  • В нескольких ответах упоминается возможность использования центральной предельной теоремы для аппроксимации нормального распределения как среднего значения равномерных случайных величин. Это обычно не рекомендуется. Представленные аргументы, такие как соответствие среднего 0 и дисперсии 1, а также соображения о поддержке распределения не убедительны. В упражнении 2.3 «Введение методов Монте-Карло в R» Кристиана П. Роберта и Джорджа Казеллы этот генератор называется устаревшим, а приближение называется очень плохим .
  • Существует множество других идей. Глава 3 и, в частности, раздел 3.4, "Искусство компьютерного программирования", том. 2 Donald E. Knuth - это классическая ссылка на генерацию случайных чисел. Брайан Рипли написал « Компьютерное поколение случайных величин: учебное пособие» , которое может быть полезным. Также рекомендуется книга, упомянутая Робертом и Казеллой, или, возможно, глава 2 в их другой книге «Статистические методы Монте-Карло».

В конце концов, правильно реализованный метод не лучше, чем используемый генератор псевдослучайных чисел. Лично я предпочитаю полагаться на специальные библиотеки, которые, на мой взгляд, заслуживают доверия. Я почти всегда полагаюсь на методы, реализованные в R, либо непосредственно в R, либо через API в C / C ++. Очевидно, что это решение не для всех, но я недостаточно знаком с другими библиотеками, чтобы рекомендовать альтернативы.

NRH
источник
(+1) Хороший ответ и совет для ОП.
кардинал
18
2log(U1)cos(2πU2)
2log(U1)sin(2πU2)
2
@Vital: не лишний комментарий; хороший. Преобразование Бокса-Мюллера, вероятно, является наиболее простым в программировании с минимальной вероятностью непреднамеренного совершения чего-либо плохого. Это не самый быстрый , но достаточно конкурентоспособный. Тем не менее, использование установленной библиотеки кодов, вероятно, еще безопаснее, особенно с учетом того, что место, где можно ошибиться, - это способ генерирования однородных случайных входных данных!
кардинал
@Vital: Спасибо, это то, что я искал. Если вы хотите преобразовать свой комментарий в ответ, я с радостью его поддержу.
Fixee
1
@VitalStatistix, это хороший комментарий, и, похоже, именно это искал ОП. Почему бы не превратить его в ответ и, возможно, немного проработать общую идею использования преобразований равномерных случайных величин. Я не решался сделать это по той причине, о которой Кардинал упоминает в основном потому, что не знаю, является ли генератор униформ по умолчанию из какого-либо языка хорошим генератором.
NRH
10

Это действительно комментарий к ответу Майкла Лью и комментария Фикси, но он опубликован как ответ, потому что у меня нет репутации на этом сайте, чтобы комментировать.

[0,1]61

E[i=112Xi]=i=112E[Xi]=12×12=6
var[i=112Xi]=i=112var[Xi]=12×112=1.
i=112Xi610/12i=112Xi6[6,6]6
Дилип Сарватэ
источник
5

В дополнение к ответу NRH, если у вас все еще нет средств для генерации случайных выборок из «стандартного нормального распределения» N (0,1), ниже приведен хороший и простой способ (поскольку вы упоминаете, что у вас нет статистических данных). пакет, функции ниже должны быть доступны на большинстве стандартных языков программирования).

1. Сгенерируйте u и v как два равномерно распределенных случайных числа в диапазоне от -1 до 1
u = 2 r1 - 1иv = 2 r2 - 1

2. рассчитать, w = u^2 + v^2если w> 1, вернуться к 1

3. вернуть u * z и y = v * z с z= sqrt(-2ln(w)/w) примером кода будет выглядеть так:

u = 2 * random() - 1;
v = 2 * random() - 1;
w = pow(u, 2) + pow(v, 2);
if (w < 1) {
    z = sqrt((-2 * log(w)) / w);
    x = u * z;
    y = v * z;
    }

затем используйте то, что MHR предложило выше, чтобы получить случайные отклонения от N(mu, sigma^2).

francogrex
источник
Когда я опубликовал свой ответ выше, я не заметил, что @vitalStatistix дал вам алгоритм преобразования Бокса-Мюллера. Тот, что я даю выше, также хорош, я полагаю.
francogrex
2
Не могли бы вы объяснить причину генерации нормальных вариаций из равномерного распределения (отличного от алгоритмической), а не просто использовать pdf гауссовского / нормального распределения напрямую? Или это совершенно неправильно?
Арун
4
@Arun Одна из причин: полярный метод Марсальи полезен, когда у вас есть только ГСЧ, который генерирует однородные отклонения.
хл
1
@ Арун, это самый простой способ. Вы также можете сгенерировать из PDF напрямую, используя, например, метод «отклонение принятия». Я разместил для вас простой пример на моем сайте (потому что здесь недостаточно места в поле для комментариев).
francogrex
4

Нормальное распределение возникает, когда складывается много случайных значений одинакового распределения (я имею в виду, что они похожи друг на друга). Если сложить десять или более равномерно распределенных случайных значений, то сумма будет распределена почти нормально. (Добавьте больше десяти, если хотите, чтобы оно было еще более нормальным, но десяти достаточно для почти всех целей.)

Скажем, что ваши равномерные случайные значения равномерно распределены между 0 и 1. Сумма будет тогда между 0 и 10. Вычтите 5 из суммы, и среднее значение полученного распределения будет 0. Теперь вы разделите результат на стандартное отклонение (почти) нормальное распределение и умножьте результат на требуемое стандартное отклонение. К сожалению, я не уверен, каково стандартное отклонение суммы десяти равномерных случайных отклонений, но если нам повезет, кто-то скажет нам в комментарии!

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

Майкл Лью
источник
Здесь вы используете центральный предел Thm (сумма случайных величин iid суммируется с нормальной случайной величиной). Я не учел это, потому что думал, что это будет слишком медленно, но вы говорите, что 10 достаточно ?! Это лучше, чем вычислять лог и sin / cos и sqrt!
Fixee
Кроме того, среднее значение равномерного rv на [0,1] равно 0,5 с дисперсией 1/12. Если вы сложите 10 из них, вы получите среднее значение 5 и дисперсию 10/12 = 5/6.
Fixee
1
С педагогической точки зрения этот метод обеспечивает приятное, полезное обсуждение и демонстрацию. Тем не менее, я настоятельно рекомендую любому использовать этот подход на практике.
кардинал
1
logsincos
1
@Michael: Заявляя это дает «право» распределение является немного растянуть, в частности , так как распределение аппроксимирующего имеет компактный носитель и, во многих случаях, один делает заботу о том , насколько эффективно этом переменных может быть получены. :) Дело в том, что есть несколько гораздо лучших вариантов. Но я все еще думаю, что это дает что-то полезное с педагогической точки зрения.
кардинал