Weź 20 losowych punktów w przestrzeni 10 000 wymiarów z każdą współrzędną id matematyczną . Podziel je na 10 par („pary”) i dodaj średnią każdej pary („dziecka”) do zestawu danych. Następnie wykonaj PCA na uzyskanych 30 punktach i wykreśl PC1 vs PC2.
Dzieje się coś niezwykłego: każda „rodzina” tworzy trójkę punktów, które są ze sobą blisko. Oczywiście każde dziecko jest bliżej każdego z rodziców w oryginalnej przestrzeni 10 000-wymiarowej, więc można się spodziewać, że będzie blisko rodziców również w przestrzeni PCA. Jednak w przestrzeni PCA każda para rodziców również jest blisko siebie, chociaż w pierwotnej przestrzeni są to tylko losowe punkty!
Jak dzieci potrafią przyciągnąć rodziców do siebie w projekcji PCA?
Można się martwić, że na to w jakiś sposób wpływa fakt, że dzieci mają niższą normę niż rodzice. To nie wydaje się ważne: jeśli produkować dzieci jako , gdzie i są punkty rodzicielskie, wówczas będą miały przeciętnie tym samym normy jako rodziców. Ale nadal obserwuję jakościowo to samo zjawisko w przestrzeni PCA:
To pytanie wykorzystuje zestaw danych z zabawkami, ale jest motywowane tym, co zaobserwowałem w prawdziwym zestawie danych z badania asocjacyjnego całego genomu (GWAS), w którym wymiarami są polimorfizmy pojedynczego nukleotydu (SNP). Ten zestaw danych zawierał trio matka-ojciec-dziecko.
Kod
%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')