利用 MATLAB SVD 进行数据分析与降维 – wiki基地

利用 MATLAB SVD 进行数据分析与降维

奇异值分解 (Singular Value Decomposition, SVD) 是一种强大的矩阵分解技术,在数据分析和降维领域有着广泛的应用。它能够揭示数据内部的结构特性,帮助我们更有效地处理高维数据。MATLAB 作为一款强大的数值计算工具,为 SVD 提供了便捷的实现。

什么是奇异值分解 (SVD)?

SVD 将任意 $m \times n$ 的矩阵 $A$ 分解为以下三个矩阵的乘积:

$A = U \Sigma V^T$

其中:
* $U$ 是一个 $m \times m$ 的正交矩阵,其列向量称为左奇异向量
* $\Sigma$ 是一个 $m \times n$ 的对角矩阵,其对角线上的元素是矩阵 $A$ 的奇异值,通常按降序排列。非对角线元素均为零。
* $V$ 是一个 $n \times n$ 的正交矩阵,其列向量称为右奇异向量。$V^T$ 是 $V$ 的转置。

奇异值的大小反映了数据在相应方向上的重要性或“能量”。较大的奇异值对应于数据中变化最显著的方向,而较小的奇异值则可能与噪声或次要模式相关。

SVD 在数据分析与降维中的应用

SVD 在数据分析和降维方面具有诸多优势:

  1. 数据压缩:通过保留最大的几个奇异值及其对应的奇异向量,可以在不显著损失信息的前提下,大幅度减少数据的存储空间。
  2. 噪声消除:较小的奇异值通常被认为代表数据中的噪声。通过丢弃这些较小的奇异值,可以有效地过滤掉数据中的噪声,使主要模式更加突出。
  3. 特征提取:SVD 能够自动识别数据中最主要、最具代表性的特征或模式,这些提取出的特征可以作为后续机器学习算法的输入,提高模型性能。
  4. 提高算法效率:将高维数据降至低维空间后,可以在降低计算复杂度的同时,加速后续的数据处理和机器学习算法的运行。
  5. 与主成分分析 (PCA) 的关系:SVD 与 PCA 紧密相关。对中心化(即每列数据减去其均值)后的数据矩阵进行 SVD,其右奇异向量 $V$ 的列向量即为主成分,而奇异值则与协方差矩阵的特征值直接相关。因此,SVD 可以作为实现 PCA 的一种高效方法。

MATLAB 中的 SVD 实现

MATLAB 提供了 svd 函数来方便地执行奇异值分解。

1. 仅获取奇异值

如果您只需要矩阵的奇异值,可以使用单输出形式:

matlab
A = randn(5, 3); % 创建一个 5x3 的随机矩阵
s = svd(A); % 返回一个包含奇异值的列向量
disp('奇异值:');
disp(s);

2. 执行完整的 SVD

要获取 $U, \Sigma, V$ 三个矩阵,可以使用三输出形式:

“`matlab
A = randn(5, 3); % 创建一个 5×3 的随机矩阵
[U, S, V] = svd(A); % U: 左奇异向量, S: 奇异值对角矩阵, V: 右奇异向量
disp(‘U 矩阵 (左奇异向量):’);
disp(U);
disp(‘S 矩阵 (奇异值对角矩阵):’);
disp(S);
disp(‘V 矩阵 (右奇异向量):’);
disp(V);

% 验证分解: A 应该约等于 U * S * V’
A_reconstructed = U * S * V’;
disp(‘原始矩阵 A:’);
disp(A);
disp(‘重构矩阵 A_reconstructed:’);
disp(A_reconstructed);
disp(‘重构误差 (norm(A – A_reconstructed)):’);
disp(norm(A – A_reconstructed));
``
请注意,
S` 矩阵是一个对角矩阵,其对角线上的元素是奇异值。

3. 经济型 SVD (Economy-size SVD)

当处理非方阵(例如 $m > n$)时,完整的 $U$ 矩阵可能会非常大,其中包含一些对应零奇异值的列。经济型 SVD (Economy-size SVD) 只计算非零奇异值及其对应的奇异向量,从而节省计算资源和存储空间。

“`matlab
A = randn(10, 5); % 一个 10×5 的矩阵
[U_econ, S_econ, V_econ] = svd(A, ‘econ’); % 经济型 SVD
disp(‘经济型 SVD – U 矩阵大小:’);
disp(size(U_econ)); % 输出: 10×5
disp(‘经济型 SVD – S 矩阵大小:’);
disp(size(S_econ)); % 输出: 5×5
disp(‘经济型 SVD – V 矩阵大小:’);
disp(size(V_econ)); % 输出: 5×5

% 验证分解
A_reconstructed_econ = U_econ * S_econ * V_econ’;
disp(‘重构误差 (norm(A – A_reconstructed_econ)):’);
disp(norm(A – A_reconstructed_econ));
“`

SVD 进行数据降维的步骤与示例

假设我们有一个 $N$ 个样本、$M$ 个特征的数据集,表示为一个 $N \times M$ 的矩阵 $X$。

  1. 数据中心化 (可选但推荐)
    为了使 SVD 的结果更接近于 PCA,通常需要对数据进行中心化,即从每个特征(列)中减去其均值。

    matlab
    X = randn(100, 50); % 100 个样本,50 个特征的示例数据
    mean_X = mean(X);
    X_centered = X - mean_X;

  2. 执行 SVD
    对中心化后的数据矩阵执行经济型 SVD。

    matlab
    [U, S, V] = svd(X_centered, 'econ');

    在此,V 矩阵的列向量代表了数据的主成分方向。

  3. 选择主成分数量 (降维维度)
    通过分析奇异值来决定保留多少个维度(即主成分)。通常,我们会计算奇异值的累积贡献率,以确定解释大部分方差所需的最小维度。

    “`matlab
    singular_values = diag(S); % 提取奇异值
    explained_variance = singular_values.^2 / sum(singular_values.^2); % 计算每个奇异值解释的方差比例
    cumulative_explained_variance = cumsum(explained_variance); % 累积解释方差

    figure;
    plot(cumulative_explained_variance, ‘o-‘);
    xlabel(‘主成分数量’);
    ylabel(‘累积解释方差比例’);
    title(‘SVD 奇异值累积解释方差’);
    grid on;

    % 例如,选择解释 95% 方差所需的主成分数量
    num_components = find(cumulative_explained_variance >= 0.95, 1, ‘first’);
    fprintf(‘保留 %d 个主成分可以解释 %.2f%% 的方差。\n’, num_components, cumulative_explained_variance(num_components)*100);
    “`

  4. 构建降维后的数据
    选择前 num_components 个右奇异向量($V$ 的前 num_components 列)作为新的基,将原始中心化数据投影到这个低维空间。

    “`matlab
    V_reduced = V(:, 1:num_components); % 选择前 num_components 个右奇异向量
    X_reduced = X_centered * V_reduced; % 原始数据投影到新的低维空间

    disp(‘原始数据维度:’);
    disp(size(X)); % 例如: [100 50]
    disp(‘降维后数据维度:’);
    disp(size(X_reduced)); % 例如: [100 10] (如果 num_components 为 10)
    ``X_reduced` 就是降维后的数据矩阵。它保留了原始数据中最重要的信息,但维度大大降低,这有助于简化模型、减少过拟合风险,并提高计算效率。

总结

SVD 是一种极其有用的线性代数工具,在 MATLAB 中通过 svd 函数可以轻松实现。它不仅能帮助您深入理解数据的内在结构,还能有效地进行数据降维,从而优化后续的数据分析和机器学习任务。通过仔细选择保留的奇异值数量,您可以在数据信息保留程度和维度降低之间找到最佳平衡点,实现更高效、更鲁棒的数据处理。

滚动至顶部