特征提取:主成分分析、因子分析

一句话概述

特征提取(Feature Extraction)与特征选择不同——它不是从原始特征中挑选子集,而是通过数学变换将原始特征映射到新的低维空间,生成全新的特征。主成分分析(PCA)和因子分析(Factor Analysis)是两种最经典的线性降维与特征提取方法:PCA 通过最大化方差寻找最优投影方向,因子分析通过揭示潜在变量来解释观测变量之间的相关性。特征提取是解决维度灾难、数据可视化和去噪的核心工具。

💡 核心要点:① PCA 是无监督的线性降维方法,通过协方差矩阵的特征分解找到方差最大的方向 ② 因子分析假设观测变量由少数潜在因子和特殊因子共同决定,更注重解释性 ③ PCA 保留方差最大,因子分析保留协方差结构 ④ 特征提取生成的新特征不可直接解释(是原始特征的线性组合),但保留了数据的主要信息

教学与演示

一、主成分分析(PCA)的原理

是什么:PCA(Principal Component Analysis)由 Karl Pearson 于 1901 年提出,是最常用的线性降维方法。它的核心思想是:找到一组正交的投影方向(主成分),使得数据在这些方向上的投影方差最大化。第一主成分方向是方差最大的方向,第二主成分方向是与第一主成分正交且方差次大的方向,以此类推。前 k 个主成分保留了数据中大部分的方差(信息)。

大白话 PCA 就像给数据「拍照」——从不同角度去看数据,找一个能让数据「拉开」最宽的角度(方差最大),这就是第一主成分。然后再找一个与第一个角度垂直、能拉开次宽的角度,这就是第二主成分。用前几个角度就能还原数据的大致轮廓。

为什么:PCA 的数学基础是协方差矩阵的特征值分解(或 SVD)。协方差矩阵的第 i 个特征向量就是第 i 主成分的方向,第 i 个特征值就是该方向上的方差。特征值越大,该方向包含的信息越多。PCA 将数据从原始 p 维空间投影到前 k 个特征向量张成的 k 维子空间,在最小化重构误差(L2 距离)的意义下是最优的。

怎么做

import numpy as np

# ========== 从零实现 PCA ==========
np.random.seed(42)

class SimplePCA:
    """从零实现主成分分析(PCA)"""
    def __init__(self, n_components=2):
        self.n_components = n_components  # 保留的主成分数量
        self.components = None  # 主成分方向(特征向量)
        self.mean = None  # 数据均值
        self.explained_variance = None  # 各主成分的方差(特征值)
    
    def fit(self, X):
        """
        计算 PCA 的投影矩阵
        X: (n_samples, n_features) 特征矩阵
        """
        # 第一步:数据中心化(减去均值)
        self.mean = np.mean(X, axis=0)
        X_centered = X - self.mean
        
        # 第二步:计算协方差矩阵
        # C = (1/(n-1)) * X^T X
        n_samples = X.shape[0]
        cov_matrix = np.dot(X_centered.T, X_centered) / (n_samples - 1)
        
        # 第三步:对协方差矩阵进行特征值分解
        eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
        # eigh 返回的特征值按升序排列,需要反转
        eigenvalues = eigenvalues[::-1]
        eigenvectors = eigenvectors[:, ::-1]
        
        # 第四步:取前 n_components 个特征向量作为主成分
        self.components = eigenvectors[:, :self.n_components]
        self.explained_variance = eigenvalues[:self.n_components]
        
        return self
    
    def transform(self, X):
        """将数据投影到主成分空间"""
        X_centered = X - self.mean
        return np.dot(X_centered, self.components)
    
    def fit_transform(self, X):
        """先 fit 再 transform"""
        self.fit(X)
        return self.transform(X)
    
    def inverse_transform(self, X_transformed):
        """从主成分空间重构回原始空间(有信息损失)"""
        return np.dot(X_transformed, self.components.T) + self.mean
    
    def explained_variance_ratio(self):
        """各主成分的方差解释比例"""
        return self.explained_variance / self.explained_variance.sum()

# ========== 演示 PCA 在合成数据上的应用 ==========
# 生成沿某个方向拉长的二维数据(高度相关)
n_samples = 200
# 生成二维数据,其中两个特征高度相关
base = np.random.randn(n_samples, 2)
# 通过线性变换制造相关性
transform_matrix = np.array([[2, 1.5], [1.5, 1]])  # 使特征1和特征2高度相关
X = np.dot(base, transform_matrix)

pca = SimplePCA(n_components=2)
X_transformed = pca.fit_transform(X)

print("=== PCA 降维演示 ===")
print(f"原始数据形状: {X.shape}")
print(f"降维后形状: {X_transformed.shape}")
print(f"\n协方差矩阵的特征值: {pca.explained_variance}")
print(f"方差解释比例: {pca.explained_variance_ratio()}")
print(f"\n第一主成分方向: {pca.components[:, 0]}")
print(f"第二主成分方向: {pca.components[:, 1]}")

# 验证重构误差
X_reconstructed = pca.inverse_transform(X_transformed)
reconstruction_error = np.mean((X - X_reconstructed) ** 2)
print(f"\n重构误差(MSE): {reconstruction_error:.6f}")

# 仅用第一主成分重构(降维到1维再还原)
pca_1d = SimplePCA(n_components=1)
X_1d = pca_1d.fit_transform(X)
X_reconstructed_1d = pca_1d.inverse_transform(X_1d)
error_1d = np.mean((X - X_reconstructed_1d) ** 2)
print(f"仅用第1主成分重构误差: {error_1d:.6f}")
print(f"信息损失: {error_1d / reconstruction_error:.1f} 倍")
\text{PCA 的协方差矩阵特征分解}\(C = \frac{1}{n-1} X^T X = V \Lambda V^T, \quad \Lambda = \text{diag}(\lambda_1, \lambda_2, \ldots, \lambda_p)\)
大白话 PCA 就是在问数据「你最「散」的方向是哪个?」——找到数据分布最宽的方向,把它作为新的坐标轴。这样用最少的坐标轴就能描述数据的大致分布。

什么用:在 AI 工业中,PCA 广泛用于:① 数据可视化——将高维数据(如 100 维特征向量)降到 2D/3D 用于可视化分析,② 去噪——保留前几个主成分(信号),丢弃后面的主成分(噪声),③ 加速训练——在几乎不损失信息的前提下将特征从 1000 维降到 50 维,大幅减少训练时间,④ 特征去相关——PCA 后的主成分互不相关,这对某些模型(如线性回归)有好处。

哪些坑:PCA 是线性变换,无法捕捉非线性结构。主成分是不可解释的——它们是原始特征的线性组合,没有物理意义。PCA 对数据缩放敏感——如果特征尺度不同,必须先标准化(Z-score)。PCA 假设数据在低维线性子空间中,如果数据是流形结构(如瑞士卷),PCA 会失效。

二、PCA 的方差解释与主成分选择

是什么:PCA 降维后,需要决定保留多少个主成分。常用的方法有:① 累积方差解释比例——选择使累积方差达到阈值(如 95%)的最少主成分数,② 碎石图(Scree Plot)——绘制特征值曲线,找到「肘部」拐点,③ Kaiser 准则——保留特征值大于 1 的主成分(仅适用于标准化数据)。

大白话 选主成分就像「压缩图片」——保留的信息越多,文件越大。你需要权衡:保留 95% 的信息(丢掉 5% 的细节),可以节省大量存储空间,但画面质量几乎不受影响。

为什么:累积方差解释比例是最直观的准则——如果前 k 个主成分解释了 95% 的总方差,说明数据在原始 p 维空间中实际上「生活」在一个 k 维子空间附近。碎石图的「肘部」之后,特征值迅速下降,说明后续主成分贡献的信息量很小,可能是噪声。

怎么做

import numpy as np

# ========== 演示 PCA 主成分数量的选择 ==========
np.random.seed(42)

def pca_component_selection_demo():
    """演示如何选择 PCA 的主成分数量"""
    n_samples = 200
    n_features = 10
    
    # 生成数据:10个特征,但只有3个独立维度
    # 通过线性变换,将3个独立信号映射到10个特征
    true_dim = 3
    latent = np.random.randn(n_samples, true_dim)  # 3个潜在因子
    # 随机投影矩阵:3 → 10
    projection = np.random.randn(true_dim, n_features)
    X = np.dot(latent, projection) + np.random.randn(n_samples, n_features) * 0.3
    
    # 标准化数据
    X_std = (X - X.mean(axis=0)) / X.std(axis=0)
    
    # 计算协方差矩阵和特征值
    cov = np.dot(X_std.T, X_std) / (n_samples - 1)
    eigenvalues = np.linalg.eigvalsh(cov)[::-1]  # 降序排列
    
    # 累积方差解释比例
    total_var = eigenvalues.sum()
    cum_var_ratio = np.cumsum(eigenvalues) / total_var
    
    print("=== PCA 主成分数量选择 ===")
    print(f"特征总数: {n_features}, 真实维度: {true_dim}")
    print()
    print(f"{'主成分':<8} {'特征值':<10} {'方差比例':<10} {'累积比例':<10}")
    print("-" * 42)
    for i in range(n_features):
        ratio = eigenvalues[i] / total_var
        cum = cum_var_ratio[i]
        marker = " ← 肘部" if i == true_dim else ""
        print(f"PC{i+1:<7} {eigenvalues[i]:<10.3f} {ratio:<10.3f} {cum:<10.3f}{marker}")
    
    print()
    print("选择方法:")
    # 方法1:累积方差 95% 阈值
    k_95 = np.searchsorted(cum_var_ratio, 0.95) + 1
    print(f"  方法1 - 累积方差 95%: 保留 {k_95} 个主成分")
    
    # 方法2:Kaiser 准则(特征值 > 1)
    # 注意:仅在标准化数据上有效(每个特征方差=1)
    k_kaiser = np.sum(eigenvalues > 1)
    print(f"  方法2 - Kaiser 准则: 保留 {k_kaiser} 个主成分(特征值>1的)")
    
    # 方法3:肘部法则
    # 计算特征值之间的差值
    diffs = np.diff(eigenvalues)
    elbow = np.argmin(diffs) + 1  # 最大下降处
    print(f"  方法3 - 肘部法则: 约 {elbow} 个主成分")
    
    print(f"\n推荐:方法1和方法3通常最可靠,本题中真实维度恰为 {true_dim}")

pca_component_selection_demo()
\text{累积方差解释比例}\(\text{CumVar}(k) = \frac{\sum_{i=1}^{k} \lambda_i}{\sum_{i=1}^{p} \lambda_i} \times 100\%\)
大白话 选择主成分数量就像「压缩照片分辨率」——降到多少像素还能看清内容?95% 的方差保留意味着你只丢了 5% 的细节,肉眼几乎看不出来,但数据维度从 1000 降到了 20,模型训练快了 50 倍。

三、因子分析(Factor Analysis)

是什么:因子分析(Factor Analysis)与 PCA 目标不同——它不是最大化方差,而是试图解释观测变量之间的相关性结构。因子分析假设每个观测变量由少数几个潜在因子(Latent Factors)的线性组合加上一个特殊因子(Unique Factor)构成。模型形式为:X = μ + L·F + ε,其中 L 是因子载荷矩阵,F 是公共因子,ε 是特殊因子。

大白话 PCA 问「数据在哪方差最大」,因子分析问「为什么这些变量会相关」。比如学生的数学、物理、化学成绩都相关——因子分析认为这是因为它们背后有一个「理科能力」的潜在因子。PCA 是「压缩」,因子分析是「解释」。

为什么:因子分析的数学基础是协方差矩阵的分解:Σ = L·L^T + Ψ,其中 Σ 是观测变量的协方差矩阵,L 是因子载荷矩阵,Ψ 是特殊方差的对角矩阵(表示每个变量独有的、不能被公因子解释的部分)。与 PCA 不同,因子分析关心的是 L·L^T 能否很好地近似 Σ(而不仅仅是方差最大的方向)。因子分析通常使用最大似然估计或主轴因子法求解。

怎么做

import numpy as np

# ========== 演示因子分析的原理 ==========
np.random.seed(42)

def factor_analysis_demo():
    """演示因子分析的核心思想:用潜在变量解释相关性"""
    print("=== 因子分析演示 ===")
    
    n_samples = 500
    n_observed = 6  # 观测变量(如6门考试成绩)
    n_factors = 2   # 潜在因子(如「理科能力」和「文科能力」)
    
    # 生成潜在因子(不可观测)
    F = np.random.randn(n_samples, n_factors)
    # F[:, 0] = 理科能力, F[:, 1] = 文科能力
    
    # 因子载荷矩阵 L(6×2):每个观测变量在各因子上的载荷
    L = np.array([
        [0.9, 0.1],  # 数学:主要由理科能力决定
        [0.8, 0.2],  # 物理:主要由理科能力决定
        [0.7, 0.1],  # 化学:主要由理科能力决定
        [0.1, 0.9],  # 语文:主要由文科能力决定
        [0.2, 0.8],  # 英语:主要由文科能力决定
        [0.3, 0.7],  # 历史:主要由文科能力决定
    ])
    
    # 特殊因子(各科独有的部分,如考试当天的状态)
    unique_var = np.array([0.1, 0.15, 0.2, 0.1, 0.15, 0.2])
    epsilon = np.random.randn(n_samples, n_observed) * np.sqrt(unique_var)
    
    # 生成观测变量:X = F·L^T + ε
    X = np.dot(F, L.T) + epsilon
    
    # 计算观测变量的协方差矩阵
    cov_observed = np.cov(X.T)
    
    print("观测变量的协方差矩阵:")
    print("可以看到:数学/物理/化学之间相关性高(理科组),语文/英语/历史之间相关性高(文科组)")
    print(np.array2string(cov_observed, precision=2, suppress_small=True))
    print()
    
    print("因子载荷矩阵 L(真实值):")
    print("       理科因子  文科因子")
    subjects = ["数学", "物理", "化学", "语文", "英语", "历史"]
    for i, subj in enumerate(subjects):
        print(f"  {subj}:  {L[i, 0]:.1f}      {L[i, 1]:.1f}")
    
    print()
    print("因子分析的协方差分解: Σ = L·L^T + Ψ")
    print("  L·L^T: 公共因子解释的协方差(相关性结构)")
    print("  Ψ: 特殊方差(每个变量独有的部分,对角矩阵)")
    
    print()
    print("=== PCA vs 因子分析 ===")
    print("PCA:")
    print("  - 目标: 最大化方差")
    print("  - 假设: 无概率模型假设")
    print("  - 新变量: 主成分(原始变量的线性组合)")
    print("  - 用途: 降维、去噪、可视化")
    print()
    print("因子分析:")
    print("  - 目标: 解释协方差结构")
    print("  - 假设: 存在潜在因子 + 特殊因子")
    print("  - 新变量: 潜在因子(不可直接观测)")
    print("  - 用途: 探索性分析、构建潜变量模型")

factor_analysis_demo()
\text{因子分析模型}\(X = \mu + LF + \varepsilon, \quad \text{Cov}(X) = LL^T + \Psi\)
大白话 PCA 是「把数据压缩」,因子分析是「给数据找原因」。PCA 告诉你「这几个变量加在一起包含了大部分信息」,因子分析告诉你「这几个变量之所以相关,是因为背后有一个共同的隐藏因素」。

什么用:因子分析在心理学(智力测验、人格测评)、金融(资产定价 Fama-French 三因子模型)、市场营销(消费者偏好分析)等领域有广泛应用。在 AI 中,因子分析的思想启发了概率 PCA(PPCA)和变分自编码器(VAE)等生成模型——它们都假设观测数据由低维潜在变量生成。

哪些坑:因子分析需要假设因子数量(通常通过平行分析或信息准则确定),因子载荷矩阵的旋转(如 Varimax 旋转)会影响可解释性。因子分析对样本量要求较高(通常 n > 5p),小样本下估计不稳定。因子分析是线性模型,无法捕捉非线性关系。

四、PCA 与因子分析的实践对比

是什么:PCA 和因子分析虽然都用于降维,但它们的数学原理、输出结果和适用场景有本质区别。PCA 的主成分是原始变量的线性组合,因子分析的潜在因子不是直接可观测的。PCA 更适合作数据预处理,因子分析更适合探索性数据分析。

大白话 如果你只是想「压缩数据」让模型跑得更快,用 PCA。如果你想「理解数据」——为什么这些变量会相关、背后有什么隐藏因素——用因子分析。

为什么:从协方差分解的角度看:PCA 只分解方差(没有误差项),Σ = VΛV^T,所有主成分加起来完美重构协方差矩阵;因子分析分解为共同部分和特殊部分,Σ = LL^T + Ψ,模型允许误差。在数据有测量噪声时,因子分析的模型假设更合理。

怎么做

import numpy as np

# ========== PCA 与因子分析的实际对比 ==========
np.random.seed(42)

def pca_vs_fa_comparison():
    """对比 PCA 和因子分析在相同数据上的表现"""
    n_samples = 200
    
    # 生成数据:2个潜在因子 + 噪声
    latent = np.random.randn(n_samples, 2)
    # 5个观测变量由2个潜在因子生成
    loadings = np.array([
        [0.9, 0.1],  # 变量1
        [0.8, 0.2],  # 变量2
        [0.7, 0.3],  # 变量3
        [0.3, 0.7],  # 变量4
        [0.1, 0.9],  # 变量5
    ])
    noise = np.random.randn(n_samples, 5) * 0.3
    X = np.dot(latent, loadings.T) + noise
    
    # 标准化
    X_std = (X - X.mean(axis=0)) / X.std(axis=0)
    
    # PCA
    cov = np.dot(X_std.T, X_std) / (n_samples - 1)
    eigvals, eigvecs = np.linalg.eigh(cov)
    eigvals = eigvals[::-1]
    eigvecs = eigvecs[:, ::-1]
    
    print("=== PCA 结果 ===")
    print(f"特征值: {eigvals[:3]}")
    print(f"方差解释: {eigvals[:2].sum() / eigvals.sum() * 100:.1f}%")
    print("PC1 载荷:", np.round(eigvecs[:, 0], 3))
    print("PC2 载荷:", np.round(eigvecs[:, 1], 3))
    print("解释:PCA 找到了方差最大的两个方向,但载荷没有简单结构")
    
    # 简化因子分析(用 PCA + Varimax 旋转近似)
    # 取前2个主成分,进行 Varimax 旋转
    L_pca = eigvecs[:, :2] * np.sqrt(eigvals[:2])  # 未旋转的载荷
    
    # 简化 Varimax 旋转(实际中更复杂)
    def varimax_rotation(L, max_iter=50):
        """简化的 Varimax 旋转,使载荷矩阵更「简单」"""
        L_rot = L.copy()
        n_features, n_factors = L.shape
        for _ in range(max_iter):
            for j in range(n_factors):
                for k in range(j + 1, n_factors):
                    # 计算旋转角度
                    u = L_rot[:, j]**2 - L_rot[:, k]**2
                    v = 2 * L_rot[:, j] * L_rot[:, k]
                    A = np.sum(u)
                    B = np.sum(v)
                    C = np.sum(u**2 - v**2)
                    D = 2 * np.sum(u * v)
                    angle = np.arctan2(D - 2*A*B/n_features, C - (A**2 - B**2)/n_features) / 4
                    # 旋转
                    cos_a, sin_a = np.cos(angle), np.sin(angle)
                    rot = np.array([[cos_a, -sin_a], [sin_a, cos_a]])
                    L_rot[:, [j, k]] = np.dot(L_rot[:, [j, k]], rot)
        return L_rot
    
    L_rotated = varimax_rotation(L_pca)
    
    print("\n=== 因子分析结果(PCA + Varimax 旋转) ===")
    print("旋转后载荷矩阵(更简单、更易解释):")
    print("       因子1   因子2")
    for i in range(5):
        f1 = L_rotated[i, 0]
        f2 = L_rotated[i, 1]
        print(f"  变量{i+1}: {f1:+.3f}  {f2:+.3f}")
    print("解释:旋转后,变量1-3主要加载在因子1上,变量4-5主要加载在因子2上")
    print("这与真实结构(前3个变量由因子1主导,后2个由因子2主导)一致!")

pca_vs_fa_comparison()
大白话 PCA 和因子分析就像「压缩照片」和「分析照片的构图」——PCA 把照片压缩成几个数字,因子分析告诉你照片里为什么会有这些元素。两者的数学工具类似(都是协方差矩阵分解),但出发点和使用场景完全不同。

概念关系图谱

方法目标数学工具输出主要用途
PCA最大化方差协方差矩阵特征分解主成分(线性组合)降维、去噪、可视化
因子分析解释协方差结构协方差矩阵分解 LL^T+Ψ潜在因子(不可观测)探索性分析、潜变量建模
截断 SVD最小化重构误差数据矩阵 SVD奇异向量稀疏矩阵降维
t-SNE保持局部结构概率分布匹配低维嵌入可视化(非线性)

重点答疑

Q1: PCA 和因子分析到底有什么区别?

四个维度:① 目标不同——PCA 最大化方差,因子分析解释协方差结构;② 模型不同——PCA 没有概率模型,因子分析有明确的生成模型;③ 输出不同——PCA 输出主成分(原始变量的线性组合),因子分析输出潜在因子(不可直接观测);④ 使用场景不同——PCA 适合数据预处理,因子分析适合探索性数据分析(如心理学量表构建)。

Q2: PCA 降维后信息丢失了多少?

PCA 的信息保留量可以通过累积方差解释比例量化。例如,前 k 个主成分解释了 95% 的方差,说明丢失了约 5% 的信息。但要注意:方差解释比例高不等于下游任务性能好——有时方差小的主成分反而包含对分类有用的判别信息(PCA 是无监督的,不利用标签)。

Q3: 数据做 PCA 之前必须标准化吗?

是的,如果特征尺度不同,必须标准化(Z-score 归一化)。PCA 对尺度敏感——如果一个特征的取值范围是 0-1000,另一个是 0-1,PCA 会几乎完全忽略后者,因为前者的方差远大于后者。标准化后所有特征方差为 1,PCA 平等对待所有特征。但如果特征本来就是同一尺度(如像素值 0-255),可以不做标准化。

章节单词汇总

英文音标术语/释义
PCA/ˌpiː.siːˈeɪ/Principal Component Analysis;主成分分析
Eigenvalue/ˈaɪɡənˌvæljuː/特征值;衡量主成分方向上的方差大小
Eigenvector/ˈaɪɡənˌvektər/特征向量;主成分的方向
Covariance Matrix/koʊˈveriəns ˈmeɪtrɪks/协方差矩阵;描述特征间线性关系
Scree Plot/skriː plɑːt/碎石图;特征值下降曲线
Factor Analysis/ˈfæktər əˈnæləsɪs/因子分析;用潜在因子解释相关性
Factor Loading/ˈfæktər ˈloʊdɪŋ/因子载荷;观测变量在因子上的权重
Varimax Rotation/ˈverɪmæks roʊˈteɪʃən/最大方差旋转;使载荷矩阵更简单
Explained Variance/ɪkˈspleɪnd ˈveriəns/解释方差;主成分保留的信息量

面试练习

Q1 [单选] PCA 的主成分方向是什么?

  • A. 数据均值的方向
  • B. 数据标准差最大的方向
  • C. 协方差矩阵的特征向量方向
  • D. 数据的最小二乘拟合方向
解答:PCA 的主成分方向是协方差矩阵的特征向量,按对应特征值(方差)降序排列。第一主成分是最大特征值对应的特征向量方向。

Q2 [单选] 关于 PCA 的方差解释比例,以下说法正确的是?

  • A. 所有主成分的方差解释比例之和为 50%
  • B. 所有主成分的方差解释比例之和为 100%
  • C. 第一个主成分的方差解释比例总是 100%
  • D. 方差解释比例与主成分数量无关
解答:PCA 保留所有主成分时,方差解释比例之和为 100%(因为特征向量张成整个空间)。降维时选取前 k 个主成分,保留的信息比例为前 k 个特征值之和除以总特征值之和。

Q3 [多选] PCA 的常见应用场景包括哪些?

  • A. 高维数据可视化(降维到 2D/3D)
  • B. 去噪(丢弃噪声成分)
  • C. 特征去相关(主成分间不相关)
  • D. 特征选择(从原始特征中选子集)
解答:PCA 用于降维可视化、去噪和去相关。但 PCA 生成的是新特征(主成分),不是从原始特征中选子集,因此不是特征选择方法。

Q4 [单选] 因子分析中,因子载荷(Factor Loading)表示什么?

  • A. 模型的计算复杂度
  • B. 观测变量与潜在因子之间的相关性或权重
  • C. 数据集的样本数量
  • D. 特征的数量
解答:因子载荷矩阵 L 中的元素 l_ij 表示观测变量 i 在潜在因子 j 上的载荷(权重),反映了变量与因子之间的关联强度。载荷绝对值越大,该因子对变量的解释力越强。

Q5 [单选] 在 PCA 中,数据的协方差矩阵的特征值代表什么?

  • A. 数据点的数量
  • B. 对应主成分方向上的方差大小
  • C. 特征之间的相关性
  • D. 模型的准确率
解答:特征值 λ_i 表示数据在对应特征向量(主成分)方向上的投影方差。λ_i 越大,该方向包含的信息越多。

Q6 [多选] 关于 PCA 和因子分析,以下哪些说法是正确的?

  • A. PCA 的目标是最大化方差,因子分析的目标是解释协方差结构
  • B. PCA 的主成分是原始变量的线性组合,因子分析的潜在因子不可直接观测
  • C. PCA 没有概率模型假设,因子分析有明确的生成模型
  • D. PCA 和因子分析的结果完全相同,只是名称不同
解答:PCA 和因子分析在目标、模型假设、输出形式上有本质区别,结果通常不同,不能混用。

Q7 [单选] 碎石图(Scree Plot)用于什么目的?

  • A. 评估模型准确率
  • B. 帮助选择 PCA 保留的主成分数量
  • C. 可视化原始数据分布
  • D. 检测异常值
解答:碎石图绘制特征值随主成分序号下降的曲线,通过寻找「肘部」(特征值急剧下降的拐点)来确定应该保留的主成分数量。

Q8 [单选] 为什么 PCA 前需要标准化数据?

  • A. 为了增加数据量
  • B. 因为 PCA 对特征尺度敏感,大尺度特征会主导主成分方向
  • C. 为了满足正态分布假设
  • D. 为了加快计算速度
解答:PCA 基于方差最大化,如果一个特征的取值范围远大于其他特征,其方差会远大于其他特征,PCA 会几乎完全被该特征主导。标准化使所有特征方差为 1,PCA 才能公平对待所有特征。

Q9 [多选] 选择 PCA 主成分数量的常用方法有哪些?

  • A. 累积方差解释比例达到阈值(如 95%)
  • B. 碎石图找「肘部」拐点
  • C. Kaiser 准则(保留特征值 > 1 的主成分)
  • D. 保留所有主成分,不做选择
解答:这三种都是选择主成分数量的常用方法。保留所有主成分等于不做降维,失去了 PCA 的意义。

Q10 [单选] PCA 的一个主要局限性是什么?

  • A. 计算速度太慢
  • B. 只能捕捉线性结构,无法处理非线性数据
  • C. 只能处理分类任务
  • D. 需要标签数据
解答:PCA 是线性降维方法,假设数据分布在一个低维线性子空间中。对于非线性结构(如瑞士卷数据),PCA 会失效,需要使用核 PCA 或 t-SNE 等非线性方法。