Wie ordne ich 2D-Daten neu an, um eine Korrelation zu erhalten?

9

Ich habe den folgenden einfachen Datensatz mit zwei kontinuierlichen Variablen; dh:

d = data.frame(x=runif(100,0,100),y = runif(100,0,100))
plot(d$x,d$y)
abline(lm(y~x,d), col="red")
cor(d$x,d$y) # = 0.2135273

Basisverteilung

Ich muss die Daten so umordnen, dass die Korrelation zwischen Variablen ~ 0,6 beträgt. Ich muss die Mittelwerte und andere beschreibende Statistiken (sd, min, max usw.) Beide Variablen konstant halten.

Ich weiß, dass es möglich ist, fast jede Korrelation mit den angegebenen Daten herzustellen, dh:

d2 = with(d,data.frame(x=sort(x),y=sort(y)))
plot(d2$x,d2$y)
abline(lm(y~x,d2), col="red")
cor(d2$x,d2$y) # i.e. 0.9965585

Geben Sie hier die Bildbeschreibung ein

Wenn ich versuche, die sampleFunktion für diese Aufgabe zu verwenden:

cor.results = c()
for(i in 1:1000){
    set.seed(i)
    d3 = with(d,data.frame(x=sample(x),y=sample(y)))
    cor.results =  c(cor.results,cor(d3$x,d3$y))
}

Ich bekomme ziemlich viele Korrelationen:

> summary(cor.results)
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-0.281600 -0.038330 -0.002498 -0.001506  0.034380  0.288800

Dieser Bereich hängt jedoch von der Anzahl der Zeilen im Datenrahmen ab und nimmt mit zunehmender Größe ab.

> d = data.frame(x=runif(1000,0,100),y = runif(1000,0,100))
> cor.results = c()
> for(i in 1:1000){
+ set.seed(i)
+ d3 = with(d,data.frame(x=sample(x),y=sample(y)))
+ cor.results =  c(cor.results,cor(d3$x,d3$y))
+ }
> summary(cor.results)
      Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
-0.1030000 -0.0231300 -0.0005248 -0.0005547  0.0207000  0.1095000

Meine Frage ist:

Wie ordne ich einen solchen Datensatz neu an, um eine gegebene Korrelation zu erhalten (dh 0,7)? (Es ist auch gut, wenn die Methode die Abhängigkeit von der Datensatzgröße beseitigt.)

Yuriy Petrovskiy
quelle

Antworten:

6

Hier ist eine Möglichkeit, die Daten neu anzuordnen, die auf der Generierung zusätzlicher Zufallszahlen basieren.

Wir ziehen Proben aus einer bivariaten Normalverteilung mit spezifizierter Korrelation. Als nächstes berechnen wir die Ränge der erhaltenen und Werte. Diese Ränge werden verwendet, um die ursprünglichen Werte zu ordnen. Für diesen Ansatz müssen wir sowohl die ursprünglichen als auch die Werte von oben sortieren .xyxy

Zuerst erstellen wir den eigentlichen Datensatz (wie in Ihrem Beispiel).

set.seed(1)
d <- data.frame(x = runif(100, 0, 100), y = runif(100, 0, 100))

cor(d$x, d$y)
# [1] 0.01703215

Nun geben wir eine Korrelationsmatrix an.

corr <- 0.7  # target correlation
corr_mat <- matrix(corr, ncol = 2, nrow = 2)
diag(corr_mat) <- 1
corr_mat
#      [,1] [,2]
# [1,]  1.0  0.7
# [2,]  0.7  1.0

Wir generieren zufällige Daten nach einer bivariaten Normalverteilung mit , (für beide Variablen) und der angegebenen Korrelation. In R kann dies mit der Funktion aus dem Paket erfolgen. Wir verwenden, um anzuzeigen, dass die Korrelation die empirische Korrelation ist (nicht die Populationskorrelation).μ=0σ=1mvrnormMASSempirical = TRUE

library(MASS)
mvdat <- mvrnorm(n = nrow(d), mu = c(0, 0), Sigma = corr_mat, empirical = TRUE)

cor(mvdat)
#      [,1] [,2]
# [1,]  1.0  0.7
# [2,]  0.7  1.0

Die Zufallsdaten stimmen perfekt mit der angegebenen Korrelation überein.

Als nächstes berechnen wir die Ränge der Zufallsdaten.

rx <- rank(mvdat[ , 1], ties.method = "first")
ry <- rank(mvdat[ , 2], ties.method = "first")

Um die Ränge für die Originaldaten zu verwenden d, müssen wir die Originaldaten sortieren.

dx_sorted <- sort(d$x)
dy_sorted <- sort(d$y)

Jetzt können wir die Ränge verwenden, um die Reihenfolge der sortierten Daten festzulegen.

cor(dx_sorted[rx], dy_sorted[ry])
# [1] 0.6868986

Die erhaltene Korrelation stimmt nicht perfekt mit der angegebenen überein, aber der Unterschied ist relativ gering.

Hier dx_sorted[rx]und dy_sorted[ry]sind neu abgetastete Versionen der Originaldaten in d.

Sven Hohenstein
quelle
2
+1 Das ist ziemlich cool. Die Schritte sind 1) Generieren normaler Daten mit der richtigen Pearson-Korrelation, 2) Erstellen der Originaldaten und der generierten Daten, die genau mit Rangkorrelationen übereinstimmen, 3) Originaldaten haben jetzt ungefähr dieselbe Pearson-Korrelation. Warum funktioniert das? Gibt es ein Analyseergebnis, das besagt, dass dies der Fall ist? Grenzen von Ungleichungen, die die verschiedenen Korrelationsmaße für gut erzogene Verteilungen nahe beieinander halten, oder so?
Bill
1
@ Bill Ich kann den Ansatz nicht analytisch erklären. Es ist nur eine Idee, die mir in den Sinn kam. Sie haben die Schritte jedoch gut zusammengefasst. Vielen Dank.
Sven Hohenstein
2

Um zwei gleichmäßige Verteilungen mit einer bestimmten Korrelation zu erzeugen, funktioniert der Algorithmus von Ruscio & Kaczetow (2008). Sie liefern R-Code . Sie können dann mit einer einfachen linearen Funktion transformieren, um Ihr Ziel min, max, mean und SD zu erhalten.

Ruscio & Kaczetow-Algorithmus

Ich werde den bivariaten Fall zusammenfassen, aber er kann auch mit multivariaten Problemen funktionieren. Nicht korrelierte und werden mit einer beliebigen Form (z. B. Uniform) erzeugt. Dann werden und als bivariate Normalen mit einer Zwischenkorrelation erzeugt. und ersetzt durch und in einem Rang erhalt Mode. Stellen Sie die Zwischenkorrelation höher oder niedriger ein, je nachdem, ob r ( ) zu niedrig oder zu hoch ist. und werden als bivariate Normalen mit der neuen Zwischenkorrelation erzeugt. Wiederholen.XoYoX1Y1X1Y1X0Y0X1,Y1X2Y2

Beachten Sie, dass dies der Lösung von @Sven Hohenstein sehr ähnlich ist, außer dass es iterativ ist, sodass die Zwischenkorrelation der Zielkorrelation immer näher kommt, bis sie nicht mehr zu unterscheiden sind. Beachten Sie auch, dass dieser Algorithmus verwendet werden kann, um eine große Population (z. B. N = 1 Million) zu generieren, aus der kleinere Stichproben gezogen werden können. Dies ist nützlich, wenn Sie Stichprobenfehler benötigen.

Für einen verwandten Beitrag: Korrelation und nicht normale Verteilungen

Beschreibende Statistiken erhalten

Es gibt keine Garantie dafür, dass der Algorithmus genau die gleichen Beschreibungen liefert. Da jedoch der Mittelwert und die SD einer gleichmäßigen Verteilung durch Min und Max bestimmt werden, können Sie Min und Max einfach anpassen, um alles zu reparieren.

Lassen Sie und Ihre generierten Variablen aus der letzten Iteration des Ruscio & Kaczetow-Algorithmus sein, und Ihre endgültigen Variablen, die Sie (mit Zielbeschreibungen) haben , und und Ihre ursprünglichen Variablen in Ihrem Datensatz. XgYgXfYfXY

Berechnen Sie Xf=(Xgmin(X))(max(X)min(x))/(max(Xg)min(Xg))

Machen Sie dasselbe fürYf

Referenz:

Ruscio, J. & Kaczetow, W. (2008). Simulation multivariater nicht normaler Daten mithilfe eines iterativen Algorithmus. Multivariate Verhaltensforschung, 43, 355–381. doi: 10.1080 / 00273170802285693

Anthony
quelle
1

Ich vermute, wenn Sie "resample" sagen, meinen Sie "simulieren", was allgemeiner ist. Das Folgende ist die prägnanteste Methode, die ich kenne, um normale, bivariate Daten mit einer bestimmten Korrelation zu simulieren. Ersetzen Sie r und n durch Ihre eigenen gewünschten Werte.

r = .6
n = 1000
x = rnorm(n) 
z = rnorm(n) 
y = (r/(1-r^2)^.5)*x + z

cor(x,y)
plot(x,y)
abline(lm(y~x), col="red")
rolando2
quelle
3
Nein, ich meine wirklich "Resample". Ich muss die Mittelwerte und andere beschreibende Statistiken (sd, min, max) beider Variablen konstant halten. Die Frage wurde aktualisiert.
Yuriy Petrovskiy