Мне нужно генерировать случайные числа после нормального распределения в пределах интервала . (Я работаю в Р.)
Я знаю, что функция rnorm(n,mean,sd)
будет генерировать случайные числа после нормального распределения, но как установить пределы интервала в этом? Для этого есть какие-то особые функции R?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Ответы:
Похоже, вы хотите смоделировать из усеченного дистрибутива , а в вашем конкретном примере, усеченного нормального .
Для этого существует множество методов, некоторые простые, некоторые относительно эффективные.
Я проиллюстрирую некоторые подходы на вашем обычном примере.
Вот один очень простой метод для генерации по одному (в некотором псевдокоде):
Если большая часть распределения находится в пределах, это довольно разумно, но это может стать довольно медленным, если вы почти всегда генерируете за пределами.
В R вы можете избежать цикла «один за раз», вычисляя область в пределах границ и генерируя достаточно значений, чтобы вы могли быть почти уверены, что после исключения значений за пределами у вас все еще будет столько значений, сколько необходимо.
Вы можете использовать accept-reject с некоторой подходящей мажорирующей функцией на интервале (в некоторых случаях будет достаточно равномерного). Если бы пределы были достаточно узкими по отношению к SD, но вы не были далеко в хвосте, например, равномерное мажорирование будет работать нормально с нормой.
Если у вас достаточно эффективный cdf и обратный cdf (такой как
pnorm
иqnorm
для нормального распределения в R), вы можете использовать метод обратного cdf, описанный в первом абзаце раздела о моделировании на странице Википедии на усеченной нормали . [По сути, это то же самое, что взять усеченную униформу (усеченную в требуемых квантилях, которая на самом деле вообще не требует отклонений, поскольку это просто еще одна униформа) и применить к ней обратный нормальный cdf. Обратите внимание, что это может потерпеть неудачу, если вы далеко в хвосте]Есть другие подходы; на той же странице Википедии упоминается адаптация метода зиккурата , который должен работать для различных дистрибутивов.
В той же ссылке в Википедии упоминаются два конкретных пакета (оба в CRAN) с функциями для генерации усеченных нормалей:
Оглядываясь вокруг, многое из этого покрыто ответами на другие вопросы (но не совсем дубликатами, так как этот вопрос является более общим, чем просто усеченная норма) ... см. Дополнительное обсуждение в
а. Этот ответ
б. Ответ Сианя здесь , где есть ссылка на его статью arXiv (наряду с некоторыми другими полезными ответами).
источник
Быстрый и грязный подход заключается в использовании правила 68-95-99.7 .
При нормальном распределении 99,7% значений находятся в пределах 3 стандартных отклонений от среднего. Таким образом, если вы установите среднее значение на середину желаемого минимального значения и максимального значения и установите стандартное отклонение на 1/3 от среднего значения, вы получите (в основном) значения, попадающие в требуемый интервал. Тогда вы можете просто очистить все остальное.
Недавно я столкнулся с той же проблемой, пытаясь генерировать случайные оценки студентов для тестовых данных. В приведенном выше коде я использовал
pmax
иpmin
для замены значений за пределами поля на значение минимальной или максимальной границы. Это работает для моей цели, потому что я генерирую довольно небольшие объемы данных, но для больших объемов это даст вам заметные удары при минимальных и максимальных значениях. Поэтому, в зависимости от ваших целей, может быть лучше отбросить эти значения, заменить их наNA
s или «перекатывать» их, пока они не окажутся в границах.источник
sample(x=min:max, prob=dnorm(...))
это может быть более простой способ сделать это.sample(x=min:max, prob=dnorm(...))
что кажется немного короче, чем ваш ответ.sample()
трюк полезен только в том случае, если вы пытаетесь выбрать случайные целые числа или какой-то другой набор дискретных, предопределенных значений.Ни один из ответов здесь не дает эффективного метода генерации усеченных нормальных переменных, который не предполагает отклонения произвольно большого числа сгенерированных значений. Если вы хотите сгенерировать значения из усеченного нормального распределения, с указанными нижними и верхними границамиа < б , это может быть сделано - без отклонения - путем генерации однородных квантилей в диапазоне квантилей, разрешенных усечением, и с использованием выборки обратного преобразования для получения соответствующих нормальных значений.
ПозволятьΦ обозначим CDF стандартного нормального распределения. Мы хотим генерироватьИкс1, . , , , XN из усеченного нормального распределения (со средним параметром μ и параметр дисперсии σ2 )† с нижней и верхней границей усечения а < б , Это можно сделать следующим образом:
Не существует встроенной функции для сгенерированных значений из усеченного распределения, но программировать этот метод тривиально, используя обычные функции для генерации случайных величин. Вот простая
R
функция,rtruncnorm
которая реализует этот метод в несколько строк кода.Это векторизованная функция, которая будет генерировать
N
случайные величины IID из усеченного нормального распределения. Было бы легко программировать функции для других усеченных распределений тем же методом. Также не было бы слишком сложно программировать связанные функции плотности и квантили для усеченного распределения.источник