主成分分析(PCA, Principal Component Analysis)和线性判别分析(LDA, Linear Discriminant Analysis)是两种常用的降维方法,它们虽然都用于数据降维,但核心思想和应用场景不同。
PCA(主成分分析)
PCA 是一种无监督学习方法,主要用于特征降维,以最大化数据的方差,同时减少信息损失。其核心思想是找到数据的主成分(方差最大的方向),然后对数据进行投影,从而降低维度。
PCA的步骤
- 将数据中心化(去均值)并标准化,以消除量纲影响。
- 衡量不同特征之间的相关性。
- 找到协方差矩阵的特征值和特征向量,特征向量代表数据的主方向,特征值表示该方向上的方差信息量。
- 根据特征值大小选择前 K K K个特征向量构成新的特征空间。
- 用选择的特征向量将原始数据投影到新的低维空间。
它不考虑类别标签,仅关注数据的整体分布,通过选择方差最大的方向来保留最多的信息。其主要作用是特征降维,去除冗余特征,并用于数据可视化,尤其适用于高维数据的降维处理,以便于后续分析和建模。
python
def pca(X:np.array, n_components:int) -> np.array:
"""
PCA 降维。
"""
# 1. 数据标准化(去均值)
X_mean = np.mean(X, axis=0)
X_centered = X - X_mean # (m, n)
# print(f'X_centered.shape: {X_centered.shape}')
# 2. 计算协方差矩阵
covariance_matrix = np.cov(X_centered, rowvar=False)
# 3. 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix)
# 4. 按特征值降序排序
sorted_indices = np.argsort(eigenvalues)[::-1]
top_eigenvectors = eigenvectors[:, sorted_indices[:n_components]] # (n, n_components)
# print(f'top_eigenvectors.shape: {top_eigenvectors.shape}')
# 5. 投影到新空间
X_pca = np.dot(X_centered, top_eigenvectors) # (m, n_components)
# print(f'X_pca.shape: {X_pca.shape}')
return X_pca
LDA (线性判别分析)
LDA 是一种有监督的降维方法,目标是在降维的同时最大化类别之间的可分性。与 PCA 不同,LDA 利用类别标签来优化数据投影,使得不同类别的样本尽可能分开。
LDA的步骤
- 计算类内散度矩阵 S W S_W SW
- 计算类间散度矩阵 S B S_B SB
- 求解投影方向
- 选择前 k k k个特征向量组成投影矩阵 W W W
它利用类别信息来优化数据投影,使得不同类别的样本在低维空间中尽可能分开。通过最大化类间距离并最小化类内方差,LDA能够增强类别可分性,因此广泛应用于分类任务,如人脸识别、文本分类等,有助于提高模型的分类性能。
python
def lda(X:np.array, y:np.array, n_components:int) -> np.array:
"""
LDA 降维
"""
# 获取类别列表
classes = np.unique(y)
n_features = X.shape[1]
# 计算总均值
mean_total = np.mean(X, axis=0)
# 计算类内散度矩阵 Sw 和 类间散度矩阵 Sb
S_W = np.zeros((n_features, n_features))
S_B = np.zeros((n_features, n_features))
for c in classes:
X_c = X[y == c] # 取出类别 c 的所有样本
mean_c = np.mean(X_c, axis=0) # 计算类别 c 的均值
S_W += np.cov(X_c, rowvar=False) * (X_c.shape[0] - 1) # 类内散度矩阵
mean_diff = (mean_c - mean_total).reshape(-1, 1)
S_B += X_c.shape[0] * (mean_diff @ mean_diff.T) # 类间散度矩阵
# 计算 Sw^-1 * Sb 的特征值和特征向量
eigvals, eigvecs = np.linalg.eig(np.linalg.inv(S_W) @ S_B)
# 选取前 n_components 个特征向量(按特征值降序排序)
sorted_indices = np.argsort(eigvals)[::-1]
W = eigvecs[:, sorted_indices[:n_components]]
# 投影数据到 LDA 低维空间
X_lda = X @ W
return X_lda, W
PCA vs. LDA
PCA | LDA | |
---|---|---|
类别信息 | 无监督,不考虑类别 | 有监督,利用类别信息 |
目标 | 最大化数据方差,保留最多信息 | 最大化类间距离,增强类别可分性 |
计算 | 计算协方差矩阵的特征值 | 计算类间/类内散度矩阵的特征值 |
应用场景 | 适用于降维、特征提取、数据压缩 | 适用于分类任务,提高模型性能 |