Muszę wygenerować liczby losowe po rozkładzie normalnym w przedziale . (Pracuję w R.)
Wiem, że funkcja rnorm(n,mean,sd)
wygeneruje losowe liczby po rozkładzie normalnym, ale jak ustawić limity interwałów w tym zakresie? Czy są do tego dostępne jakieś konkretne funkcje R?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Odpowiedzi:
To brzmi jak chcesz symulować z obciętego rozkładu , aw twoim konkretnym przykładzie obciętego normalnego .
Istnieje wiele różnych metod, niektóre proste, a niektóre stosunkowo wydajne.
Zilustruję niektóre podejścia na twoim normalnym przykładzie.
Oto jedna bardzo prosta metoda generowania pojedynczo (w jakimś pseudokodzie):
Jeśli większość rozkładu mieści się w granicach, jest to całkiem rozsądne, ale może być dość powolne, jeśli prawie zawsze generujesz poza granicami.
W R można uniknąć pętli pojedynczej, obliczając obszar w granicach i generując wystarczającą liczbę wartości, dzięki czemu można być niemal pewnym, że po wyrzuceniu wartości poza granice nadal masz tyle wartości, ile potrzeba.
Możesz użyć akceptacji-odrzucenia z jakąś odpowiednią funkcją majorowania w tym przedziale (w niektórych przypadkach mundur będzie wystarczająco dobry). Gdyby granice były dość wąskie w stosunku do SD, ale nie byłeś daleko w tyle, jednolita majoralizacja działałaby dobrze na przykład z normalną.
Jeśli masz dość wydajne cdf i odwrotne cdf (takie jak
pnorm
iqnorm
do normalnego rozkładu w R), możesz użyć metody odwrotnej cdf opisanej w pierwszym akapicie sekcji symulacyjnej strony Wikipedii na normalnej skróconej . [W efekcie jest to to samo, co pobranie obciętego munduru (obciętego przy wymaganych kwantylach, który w rzeczywistości nie wymaga żadnych odrzuceń, ponieważ jest to tylko kolejny mundur) i zastosowanie do tego odwrotnego normalnego cdf. Pamiętaj, że może się to nie powieść, jeśli jesteś daleko w ogonie]Istnieją inne podejścia; ta sama strona Wikipedii wspomina o dostosowaniu metody ziggurat , która powinna działać dla różnych dystrybucji.
Ten sam link do Wikipedii wymienia dwa konkretne pakiety (oba w CRAN) z funkcjami do generowania obciętych normalnych:
Rozglądając się, wiele z tego jest zawartych w odpowiedziach na inne pytania (ale nie do końca duplikowane, ponieważ to pytanie jest bardziej ogólne niż tylko okrojona norma) ... zobacz dodatkową dyskusję w
za. Ta odpowiedź
b. Odpowiedź Xi'ana tutaj , która zawiera link do jego artykułu arXiv (wraz z kilkoma innymi wartościowymi odpowiedziami).
źródło
Szybkim i brudnym podejściem jest użycie reguły 68-95-99.7 .
W rozkładzie normalnym 99,7% wartości mieści się w 3 standardowych odchyleniach średniej. Tak więc, jeśli ustawisz średnią na żądaną wartość minimalną i maksymalną i ustawisz odchylenie standardowe na 1/3 średniej, otrzymasz (głównie) wartości mieszczące się w pożądanym przedziale. Następnie możesz po prostu posprzątać resztę.
Ostatnio napotkałem ten sam problem, próbując wygenerować losowe oceny uczniów na potrzeby danych testowych. W powyższym kodzie użyłem
pmax
ipmin
zamieniłem wartości spoza zakresu na wartość minimalną lub maksymalną. Działa to w moim celu, ponieważ generuję dość małe ilości danych, ale w przypadku większych ilości spowoduje to zauważalne nierówności przy wartościach minimalnej i maksymalnej. Dlatego w zależności od celów lepiej odrzucić te wartości, zastąpić jeNA
s lub „przerzucić”, dopóki nie znajdą się w granicach.źródło
sample(x=min:max, prob=dnorm(...))
może to być łatwiejszy sposób.sample(x=min:max, prob=dnorm(...))
co wydaje się nieco krótsze niż twoja odpowiedź.sample()
sztuczka jest przydatna tylko wtedy, gdy próbujesz wybrać losowe liczby całkowite lub inny zestaw dyskretnych, predefiniowanych wartości.Nie ma wbudowanej funkcji generowania wartości z obciętego rozkładu, ale programowanie tej metody przy użyciu zwykłych funkcji do generowania zmiennych losowych jest banalne. Oto prosta
R
funkcja,rtruncnorm
która implementuje tę metodę w kilku wierszach kodu.Jest to wektoryzowana funkcja, która wygeneruje
N
losowe zmienne IID ze skróconego rozkładu normalnego. Łatwo byłoby zaprogramować funkcje dla innych skróconych dystrybucji za pomocą tej samej metody. Nie byłoby też zbyt trudne zaprogramowanie powiązanych funkcji gęstości i kwantylu dla skróconego rozkładu.źródło