Um eine Normalverteilung aus einer Reihe einheitlicher Variablen zu simulieren, gibt es verschiedene Techniken:
Der Box-Muller-Algorithmus , bei dem zwei unabhängige Uniformvariablen abgetastet werden, variiert auf und transformiert sie in zwei unabhängige Standardnormalverteilungen über: Z 0 = √
die CDF-Methode , bei der man das normale cdf einer Uniformvariablen gleichsetzen kann : und daraus F ( Z ) = U Z = F - 1 ( U )
Meine Frage ist: Was ist rechnerisch effizienter? Ich würde denken, es ist die letztere Methode - aber die meisten Zeitungen, die ich lese, verwenden Box-Müller - warum?
Zusätzliche Information:
Die Umkehrung der normalen CDF ist bekannt und gegeben durch:
Also:
normal-distribution
simulation
uniform
user2350366
quelle
quelle
Antworten:
Aus rein probabilistischer Sicht sind beide Ansätze richtig und daher gleichwertig. Aus algorithmischer Sicht muss der Vergleich sowohl die Genauigkeit als auch die Rechenkosten berücksichtigen.
Box-Muller setzt auf einen einheitlichen Generator und kostet ungefähr das Gleiche wie dieser einheitliche Generator. Wie in meinem Kommentar erwähnt, können Sie ohne Sinus- oder Cosinus-Aufrufe davonkommen, wenn nicht ohne den Logarithmus:
Der generische Inversionsalgorithmus erfordert beispielsweise den Aufruf der inversen normalen cdf
qnorm(runif(N))
in R, die teurer als die oben genannten sein und, was noch wichtiger ist, in Bezug auf die Genauigkeit in den Schwänzen versagen kann, sofern die Quantilfunktion nicht gut codiert ist.Um den Kommentaren von whuber zu folgen , ist der Vergleich von
rnorm(N)
undqnorm(runif(N))
der Vorteil des inversen cdf, sowohl in Bezug auf die Ausführungszeit:und in Bezug auf die Passform im Schwanz:
Nach einem Kommentar von Radford Neal in meinem Blog möchte ich darauf hinweisen, dass der Standardwert
rnorm
in R die Inversionsmethode verwendet, sodass der obige Vergleich sich auf die Schnittstelle und nicht auf die Simulationsmethode selbst auswirkt! So zitieren Sie die R-Dokumentation zu RNG:quelle
R 3.0.2
rowSums
qnorm(runif(N))
InverseCDF[NormalDistribution[], #] &
qnorm(runif(N))
ist sogar 20% schneller alsrnorm(N)
RNGkind(kind = NULL, normal.kind = 'Inversion');At <- microbenchmark(A <- rnorm(1e5, 0, 1), times = 100L);RNGkind(kind = NULL, normal.kind = 'Box-Muller');Bt <- microbenchmark(B <- rnorm(1e5, 0, 1), times = 100L)
Ich bekommemean 11.38363 median 11.18718
für die Inversion undmean 13.00401 median 12.48802
für Box-Muller