Erzeugung von zwei korrelierten Pseudozufallszahlen (mit Python-Beispiel)

Wenn Sie statistische numerische Experimente durchführen, möchten Sie möglicherweise korrelierte Zufallszahlen generieren. Eine schnelle Suche zeigt eine Methode mit Choleskey-Zerlegung. Dies ist eine Möglichkeit, mit einer beliebigen Anzahl von Variablen umzugehen, aber ich wollte nur die Variable $ 2 $, daher erkläre ich sie etwas matschiger [^ 1]. [^ 1]: Immerhin ist das Ergebnis dasselbe wie die Choleskey-Zerlegung für die Variable $ 2 $.

Überblick

Angenommen, Sie haben unabhängige Zufallszahlen $ X $ und $ Y $ mit einem Mittelwert von Null und gleicher Varianz. Zu diesem Zeitpunkt ist die Zufallszahl $ Z $, die mit $ X $ durch den Korrelationskoeffizienten $ \ rho $ korreliert und dieselbe Varianz aufweist

Z = \rho X + \sqrt{1 - \rho^2} Y

Sie können es so machen.

In diesem Artikel

Ich werde darüber schreiben.

Theorie

Für die unabhängigen Zufallszahlen $ X $ und $ Y $ ist der Durchschnitt Null und die Varianz ist der gleiche Wert, $ \ sigma ^ 2 $. Da $ X $ und $ Y $ unabhängig sind, sind Kovarianz und Korrelationskoeffizient Null.

Außerdem wird vorerst die Zufallszahl $ Z $, die Sie mit $ X $ korrelieren möchten, $ X $ und $ Y $ überlagert.

Z = a X + b Y

Ich werde es definieren als. $ a $ und $ b $ sind Konstanten.

Der Grund dafür ist, dass das Folgende für die folgenden extremen Beispiele gilt.

a b \rho
> 0 0 1
=0 \neq 0 0
< 0 0 -1

Wenn ich mir diese Tabelle anschaue, habe ich das Gefühl, dass ein freier Korrelationskoeffizient erzeugt werden kann, indem das Gleichgewicht zwischen $ a $ und $ b $ [^ 2] geändert wird. Der Ausdruck von $ Z $ oben ist also vielversprechend als Zufallszahl, die eine willkürliche Korrelation mit $ X $ hat.

Berechnen wir nun tatsächlich den Korrelationskoeffizienten $ \ rho $ zwischen $ X $ und $ Z $. Der Korrelationskoeffizient ist

\rho = \frac{\mathrm{Cov}[X, Z]}{\sqrt{\mathrm{Var}[X]} \sqrt{\mathrm{Var}[Z]}}

Es kann mit berechnet werden. Hier sind $ \ mathrm {Cov} $ und $ \ mathrm {Var} $ gemeinsam verteilt bzw. verteilt. Beginnen wir mit der Berechnung aus der Kovarianz.

\begin{align}
\mathrm{Cov}[X, Z] &= \mathrm{Cov}[X, a X + b Y] & (\because Z \Definition von)
\\
&= a \ \mathrm{Cov}[X, X] + b \ \mathrm{Cov}[X, Y] & (\because \mathrm{Cov} \Die Natur von)
\\
&= a \ \sigma^2 & (\because \mathrm{Cov}[X, X] = \mathrm{Var}[X] = \sigma^2, \mathrm{Cov}[X, Y] = 0)
\end{align}

Es ist eine verwirrende Berechnung, aber wenn Sie sie nicht verstehen, sollten Sie sie erreichen können, indem Sie zur Definition zurückkehren und ruhig rechnen. Wenn es ein Ärger ist, müssen Sie der Berechnung nicht folgen.

Auch in Bezug auf die Verteilung von $ Z $,

\begin{align}
\mathrm{Var}[Z] &= \mathrm{Var}[a X + b Y] & (\because Z \Definition von)
\\
&= a^2 \mathrm{Var}[X] + b^2 \mathrm{Var}[Y] & (\because \mathrm{Var} \Die Natur von)
\\
&= a^2 \sigma^2 + b^2 \sigma^2 &
\end{align}

Daher ist der Korrelationskoeffizient, den ich berechnen wollte

\begin{align}
\rho &= \frac{\mathrm{Cov}[X, Z]}{\sqrt{\mathrm{Var}[X]} \sqrt{\mathrm{Var}[Z]}}
\\
&= \frac{a \ \sigma^2}{\sqrt{\sigma^2} \sqrt{a^2 \sigma^2 + b^2 \sigma^2}}
\\
&= \frac{a}{\sqrt{a^2 + b^2}}
\end{align}

Und es war eine ziemlich schöne Zeremonie. Lösen dieser Gleichung für $ b $

b = \frac{\sqrt{1 - \rho^2}}{\rho} a

Es kann erhalten werden. Wenn Sie $ a = c \ rho $ setzen ($ c $ ist eine positive Konstante), nur um den Ausdruck zu bereinigen,

Z = c \left( \rho X + \sqrt{1 - \rho^2} Y \right)

Es kann erhalten werden. Dieses $ c $ ist ein Parameter zum Steuern der Verteilung von $ Z $ und tatsächlich

\begin{align}
\mathrm{Var}[Z] &= \mathrm{Var}\left[{c \left( \rho X + \sqrt{1 - \rho^2} Y \right)} \right]
\\
&= c^2 \left[ \rho^2 \sigma^2 + (1 - \rho) \sigma^2 \right]
\\
&= c^2 \sigma^2
\end{align}

Und bewirkt, dass die Varianz mit $ c ^ 2 $ multipliziert wird (dh die Standardabweichung mit $ c $ multipliziert wird). Wenn Sie dies auf $ 1 $ setzen, wird die Eröffnungsformel angezeigt

Z = \rho X + \sqrt{1 - \rho^2} Y

Kann erhalten werden.

[^ 2]: Die Freiheit liegt im Bereich von $ -1 $ bis $ 1 $.

Überprüfung

Lassen Sie uns nun überprüfen, ob die mit Python 3 tatsächlich erhaltenen Zufallszahlen unseren Wünschen entsprechen. Verwenden wir zunächst einheitliche Zufallszahlen für $ X $ und $ Y $.

import numpy as np
import numpy.random as rand
import matplotlib.pyplot as plt

size = int(1e3) # Size of the vector
rho_in = 0.6 # Correlation coefficient between two random variables

# Generate uniform random numbers with mean = 0
x = rand.rand(size) - 0.5
y = rand.rand(size) - 0.5

# Generate random numbers correlated with x
z = rho_in * x + (1 - rho_in ** 2) ** 0.5 * y

# Calculate stats
variance = np.var(z)
rho_out = np.corrcoef(x, z)[1][0]
print("variance: {}, correlation: {}".format(variance, rho_out))

# Plot results
fig, ax = plt.subplots()
ax.scatter(x, z, s=1)
ax.set_xlabel('X')
ax.set_ylabel('Z')
plt.show()

Das Ergebnis sieht so aus.

variance: 0.08332907524577293, correlation: 0.5952102586280674

Oh? Der Wert der Dispersion liegt auf halber Strecke. Der Korrelationskoeffizient scheint näher am Ziel zu liegen ($ 0,6 $). ..

Das sollte es sein. Die Verteilung von $ Z $ war dieselbe wie die Verteilung von $ X $. Jetzt ist $ X $ eine einheitliche Zufallszahl im Intervall $ [-0,5, 0,5] $ und ihre Varianz ist [1/12](http://www.geocities.jp/jun930/etc/varianceofrandom.html "1" Da die Verteilung der Zufallszahlen ") ist, wird ein Wert nahe $ 1/12 = 0,0833 ... $ ausgegeben.

Das resultierende $ Z $ - $ X $ -Diagramm sieht folgendermaßen aus. Da die einheitliche Zufallszahl zur einheitlichen Zufallszahl addiert wird, sieht sie wie ein paralleles Viereck aus. uniform_uniform_rho0.6.png

Wenn dir das nicht gefällt, gehe zu "y"

y = rand.randn(size) * (1 / 12) ** 0.5

Sie können es in eine normale Zufallszahl wie diese ändern. Die Standardabweichung einheitlicher Zufallszahlen wird angewendet, um die Varianzen von $ X $ und $ Y $ auszurichten.

Die Ausgabe ist unten. variance: 0.0823649369923887, correlation: 0.5983078612793685 uniform_normal_rho0.6.png

Das sieht ziemlich gut aus, also habe ich es benutzt.

Eine Einschränkung ist jedoch, dass die durch diese beiden Methoden erzeugten Zufallszahlen $ Z $ keine einheitlichen Zufallszahlen sind. Wenn sowohl $ X $ als auch $ Y $ einheitliche Zufallszahlen verwenden, sieht das Histogramm wie ein Trapez wie das folgende aus. histo_uniform_uniform_rho0.6.png

Dies ist auch der Fall, wenn eine normale Zufallszahl für $ Y $ verwendet wird, wodurch der Berg-Cado etwas gerundet aussieht.

Dies liegt daran, dass das Hinzufügen von zwei stochastischen Variablen, die unterschiedlichen Gleichverteilungen folgen, nicht immer zu einer Gleichverteilung führt (es ist wahr) und statistisch gesehen "[Reproduzierbarkeit](https: /) /ja.wikipedia.org/wiki/%E5%86%8D%E7%94%9F%E6%80%A7 "Reproduzierbarkeit-Wikipedia") ist nicht verfügbar. " Also wieder zwangsweise Es wird auch versucht, zu einer einheitlichen Zufallszahl zurückzukehren "Ein-Generation-Methode einheitlicher Zufallszahlen mit gegenseitiger Korrelation").

Welche Art von Verteilung reproduzierbar ist, ist zum Beispiel die Normalverteilung, die jeder liebt. $ X $ und $ Y $ sollten also reguläre Zufallszahlen sein! Das ist die folgende Version. Nun, das einzige, was sich geändert hat, ist das obere "x" und "y".

import numpy as np
import numpy.random as rand
import matplotlib.pyplot as plt

size = int(1e4) # Size of the vector
rho_in = 0.6 # Correlation coefficient between two random variables

# Generate normal random numbers
x = rand.randn(size)
y = rand.randn(size)

# Generate random numbers correlated with x
z = rho_in * x + (1 - rho_in ** 2) ** 0.5 * y

# Calculate stats
variance = np.var(z)
rho_out = np.corrcoef(x, z)[1][0]
print("variance: {}, correlation: {}".format(variance, rho_out))

# Plot results
fig, ax = plt.subplots()
ax.scatter(x, z, s=1)
ax.set_xlabel('X')
ax.set_ylabel('Z')
plt.show()

Die Ausgabe ist wie folgt. variance: 0.9884508169450733, correlation: 0.5936089719053868

Ich habe versucht, eine Korrelation von $ 0,6 $ mit einer normalen Zufallszahl mit einer Varianz von $ 1 $ zu erhalten, also ist es ziemlich nah! Wenn der Korrelationskoeffizient im Bereich von $ [-1, 1] $ liegt, kann er natürlich negativ oder $ 1 $ [^ 3] sein.

Klicken Sie hier für die Handlung. normal_normal_rho0.6.png

Ich werde vorerst auch ein Histogramm veröffentlichen. Die rot gepunktete Linie ist die theoretisch vorhergesagte Normalverteilung mit einem Mittelwert von Null und einer Varianz von $ 1 $. Es scheint dem guten Gefühl zu entsprechen! histo_normal_normal_rho0.6.png

[^ 3]: Wenn Sie für $ \ rho $ einen anderen Wert als $ [-1, 1] $ angeben, passiert übrigens etwas Seltsames. Wenn Sie interessiert sind, denken oder versuchen Sie es.

Zusammenfassung

Wie können wir korrelierte Zufallszahlen erstellen? Und warum? Ich habe gesehen. Leute, die nicht daran gewöhnt sind, mögen verwirrt sein, aber ich denke, dass es keinen Verlust bei der Berechnung der Streuung neuer Zufallszahlen aufgrund der Art der Streuung gibt (weil es eine einfachere Berechnung ist, als es aussieht). Wenn Sie von nun an Statistiken lernen möchten, können Sie den Berechnungen in diesem Artikel folgen.

Es wurde auch gefunden, dass eine einfache Kombination von einheitlichen Zufallszahlen zu einer seltsamen Verteilung führt. Ich habe die Versionen $ X $: einheitliche Zufallszahl und $ Y $: normale Zufallszahlen verwendet, da es sich um ein leichtes Experiment handelte, bei dem die Form der Verteilung nicht besonders wichtig war, bei denen jedoch normale Zufallszahlen verwendet wurden. Es kann doch schnell gehen.

Ich möchte es zusammen lesen

** Erzeugung von n korrelierten Pseudozufallszahlen (mit Python-Stichprobe) - Qiita ** Dies ist die Fortsetzung. Wie können $ n $ Zufallszahlen erstellt werden? Ich erkläre das.

Recommended Posts

Erzeugung von zwei korrelierten Pseudozufallszahlen (mit Python-Beispiel)
Generiere n korrelierte Pseudozufallszahlen (mit Python-Beispiel)
Generieren Sie Fibonacci-Zahlen mit Python-Closures, Iteratoren und Generatoren
Mit Python erstellte Beispieldaten
Generieren Sie XML (RSS) mit Python
Beurteilung von Primzahlen mit Python
Spielen Sie handschriftliche Zahlen mit Python Part 1
Testen mit Zufallszahlen in Python
[Python] Verbinde zwei Tabellen mit Pandas
[Python] Generiere ein Passwort mit Slackbot
Spielen Sie handschriftliche Zahlen mit Python Teil 2 (identifizieren)
Generieren Sie japanische Testdaten mit Python faker
Beispiel für die Wavelet-Konvertierung von Bildern in Python
Zusammenfassung des Bibliotheksvergleichs zum Generieren von PDF mit Python
Versuchen Sie, Python-Dokumente automatisch mit Sphinx zu generieren
Hinweis zum Formatieren von Zahlen mit der Python-Formatierungsfunktion
Beispiel für eine Slack-Benachrichtigung mit Python Lambda
Generieren Sie mit Python eine Einfügeanweisung aus CSV.
Beispielprogramm, das Syslog mit Python-Protokollierung ausgibt
FizzBuzz in Python3
Scraping mit Python
Statistik mit Python
Scraping mit Python
Python mit Go
Twilio mit Python
Python-Abschlussbeispiel
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
Spezifischer Beispielcode für die Arbeit mit SQLite3 in Python
[Python] Holen Sie sich die Zahlen im Diagramm mit OCR
[Python] Generieren Sie Zufallszahlen, die der Rayleigh-Verteilung folgen