Jak mogę przekształcić rozkład równomierny (jak generuje większość generatorów liczb losowych, np. Między 0,0 a 1,0) na rozkład normalny? A jeśli chcę mieć wybraną średnią i odchylenie standardowe?
106
Jak mogę przekształcić rozkład równomierny (jak generuje większość generatorów liczb losowych, np. Między 0,0 a 1,0) na rozkład normalny? A jeśli chcę mieć wybraną średnią i odchylenie standardowe?
Odpowiedzi:
Algorytm Ziggurat jest dość skuteczny w tym, choć Transformacja Boxa-Mullera jest łatwiejszy do wdrożenia od zera (a nie szalone powolny).
źródło
Istnieje wiele metod:
źródło
Zmiana rozkładu dowolnej funkcji na inną wymaga użycia odwrotności żądanej funkcji.
Innymi słowy, jeśli dążysz do określonej funkcji prawdopodobieństwa p (x), otrzymasz rozkład przez całkowanie po niej -> d (x) = całka (p (x)) i użycie jej odwrotności: Inv (d (x)) . Teraz użyj funkcji prawdopodobieństwa losowego (które mają rozkład równomierny) i rzuć wartość wyniku za pomocą funkcji Inv (d (x)). Powinieneś otrzymać losowe wartości rzutowane z rozkładem zgodnie z wybraną funkcją.
To jest ogólne podejście matematyczne - używając go możesz teraz wybrać dowolną funkcję prawdopodobieństwa lub rozkładu, o ile ma ona odwrotne lub dobre odwrotne przybliżenie.
Mam nadzieję, że to pomogło i dziękuję za małą uwagę na temat korzystania z rozkładu, a nie samego prawdopodobieństwa.
źródło
Oto implementacja javascript wykorzystująca polarną postać transformacji Boxa-Mullera.
źródło
Użyj centralnego twierdzenia granicznego wpisu wikipedii o mathworld na swoją korzyść.
Wygeneruj n równomiernie rozłożonych liczb, zsumuj je, odejmij n * 0,5 i otrzymasz wynik w przybliżeniu normalnego rozkładu ze średnią równą 0 i wariancją równą
(1/12) * (1/sqrt(N))
(patrz wikipedia o rozkładach jednorodnych dla tego ostatniego)n = 10 daje coś w połowie przyzwoitego szybko. Jeśli chcesz czegoś więcej niż w połowie przyzwoitego, wybierz rozwiązanie Tylers (jak wspomniano we wpisie Wikipedii o normalnych dystrybucjach )
źródło
Użyłbym Box-Mullera. Dwie rzeczy na ten temat:
Zwykle buforujesz jedną wartość, a zwracasz drugą. Przy następnym wywołaniu próbki zwracasz zbuforowaną wartość.
Następnie należy wyskalować wynik Z za pomocą odchylenia standardowego i dodać średnią, aby uzyskać pełną wartość w rozkładzie normalnym.
źródło
Gdzie R1, R2 to losowe liczby jednolite:
ROZKŁAD NORMALNY, ze SD równym 1: sqrt (-2 * log (R1)) * cos (2 * pi * R2)
To jest dokładne ... nie musisz robić tych wszystkich wolnych pętli!
źródło
Wydaje się niewiarygodne, że mogłem coś do tego dodać po ośmiu latach, ale w przypadku Javy chciałbym zwrócić czytelnikom uwagę na metodę Random.nextGaussian () , która generuje rozkład Gaussa ze średnią 0,0 i odchyleniem standardowym 1,0.
Proste dodawanie i / lub mnożenie zmieni średnią i odchylenie standardowe zgodnie z Twoimi potrzebami.
źródło
Standardowy moduł losowy biblioteki Pythona ma to, czego chcesz:
Jeśli chodzi o sam algorytm, spójrz na funkcję w random.py w bibliotece Pythona.
Ręczne wprowadzanie jest tutaj
źródło
Oto moja implementacja algorytmu P ( metoda biegunowa dla odchyleń normalnych ) z sekcji 3.4.1 książki Donalda Knutha The Art of Computer Programming :
źródło
Myślę, że powinieneś spróbować tego w EXCEL:
=norminv(rand();0;1)
. Spowoduje to iloczyn liczb losowych, które powinny mieć rozkład normalny ze średnią zerową i jednoczącą wariancję. „0” można podać dowolną wartość, dzięki czemu liczby będą miały pożądaną średnią, a zmieniając „1”, uzyskasz wariancję równą kwadratowi wprowadzonego przez Ciebie tekstu.Na przykład:
=norminv(rand();50;3)
ustąpi liczbom o rozkładzie normalnym z ŚREDNIA = 50 ODMIANA = 9.źródło
P Jak mogę przekształcić rozkład równomierny (jak generuje większość generatorów liczb losowych, np. Między 0,0 a 1,0) na rozkład normalny?
Do implementacji oprogramowania znam kilka losowych nazw generatorów, które dają pseudojednorodną losową sekwencję w [0,1] (Mersenne Twister, Linear Congruate Generator). Nazwijmy to U (x)
Istnieje obszar matematyczny, który nazywa się teorią prawdopodobieństwa. Pierwsza rzecz: jeśli chcesz modelować rv z rozkładem całkowym F, możesz spróbować po prostu obliczyć F ^ -1 (U (x)). W teorii pr udowodniono, że taki rv będzie miał rozkład całkowy F.
Krok 2 można zastosować do wygenerowania rv ~ F bez użycia jakichkolwiek metod zliczania, gdy F ^ -1 można wyprowadzić analitycznie bez problemów. (np. dystrybucja eksp.)
Aby zamodelować rozkład normalny, można obliczyć y1 * cos (y2), gdzie y1 ~ jest jednorodne w [0,2pi]. a y2 to dystrybucja releasei.
P: A jeśli chcę mieć wybrane średnie i odchylenie standardowe?
Możesz obliczyć sigma * N (0,1) + m.
Można wykazać, że takie przesunięcie i skalowanie prowadzą do N (m, sigma)
źródło
To jest implementacja Matlaba wykorzystująca polarną postać transformacji Boxa-Mullera :
Funkcja
randn_box_muller.m
:A wywołanie
histfit(randn_box_muller(10000000),100);
tego jest wynikiem:Oczywiście jest to naprawdę nieefektywne w porównaniu z randn wbudowanym w Matlab .
źródło
Mam następujący kod, który może pomóc:
źródło
Użycie zaimplementowanej funkcji rnorm () jest również łatwiejsze, ponieważ jest szybsze niż pisanie generatora liczb losowych dla rozkładu normalnego. Zobacz poniższy kod jako dowód
źródło
źródło