主成分分析算法
- PCA的数学实现
主成分分析算法
PCA 减少 n 维到 k 维:
第一步是均值归一化。计算出所有特征的均值,然后令$x_j=x_j-\mu_j$。如果特征是在不同的数量级上,我们还需要将其除以标准差 $\sigma^2$。
第二步是计算协方差矩阵(covariance matrix)Σ:
第三步是计算协方差矩阵 Σ 的特征向量(eigenvectors): 可以利用奇异值分解(singular value decomposition)来求解,[U, S, V]= svd(sigma)。
对于一个 n×n 维度的矩阵,上式中的 U 是一个具有与数据之间最小投射误差的方向向量构成的矩阵。如果我们希望将数据从 n 维降至 k 维,我们只需要从 U 中选取前 K 个向量,获得一个 n×k 维度的矩阵,我们用 $U_{reduce}$表示,然后通过如下计算获得要求的新特征向量$z^{(i)}$:
其中 x 是 n×1 维的,因此结果为 k×1 维度。注,我们不对方差特征进行处理。
牛刀小试
我们来实现PCA算法
import numpy as np
def covariance_matrix(X):
"""
Args:
X (ndarray) (m, n)
Return:
cov_mat (ndarray) (n, n):
covariance matrix of X
"""
m = X.shape[0]
return (X.T @ X) / m
def normalize(X):
"""
for each column, X-mean / std
"""
X_copy = X.copy()
m, n = X_copy.shape
for col in range(n):
X_copy[:, col] = (X_copy[:, col] - X_copy[:, col].mean()) / X_copy[:, col].std()
return X_copy
def pca(x, keep_dims=None):
if not keep_dims:
keep_dims = x.shape[1] - 1
# todo 进行归一化
normalize_x = normalize(x)
# todo 求出协方差矩阵
cov_x = covariance_matrix(x)
# todo 奇异值分解
U, S, V = np.linalg.svd(cov_x) # U: principle components (n, n)
# todo 选取前 keep_dims 维特征
reduction = U[:, :keep_dims]
# todo 得到降维的结果
return np.matmul(x, reduction)
x = np.random.uniform(size=(10, 10))
pca(x).shape