Pegue 20 pontos aleatórios em um espaço de 10.000 dimensões com cada ID de coordenada de . Divida-os em 10 pares ("casais") e adicione a média de cada par ("um filho") ao conjunto de dados. Em seguida, faça o PCA nos 30 pontos resultantes e plote PC1 vs PC2.
Uma coisa notável acontece: cada "família" forma um trio de pontos que estão todos juntos. É claro que toda criança está mais próxima de cada um de seus pais no espaço original de 10.000 dimensões, de modo que se poderia esperar que ele estivesse perto dos pais também no espaço da PCA. No entanto, no espaço da PCA, cada par de pais também está próximo, embora no espaço original sejam apenas pontos aleatórios!
Como as crianças conseguem reunir os pais na projeção do PCA?
Pode-se preocupar que isso seja de alguma forma influenciado pelo fato de os filhos terem uma norma mais baixa que os pais. Isso não parece ser a questão: se eu produzir as crianças como onde e são pontos dos pais, então eles vão ter, em média, a mesma norma como os pais. Mas ainda observo qualitativamente o mesmo fenômeno no espaço da APC:
Essa pergunta está usando um conjunto de dados de brinquedos, mas é motivada pelo que observei em um conjunto de dados do mundo real de um estudo de associação genômica (GWAS) em que as dimensões são polimorfismos de nucleotídeo único (SNP). Esse conjunto de dados continha trios mãe-pai-filho.
Código
%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')