Ich möchte zufällige Daten aus einer eingeschränkten Normalverteilung mit R generieren.
Zum Beispiel möchte ich vielleicht eine Variable aus einer Normalverteilung mit simulieren mean=3, sd= 2
und alle Werte größer als 5 werden aus derselben Normalverteilung neu abgetastet.
Für die allgemeine Funktion könnte ich also Folgendes tun.
rnorm(n=100, mean=3, sd=2)
Ich hatte dann ein paar Gedanken:
- Iterieren Sie eine
ifelse
Funktion mit einer Schleife, die wiederholt wird, bis alle Werte innerhalb der Grenzen liegen müssen. - Simulieren Sie viel mehr Werte als erforderlich und verwenden Sie den ersten
n
, der die Einschränkung erfüllt. - Vermeiden Sie vektorisierte normale Variablensimulatoren und verwenden Sie stattdessen eine for-Schleife mit einem do while im Inneren, um jede Beobachtung einzeln zu simulieren und bei Bedarf eine Schleife durchzuführen.
All dies scheint ein bisschen klobig.
Frage
- Was ist eine einfache Möglichkeit, eine beschränkte zufällige Normalvariable in R von normal mit Mittelwert = 3, sd = 2 und max = 5 zu simulieren?
- Was ist allgemein eine gute allgemeine Möglichkeit, Einschränkungen in simulierte Variablen in R zu integrieren?
r
normal-distribution
simulation
truncation
Jeromy Anglim
quelle
quelle
Antworten:
Dies wird als abgeschnittene Normalverteilung bezeichnet:
http://en.wikipedia.org/wiki/Truncated_normal_distribution
Christian Robert schrieb hier über einen Ansatz, dies für eine Vielzahl von Situationen zu tun (je nachdem, wo sich die Kürzungspunkte befanden):
Robert, CP (1995) "Simulation abgeschnittener normaler Variablen",
Statistics and Computing, Band 5, Ausgabe 2, Juni, S. 121-125
Papier verfügbar unter http://arxiv.org/abs/0907.4010
Hier werden verschiedene Ideen für verschiedene Kürzungspunkte erörtert. Es ist nicht die einzige Möglichkeit, sich diesen zu nähern, aber es hat normalerweise eine ziemlich gute Leistung. Wenn Sie viele verschiedene abgeschnittene Normalen mit verschiedenen Kürzungspunkten ausführen möchten, ist dies ein vernünftiger Ansatz. Wie Sie bemerkt haben,
msm::tnorm
basiert es auf Roberts Ansatz, währendtruncnorm::truncnorm
Gewekes (1991) Accept-Reject-Sampler implementiert wird. Dies hängt mit dem Ansatz in Roberts Artikel zusammen. Beachten Sie, dassmsm::tnorm
Dichte-, cdf- und Quantilfunktionen (inverses cdf) auf die üblicheR
Weise enthalten sind.Eine ältere Referenz mit einem Ansatz ist Luc Devroyes Buch ; da es vergriffen ist, hat er das Urheberrecht zurückbekommen und es als Download zur Verfügung gestellt.
Ihr spezielles Beispiel ist dasselbe wie das Abtasten einer bei 1 abgeschnittenen Standardnormalen (wenn der Kürzungspunkt ist, ) und das anschließende Skalieren des Ergebnisses (multiplizieren) durch und füge ).t ( t - μ ) / σ= ( 5 - 3 ) / 2 = 1 σ μ
In diesem speziellen Fall schlägt Robert vor, dass Ihre Idee (in der zweiten oder dritten Inkarnation) durchaus vernünftig ist. Sie erhalten in etwa 84% der Fälle einen akzeptablen Wert und generieren so durchschnittlich etwa Normalen (Sie können Grenzen so berechnen, dass Sie mit einem vektorisierten Algorithmus, beispielsweise in 99,5% der Fälle, genügend Werte generieren und dann ab und zu generieren die letzten weniger effizient - sogar einzeln).1,19 n
Es gibt auch die Diskussion über eine Implementierung in R - Code hier (und in RCCP in einer anderen Antwort auf die gleiche Frage, aber der R - Code gibt es tatsächlich schneller). Der dortige einfache R-Code erzeugt 50000 abgeschnittene Normalen in 6 Millisekunden, obwohl diese bestimmte abgeschnittene Normalen nur die extremen Schwänze abschneidet, sodass eine substanziellere Kürzung bedeuten würde, dass die Ergebnisse langsamer sind. Es implementiert die Idee, "zu viele" zu generieren, indem berechnet wird, wie viele es generieren soll, um mit ziemlicher Sicherheit genug zu bekommen.
Wenn ich oft nur eine bestimmte Art von abgeschnittenem Normal brauchte, würde ich wahrscheinlich versuchen, eine Version der Zikkurat-Methode oder etwas Ähnliches an das Problem anzupassen.
Tatsächlich sieht es so aus, als hätte Nicolas Chopin genau das bereits getan, also bin ich nicht die einzige Person, der Folgendes eingefallen ist:
http://arxiv.org/abs/1201.6140
Er diskutiert mehrere andere Algorithmen und vergleicht die Zeit für 3 Versionen seines Algorithmus mit anderen Algorithmen, um 10 ^ 8 zufällige Normalen für verschiedene Kürzungspunkte zu erzeugen.
Es überrascht vielleicht nicht, dass sein Algorithmus relativ schnell ist.
Aus der Grafik in der Arbeit geht hervor, dass selbst der langsamste der Algorithmen, mit denen er an den (für sie) schlechtesten Kürzungspunkten vergleicht , in etwa 3 Sekunden Werte generiert - was darauf hindeutet, dass jeder der dort diskutierten Algorithmen akzeptabel sein kann, wenn dies vernünftigerweise der Fall ist gut umgesetzt.108
Bearbeiten: Eine, von der ich nicht sicher bin, dass sie hier erwähnt wird (aber vielleicht in einem der Links), ist das Transformieren (über inverses normales cdf) einer abgeschnittenen Uniform - aber die Uniform kann abgeschnitten werden, indem einfach eine Uniform innerhalb der Kürzungsgrenzen erzeugt wird . Wenn das inverse normale PDF schnell ist, ist dies sowohl schnell als auch einfach und funktioniert gut für eine Vielzahl von Kürzungspunkten.
quelle
In Anlehnung an die Referenzen von @ glen_b und ausschließlich auf die R-Implementierung ausgerichtet. Es gibt einige Funktionen, die zum Abtasten einer abgeschnittenen Normalverteilung entwickelt wurden:
rtruncnorm(100, a=-Inf, b=5, mean=3, sd=2)
imtruncnorm
Paketrtnorm(100, 3, 2, upper=5)
immsm
Paketquelle