Ich benutze die Cholesky-Zerlegung, um korrelierte Zufallsvariablen bei gegebener Korrelationsmatrix zu simulieren. Die Sache ist, das Ergebnis reproduziert niemals die Korrelationsstruktur, wie sie gegeben ist. Hier ist ein kleines Beispiel in Python, um die Situation zu veranschaulichen.
import numpy as np
n_obs = 10000
means = [1, 2, 3]
sds = [1, 2, 3] # standard deviations
# generating random independent variables
observations = np.vstack([np.random.normal(loc=mean, scale=sd, size=n_obs)
for mean, sd in zip(means, sds)]) # observations, a row per variable
cor_matrix = np.array([[1.0, 0.6, 0.9],
[0.6, 1.0, 0.5],
[0.9, 0.5, 1.0]])
L = np.linalg.cholesky(cor_matrix)
print(np.corrcoef(L.dot(observations)))
Dies druckt:
[[ 1. 0.34450587 0.57515737]
[ 0.34450587 1. 0.1488504 ]
[ 0.57515737 0.1488504 1. ]]
Wie Sie sehen, unterscheidet sich die post-hoc geschätzte Korrelationsmatrix drastisch von der vorherigen. Befindet sich in meinem Code ein Fehler oder gibt es eine Alternative zur Verwendung der Cholesky-Dekomposition?
Bearbeiten
Ich bitte um Verzeihung für dieses Durcheinander. Ich dachte nicht, dass es einen Fehler im Code und / oder in der Art und Weise gab, wie die Cholesky-Zerlegung angewendet wurde, weil ich das Material, das ich zuvor studiert hatte, falsch verstanden hatte. Tatsächlich war ich mir sicher, dass die Methode selbst nicht genau sein sollte, und ich war damit bis zu der Situation einverstanden, die mich veranlasste, diese Frage zu stellen. Vielen Dank für den Hinweis auf das Missverständnis, das ich hatte. Ich habe den Titel bearbeitet, um die von @Silverfish vorgeschlagene reale Situation besser widerzuspiegeln.
quelle
Antworten:
Der Ansatz, der auf der Cholesky-Zerlegung basiert, sollte funktionieren, er wird hier beschrieben und in der Antwort von Mark L. Stone fast zeitgleich mit dieser Antwort veröffentlicht.
wo die letzten Züge sind, XY X Φ Σ Λ Σ Φ
Beispiel in
R
(Entschuldigung, ich verwende nicht dieselbe Software, die Sie in der Frage verwendet haben):Sie könnten auch an diesem Beitrag und diesem Beitrag interessiert sein .
quelle
Die Leute würden Ihren Fehler wahrscheinlich viel schneller finden, wenn Sie erklären würden, was Sie mit Worten und Algebra anstatt mit Code gemacht haben (oder zumindest mit Pseudocode schreiben).
Sie scheinen das Äquivalent dazu zu tun (obwohl möglicherweise transponiert):
Generiere einn×k Z
multiplizieren Sie die Spalten mitσi μi
berechneY=LX
Was Sie tun sollten, ist Folgendes:
Generiere einn×k Z
berechneX=LZ
multipliziere die Spalten mit und addiereσi μi
Es gibt viele Erklärungen für diesen Algorithmus vor Ort. z.B
Wie werden korrelierte Zufallszahlen generiert (gegebene Mittelwerte, Varianzen und Grad der Korrelation)?
Kann ich die Cholesky-Methode verwenden, um korrelierte Zufallsvariablen mit dem angegebenen Mittelwert zu erzeugen?
Dieser diskutiert es direkt in Bezug auf die gewünschte Kovarianzmatrix und gibt auch einen Algorithmus zum Erhalten einer gewünschten Sample- Kovarianz an:
Generieren von Daten mit einer bestimmten Stichproben-Kovarianzmatrix
quelle
An der Cholesky-Faktorisierung ist nichts auszusetzen. In Ihrem Code ist ein Fehler aufgetreten. Siehe unten bearbeiten.
Hier ist der MATLAB-Code und die Ergebnisse, zuerst für n_obs = 10000 wie Sie, dann für n_obs = 1e8. Der Einfachheit halber kümmere ich mich nicht um die Mittelwerte, da sie die Ergebnisse nicht beeinflussen, dh ich mache sie zu Nullen. Beachten Sie, dass MATLABs chol einen oberen dreieckigen Cholesky-Faktor R der Matrix M erzeugt, so dass R '* R = M. numpy.linalg.cholesky einen unteren dreieckigen Cholesky-Faktor erzeugt, so dass eine Anpassung gegenüber meinem Code erforderlich ist; aber ich glaube, Ihr Code ist in dieser Hinsicht in Ordnung.
Edit: Ich habe deinen Fehler gefunden. Sie haben die Standardabweichung falsch angewendet. Dies ist das Äquivalent zu dem, was Sie getan haben, was falsch ist.
quelle
In meinem Lebenslauf geht es nicht um Code, aber ich war gespannt, wie dies nach all den guten Antworten und speziell nach dem Beitrag von @Mark L. Stone aussehen würde. Die eigentliche Antwort auf die Frage finden Sie auf seinem Beitrag (im Zweifelsfall bitte seinen Beitrag gutschreiben). Ich verschiebe diese angehängten Informationen hierher, um den Abruf dieses Beitrags in Zukunft zu erleichtern. Ohne eine der anderen hervorragenden Antworten herunterzuspielen, wird das Problem nach Marks Antwort durch die Korrektur des Postens im OP behoben.
Quelle
IN PYTHON:
IN [R]:
quelle
Wie schon andere gezeigt haben: cholesky works. Hier ein Teil des Codes, der sehr kurz und sehr nahe am Pseudocode ist: ein Codeteil in MatMate:
quelle