Візьміть 20 випадкових точок у 10-мірному просторі з кожною координатною лінією від . Розділіть їх на 10 пар ("пари") і додайте до набору даних середнє значення кожної пари ("дитина"). Потім зробіть PCA на отриманих 30 очках і побудуйте графік PC1 проти PC2.
Відбувається чудова річ: кожна «родина» утворює трійку точок, які всі зближені. Звичайно, кожна дитина ближче до кожного з своїх батьків у оригінальному 10-мірному просторі, так що можна було очікувати, що вона буде близькою до батьків також у просторі PCA. Однак у просторі PCA кожна пара батьків також близька разом, хоча в оригінальному просторі вони є лише випадковими точками!
Як дітям вдається зібрати батьків у проекції PCA?
Можна турбуватися, що на це якимось чином впливає той факт, що у дітей нижча норма, ніж у батьків. Це, мабуть, не має значення: якщо я виховую дітей як де і є батьківськими пунктами, то вони матимуть у середньому ту саму норму, що й батьки. Але я все ще якісно спостерігаю те саме явище в просторі PCA:
Це питання використовує набір даних про іграшки, але його мотивує те, що я спостерігав у наборі даних у реальному світі від дослідження асоціації, пов’язаного з геном (GWAS), де розміри є одноядерними поліморфізмами (SNP). Цей набір даних містив тріо матері-батька-дитини.
Код
%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')