Ich habe einige Beobachtungen und möchte anhand dieser Beobachtungen Stichproben nachahmen. Hier betrachte ich ein nicht parametrisches Modell, insbesondere verwende ich die Kernel-Glättung, um eine CDF aus den begrenzten Beobachtungen zu schätzen. Dann ziehe ich zufällige Werte aus der erhaltenen CDF. Das Folgende ist mein Code (die Idee ist, zufällig eine kumulative zu erhalten Wahrscheinlichkeit unter Verwendung einer gleichmäßigen Verteilung und nehmen die Umkehrung der CDF in Bezug auf den Wahrscheinlichkeitswert)
x = [randn(100, 1); rand(100, 1)+4; rand(100, 1)+8];
[f, xi] = ksdensity(x, 'Function', 'cdf', 'NUmPoints', 300);
cdf = [xi', f'];
nbsamp = 100;
rndval = zeros(nbsamp, 1);
for i = 1:nbsamp
p = rand;
[~, idx] = sort(abs(cdf(:, 2) - p));
rndval(i, 1) = cdf(idx(1), 1);
end
figure(1);
hist(x, 40)
figure(2);
hist(rndval, 40)
Wie im Code gezeigt, habe ich ein synthetisches Beispiel verwendet, um mein Verfahren zu testen, aber das Ergebnis ist unbefriedigend, wie die beiden folgenden Abbildungen zeigen (die erste ist für die simulierten Beobachtungen und die zweite Abbildung zeigt das Histogramm, das aus der geschätzten CDF gezogen wurde). ::
Gibt es jemanden, der weiß, wo das Problem liegt? Vielen Dank im Voraus.
quelle
Antworten:
Ein Kernel-Dichteschätzer (KDE) erzeugt eine Verteilung, die eine Ortsmischung der Kernel-Verteilung ist. Um also einen Wert aus der Kernel-Dichteschätzung zu ziehen, müssen Sie lediglich (1) einen Wert aus der Kernel-Dichte ziehen und dann (2) Wählen Sie einen der Datenpunkte unabhängig voneinander nach dem Zufallsprinzip aus und addieren Sie seinen Wert zum Ergebnis von (1).
Hier ist das Ergebnis dieser Prozedur, die auf einen Datensatz wie den in der Frage angewendeten angewendet wird.
Das Histogramm links zeigt die Probe. Als Referenz zeigt die schwarze Kurve die Dichte, aus der die Probe gezogen wurde. Die rote Kurve zeigt die KDE der Probe (unter Verwendung einer schmalen Bandbreite). (Es ist kein Problem oder sogar unerwartet, dass die roten Peaks kürzer als die schwarzen Peaks sind: Der KDE verteilt die Dinge, sodass die Peaks zum Ausgleich niedriger werden.)
Das Histogramm rechts zeigt eine Probe (gleicher Größe) aus dem KDE. Die schwarzen und roten Kurven sind die gleichen wie zuvor.
Offensichtlich funktioniert das Verfahren zur Probenahme aus der Dichte. Es ist auch extrem schnell: Die folgende
R
Implementierung generiert Millionen von Werten pro Sekunde aus jedem KDE. Ich habe es stark kommentiert, um die Portierung auf Python oder andere Sprachen zu unterstützen. Der Abtastalgorithmus selbst ist in der Funktionrdens
mit den Linien implementiertrkernel
ziehtn
IId Proben aus der Kernel - Funktion währendsample
ziehenn
Proben mit Ersatz aus den Datenx
. Der Operator "+" fügt die beiden Arrays von Samples Komponente für Komponente hinzu.Für diejenigen, die eine formelle Demonstration der Korrektheit wünschen, biete ich sie hier an. Es sei die Kernelverteilung mit CDF und die Daten seien . Nach der Definition einer Kernelschätzung ist die CDF der KDEF K x = ( x 1 , x 2 , … , x n )K FK x=(x1,x2,…,xn)
Das vorhergehende Rezept besagt, dass aus der empirischen Verteilung der Daten gezogen werden soll (dh es wird der Wert mit einer Wahrscheinlichkeit von für jedes ), unabhängig eine Zufallsvariable aus der Kernverteilung gezogen und summiert werden soll. Ich schulde Ihnen einen Beweis dafür, dass die Verteilungsfunktion von die des KDE ist. Beginnen wir mit der Definition und sehen, wohin sie führt. Sei eine beliebige reelle Zahl. Konditionierung auf gibtx i 1 / n i Y X + Y x X.X xi 1/n i Y X+Y x X
wie behauptet.
quelle
Sie probieren zuerst aus der CDF, indem Sie sie invertieren. Die inverse CDF wird als Quantilfunktion bezeichnet; Es ist eine Zuordnung von [0,1] zur Domäne des Wohnmobils. Anschließend werden zufällige einheitliche RVs als Perzentile abgetastet und an die Quantilfunktion übergeben, um eine zufällige Stichprobe aus dieser Verteilung zu erhalten.
quelle
Hier möchte ich auch den Matlab-Code veröffentlichen, der der von whuber beschriebenen Idee folgt, um denjenigen zu helfen, die mit Matlab besser vertraut sind als R.
Folgendes ist das Ergebnis:
Bitte sagen Sie mir, wenn jemand ein Problem mit meinem Verständnis und dem Code findet. Vielen Dank.
quelle
Ohne Ihre Implementierung zu genau zu betrachten, kann ich Ihr Indizierungsverfahren nicht vollständig aus dem ICDF ziehen. Ich denke, Sie ziehen aus der CDF, nicht es ist umgekehrt. Hier ist meine Implementierung:
quelle