Nehmen Sie 20 zufällige Punkte in einem 10.000-dimensionalen Raum mit jeder Koordinate iid aus . Teilen Sie sie in 10 Paare ("Paare") auf und addieren Sie den Durchschnitt jedes Paares ("ein Kind") zum Datensatz. Führen Sie dann PCA für die resultierenden 30 Punkte durch und zeichnen Sie PC1 gegen PC2.
Eine bemerkenswerte Sache passiert: Jede "Familie" bildet ein Triplett von Punkten, die alle nahe beieinander liegen. Natürlich ist jedes Kind im ursprünglichen 10.000-dimensionalen Raum näher an jedem seiner Eltern, so dass man erwarten kann, dass es auch im PCA-Raum nahe an den Eltern ist. Im PCA-Bereich ist jedoch auch jedes Elternpaar nahe beieinander, obwohl es sich im ursprünglichen Bereich nur um zufällige Punkte handelt!
Wie schaffen es Kinder, Eltern in der PCA-Projektion zusammenzubringen?
Man könnte befürchten, dass dies irgendwie durch die Tatsache beeinflusst wird, dass die Kinder eine niedrigere Norm haben als die Eltern. Dies scheint keine Rolle zu spielen: Wenn ich die Kinder als wobei und Elternpunkte sind, haben sie im Durchschnitt die gleiche Norm wie die Eltern. Aber ich beobachte qualitativ immer noch das gleiche Phänomen im PCA-Raum:
Diese Frage verwendet einen Spielzeugdatensatz, ist jedoch durch das motiviert, was ich in einem realen Datensatz aus einer genomweiten Assoziationsstudie (GWAS) beobachtet habe, in der Dimensionen Einzelnukleotidpolymorphismen (SNP) sind. Dieser Datensatz enthielt Mutter-Vater-Kind-Trios.
Code
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
def generate_families(n = 10, p = 10000, divide_by = 2):
X1 = np.random.randn(n,p) # mothers
X2 = np.random.randn(n,p) # fathers
X3 = (X1+X2)/divide_by # children
X = []
for i in range(X1.shape[0]):
X.extend((X1[i], X2[i], X3[i]))
X = np.array(X)
X = X - np.mean(X, axis=0)
U,s,V = np.linalg.svd(X, full_matrices=False)
X = U @ np.diag(s)
return X
n = 10
plt.figure(figsize=(4,4))
X = generate_families(n, divide_by = 2)
for i in range(n):
plt.scatter(X[i*3:(i+1)*3,0], X[i*3:(i+1)*3,1])
plt.tight_layout()
plt.savefig('families1.png')
plt.figure(figsize=(4,4))
X = generate_families(n, divide_by = np.sqrt(2))
for i in range(n):
plt.scatter(X[i*3:(i+1)*3,0], X[i*3:(i+1)*3,1])
plt.tight_layout()
plt.savefig('families2.png')