Lấy 20 điểm ngẫu nhiên trong không gian 10.000 chiều với mỗi tọa độ iid từ . Chia chúng thành 10 cặp ("cặp vợ chồng") và thêm trung bình của mỗi cặp ("một đứa trẻ") vào bộ dữ liệu. Sau đó, làm PCA trên kết quả 30 điểm và vẽ PC1 so với PC2.
Một điều đáng chú ý xảy ra: mỗi "gia đình" tạo thành một bộ ba điểm gần nhau. Tất nhiên mọi đứa trẻ đều gần gũi hơn với mỗi cha mẹ của nó trong không gian 10.000 chiều ban đầu, vì vậy người ta có thể mong đợi nó gần với cha mẹ cũng trong không gian PCA. Tuy nhiên, trong không gian PCA, mỗi cặp cha mẹ cũng ở gần nhau, mặc dù trong không gian ban đầu, họ chỉ là những điểm ngẫu nhiên!
Làm thế nào để trẻ có thể kéo cha mẹ lại với nhau trong phép chiếu PCA?
Người ta có thể lo lắng rằng điều này bằng cách nào đó bị ảnh hưởng bởi thực tế là trẻ em có chỉ tiêu thấp hơn cha mẹ. Điều này dường như không quan trọng: nếu tôi sinh ra những đứa trẻ là trong đó và là điểm của cha mẹ, thì chúng sẽ có trung bình giống như cha mẹ. Nhưng tôi vẫn quan sát một cách định tính hiện tượng tương tự trong không gian PCA:
Câu hỏi này đang sử dụng một bộ dữ liệu đồ chơi nhưng nó được thúc đẩy bởi những gì tôi quan sát được trong một bộ dữ liệu trong thế giới thực từ một nghiên cứu kết hợp trên toàn bộ bộ gen (GWAS) trong đó kích thước là đa hình đơn nucleotide (SNP). Bộ dữ liệu này chứa bộ ba mẹ-con-con.
Mã
%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')