Створення випадкових чисел після розподілу в інтервалі


17

Мені потрібно генерувати випадкові числа після нормального розподілу в інтервалі . (Я працюю в Р.)(a,b)

Я знаю, що функція rnorm(n,mean,sd)генерує випадкові числа після нормального розподілу, але як встановити межі інтервалу в межах цього? Чи є для цього якісь функції R?


Чому ти хочеш це робити? Якщо воно обмежене, то воно справді не може бути нормальним. Чого ви намагаєтесь досягти?
gung - Відновіть Моніку

x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Х'ю,

3
@Hugh, це чудово ... до тих пір, поки вам не байдуже, скільки випадкових значень ви отримаєте.
Glen_b -Встановити Моніку

Відповіді:


31

Це здається, що ви хочете імітувати з усіченого розподілу , а у вашому конкретному прикладі - усічений нормал .

Існує безліч методів цього, деякі прості, деякі відносно ефективні.

Я проілюструю деякі підходи на вашому звичайному прикладі.

  1. Ось один дуже простий метод генерації одного за одним (у якомусь псевдокоді):

    repeat генеруватиxi з N (середнє значення, sd)until нижнійxi верхній

    введіть тут опис зображення

    Якщо більша частина дистрибуції знаходиться в межах, це досить розумно, але це може вийти досить повільним, якщо ви майже завжди генеруєтесь поза межами.

    У R ви можете уникнути одноразового циклу, обчислюючи область в межах та генеруючи достатню кількість значень, щоб ви могли бути майже впевнені, що після викидання значень за межі у вас все-таки залишилося стільки значень, скільки потрібно.

  2. Ви можете використовувати прийом-відхилення з деякою підходящою функцією мажоризації протягом інтервалу (у деяких випадках рівномірність буде досить хорошою). Якби межі були досить вузькими щодо sd, але ви не були далеко в хвіст, наприклад, рівномірне мажоризування спрацювало б нормально.

    введіть тут опис зображення

  3. Якщо у вас є досить ефективний cdf та зворотний cdf (наприклад, pnormі qnormдля нормального розподілу в R), ви можете використовувати метод inverse-cdf, описаний у першому параграфі імітаційного розділу сторінки Вікіпедії на усіченому нормалі . [Насправді це те саме, що взяти усічену форму (усічену за потрібними квантовими елементами, яка насправді не потребує відхилень взагалі, оскільки це просто ще одна рівномірність) і застосувати до цього зворотний нормальний cdf. Зауважте, що це може вийти з ладу, якщо ви далеко в хвіст]

    введіть тут опис зображення

  4. Є й інші підходи; та ж сторінка Вікіпедії згадує про адаптацію методу зиггурат , який повинен працювати для різних розповсюджень.

Це ж посилання Вікіпедії згадує два конкретні пакети (обидва на CRAN) з функціями для генерації усічених нормалів:

MSMПакет в R має функцію, rtnorm, яка обчислює черпає з усічених нормально. truncnormПакет в R також має функції для малювання з усічених нормальних.


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

а. Ця відповідь

б. Тут відповідь Сіань , яка містить посилання на його арксiвський статтю (разом з деякими вагомими відповідями).


2

Швидкий і брудний підхід полягає у використанні правила 68-95-99.7 .

При нормальному розподілі 99,7% значень підпадають під 3 стандартні відхилення середнього значення. Отже, якщо встановити середнє значення бажаного мінімального значення та максимального значення, а стандартне відхилення встановити на 1/3 середнього значення, ви отримаєте (в основному) значення, які знаходяться в межах потрібного інтервалу. Тоді ви можете просто почистити решту.

minVal <- 0
maxVal <- 100
mn <- (maxVal - minVal)/2
# Generate numbers (mostly) from min to max
x <- rnorm(count, mean = mn, sd = mn/3)
# Do something about the out-of-bounds generated values
x <- pmax(minVal, x)
x <- pmin(maxVal, x)

Нещодавно я стикався з цією ж проблемою, намагаючись генерувати випадкові оцінки студентів для тестових даних. У наведеному вище коді я використовував pmaxта pminзамінював значення поза межами межі зі значенням min або max у межах. Це працює для моєї мети, тому що я генерую досить невеликий обсяг даних, але для більшої кількості він надасть вам помітних ударів при мінімальних та максимальних значеннях. Отже, залежно від ваших цілей, можливо, краще відкинути ці значення, замінити їх на NAs або перезапустити їх, поки вони не знаходяться в межах.


Навіщо турбуватися цим? Генерувати нормальні випадкові числа так просто і скидати ті, які потребують укорочення, що з цим не потрібно ускладнюватися, якщо бажане усічення не наближається до 100% площі щільності.
Карл

2
Можливо, я неправильно трактую початкове запитання. Я зіткнувся з цим питанням, намагаючись розібратися, як досягти завдання, яке не пов'язане безпосередньо зі статистикою, у програмі R, і я лише зараз помітив, що ця сторінка - це stackexchange, а не stackexchange програмування. :) У моєму випадку я хотів генерувати певну кількість випадкових цілих чисел із значеннями в межах від 0 до 100, і я хотів, щоб згенеровані значення падали на гарну криву дзвона через цей діапазон. Починаючи писати це, я зрозумів, що sample(x=min:max, prob=dnorm(...))це, можливо, простіший спосіб зробити це.
Аарон Уеллс

@Glen_b Аарон Уеллс згадує, sample(x=min:max, prob=dnorm(...))що здається трохи коротшим, ніж ваша відповідь.
Карл

Але зауважте, що sample()хитрість корисна лише в тому випадку, якщо ви намагаєтеся вибрати випадкові цілі числа чи інший набір дискретних, заздалегідь визначених значень.
Аарон Уеллс

1

a<b для отримання відповідних нормальних значень.

ΦX1,...,XNμσ2a<b

Xi=μ+σΦ1(Ui)U1,...,UNIID U[Φ(aμσ),Φ(bμσ)].

Не існує вбудованої функції для генерованих значень із усіченого розподілу, але тривіально програмувати цей метод, використовуючи звичайні функції для генерації випадкових змінних. Ось проста Rфункція, rtruncnormяка реалізує цей метод у кількох рядках коду.

rtruncnorm <- function(N, mean = 0, sd = 1, a = -Inf, b = Inf) {
  if (a > b) stop('Error: Truncation range is empty');
  U <- runif(N, pnorm(a, mean, sd), pnorm(b, mean, sd));
  qnorm(U, mean, sd); }

Це векторизована функція, яка буде генерувати NIID випадкові змінні з усіченого нормального розподілу. Програмувати функції для інших усічених дистрибутивів за допомогою того ж методу було б легко. Також було б не надто складно запрограмувати пов'язані функції щільності та квантилі для усіченого розподілу.


μσ2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.