Ich muss Zufallszahlen generieren, die der Normalverteilung innerhalb des Intervalls folgen . (Ich arbeite in R.)
Ich weiß, dass die Funktion rnorm(n,mean,sd)
nach der Normalverteilung Zufallszahlen generiert, aber wie werden die Intervallgrenzen innerhalb dieser Funktion festgelegt? Gibt es dafür spezielle R-Funktionen?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Antworten:
Es hört sich so an, als ob Sie eine abgeschnittene Verteilung und in Ihrem speziellen Beispiel eine abgeschnittene Normalverteilung simulieren möchten .
Es gibt eine Vielzahl von Methoden, einige einfache, andere relativ effiziente.
Ich werde einige Ansätze an Ihrem normalen Beispiel veranschaulichen.
Hier ist eine sehr einfache Methode, um einen nach dem anderen zu generieren (in einer Art Pseudocode):
Wenn der Großteil der Distribution innerhalb der Grenzen liegt, ist dies ziemlich vernünftig, aber es kann ziemlich langsam werden, wenn Sie fast immer außerhalb der Grenzen generieren.
In R können Sie die einzelne Schleife vermeiden, indem Sie den Bereich innerhalb der Grenzen berechnen und so viele Werte generieren, dass Sie fast sicher sein können, dass Sie nach dem Wegwerfen der Werte außerhalb der Grenzen immer noch so viele Werte wie nötig hatten.
Sie können Accept-Reject mit einer geeigneten Majorizing-Funktion über das Intervall verwenden (in einigen Fällen ist Uniform ausreichend). Wenn die Grenzen relativ zum SD relativ eng wären, Sie aber nicht weit im Heck stecken, würde eine einheitliche Majorisierung zum Beispiel mit dem Normalen gut funktionieren.
Wenn Sie eine einigermaßen effiziente cdf- und inverse cdf-Datei haben (z. B.
pnorm
undqnorm
für die Normalverteilung in R), können Sie die inverse cdf-Methode verwenden, die im ersten Absatz des Simulationsabschnitts der Wikipedia-Seite für die abgeschnittene Normalen beschrieben ist . [Tatsächlich ist dies dasselbe, als würde man eine abgeschnittene Uniform nehmen (abgeschnitten auf die erforderlichen Quantile, für die eigentlich überhaupt keine Ablehnung erforderlich ist, da dies nur eine weitere Uniform ist) und darauf die inverse normale cdf anwenden. Beachten Sie, dass dies fehlschlagen kann, wenn Sie weit im Heck sind.]Es gibt andere Ansätze; Die gleiche Wikipedia-Seite erwähnt die Anpassung der Zikkurat- Methode, die für eine Vielzahl von Distributionen funktionieren sollte.
Die gleichen Empfehlungen erwähnt zwei spezifische Pakete (beide auf CRAN) mit Funktionen zur Erzeugung von Normalen trunkiert:
Wenn Sie sich umschauen, wird vieles davon in Antworten auf andere Fragen behandelt (aber nicht genau doppelt, da diese Frage allgemeiner ist als nur die abgeschnittene Norm) ... siehe zusätzliche Diskussion in
ein. Diese Antwort
b. Xi'ans Antwort hier , die einen Link zu seinem Artikel von arXiv enthält (zusammen mit einigen anderen nützlichen Antworten).
quelle
Der schnelle und schmutzige Ansatz besteht darin, die 68-95-99.7-Regel zu verwenden .
Bei einer Normalverteilung liegen 99,7% der Werte innerhalb von 3 Standardabweichungen vom Mittelwert. Wenn Sie also Ihren Mittelwert auf die Mitte Ihres gewünschten Minimal- und Maximalwerts einstellen und Ihre Standardabweichung auf 1/3 Ihres Mittelwerts einstellen, erhalten Sie (meistens) Werte, die innerhalb des gewünschten Intervalls liegen. Dann können Sie einfach den Rest aufräumen.
Vor kurzem war ich mit demselben Problem konfrontiert, als ich versuchte, zufällige Noten für Testdaten zu generieren . Im obigen Code habe ich Grenzüberschreitungswerte verwendet
pmax
undpmin
durch den Grenzüberschreitungswert "min" oder "max" ersetzt. Dies funktioniert für meinen Zweck, da ich relativ kleine Datenmengen generiere, bei größeren Datenmengen jedoch spürbare Unebenheiten bei den Min- und Max-Werten auftreten. Abhängig von Ihren Zwecken ist es daher möglicherweise besser, diese Werte zu verwerfen, durchNA
s zu ersetzen oder sie neu zu würfeln, bis sie eingegrenzt sind.quelle
sample(x=min:max, prob=dnorm(...))
ist mir klar geworden, dass dies vielleicht ein einfacher Weg ist.sample(x=min:max, prob=dnorm(...))
was etwas kürzer zu sein scheint als Ihre Antwort.sample()
Trick nur nützlich ist, wenn Sie versuchen, zufällige Ganzzahlen oder einen anderen Satz diskreter vordefinierter Werte auszuwählen.Lassen SieΦ X1,...,XN μ σ2 † a<b
Es gibt keine eingebaute Funktion für generierte Werte aus der abgeschnittenen Verteilung, aber es ist trivial, diese Methode mit den üblichen Funktionen zum Generieren von Zufallsvariablen zu programmieren. Hier ist eine einfache
R
Funktionrtruncnorm
, die diese Methode in wenigen Codezeilen implementiert.Dies ist eine vektorisierte Funktion, die
N
IID-Zufallsvariablen aus der abgeschnittenen Normalverteilung generiert . Es wäre einfach, Funktionen für andere verkürzte Verteilungen mit derselben Methode zu programmieren. Es wäre auch nicht zu schwierig, zugehörige Dichte- und Quantilfunktionen für die abgeschnittene Verteilung zu programmieren.quelle