MATLAB SVD 教程:一步步带你掌握奇异值分解 – wiki大全


MATLAB SVD 教程:一步步带你掌握奇异值分解

奇异值分解(Singular Value Decomposition,简称 SVD)是线性代数中一种重要的矩阵分解方法,它在数据压缩、降噪、推荐系统、图像处理等众多领域都有着广泛的应用。本文将通过详细的步骤和 MATLAB 代码示例,带你深入理解 SVD 的原理和应用。

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

SVD 是一种将任意 $m \times n$ 矩阵 $A$ 分解为三个矩阵乘积的形式:

$A = U \Sigma V^T$

其中:
* $U$ 是一个 $m \times m$ 的正交矩阵(Orthogonal Matrix),其列向量是 $A A^T$ 的特征向量,称为左奇异向量。
* $\Sigma$ 是一个 $m \times n$ 的对角矩阵,其对角线上的元素是非负实数,称为奇异值(Singular Values),且通常按降序排列。对角线以外的元素均为 0。
* $V$ 是一个 $n \times n$ 的正交矩阵,其列向量是 $A^T A$ 的特征向量,称为右奇异向量。$V^T$ 是 $V$ 的转置。

核心思想: SVD 揭示了矩阵内部最重要的结构和信息。奇异值的大小反映了对应奇异向量方向上的数据变化强度,大的奇异值对应着数据中更重要的特征。

2. SVD 的数学原理(简要)

理解 SVD 的关键在于它与特征值分解的关系。

  1. 从 $A^T A$ 和 $A A^T$ 出发:

    • $A^T A$ 是一个 $n \times n$ 的对称矩阵,它的特征值非负。
    • $A A^T$ 是一个 $m \times m$ 的对称矩阵,它的特征值非负。
    • 两者非零特征值是相同的。
  2. 右奇异向量 $V$:

    • $V$ 的列向量是 $A^T A$ 的特征向量。
    • 如果 $\lambda_i$ 是 $A^T A$ 的特征值,那么 $\sqrt{\lambda_i}$ 就是矩阵 $A$ 的奇异值。
  3. 左奇异向量 $U$:

    • $U$ 的列向量是 $A A^T$ 的特征向量。
  4. 奇异值 $\Sigma$:

    • $\Sigma$ 的对角线元素 $\sigma_i$ 是 $A^T A$(或 $A A^T$)的特征值的平方根,即 $\sigma_i = \sqrt{\lambda_i}$。

3. MATLAB 中的 SVD 函数

MATLAB 提供了内置函数 svd() 来执行奇异值分解。

语法:
[U, S, V] = svd(A)

  • A: 输入矩阵。
  • U: 左奇异向量矩阵。
  • S: 奇异值矩阵(对角矩阵)。
  • V: 右奇异向量矩阵。

4. SVD 示例与 MATLAB 实现

让我们通过一个具体的例子来演示 SVD 在 MATLAB 中的应用。

例 1:基本 SVD 分解

假设我们有一个矩阵 $A$:

$A = \begin{pmatrix} 1 & 1 \ 0 & 1 \ 1 & 0 \end{pmatrix}$

MATLAB 代码:

“`matlab
% 定义输入矩阵 A
A = [1 1; 0 1; 1 0];

% 执行奇异值分解
[U, S, V] = svd(A);

% 显示结果
disp(‘原始矩阵 A:’);
disp(A);

disp(‘左奇异向量矩阵 U:’);
disp(U);

disp(‘奇异值矩阵 S:’);
disp(S);

disp(‘右奇异向量矩阵 V:’);
disp(V);

% 验证 SVD 分解的正确性:U * S * V’ 应该等于 A
A_reconstructed = U * S * V’;
disp(‘重构后的矩阵 A (U * S * V”):’);
disp(A_reconstructed);

% 检查重构误差
error = norm(A – A_reconstructed);
fprintf(‘重构误差 (norm(A – A_reconstructed)): %f\n’, error);
“`

运行结果分析:

你会看到 A_reconstructed 与原始矩阵 A 非常接近(误差接近于 0),这验证了 SVD 分解的正确性。

S 矩阵的对角线上的值就是奇异值,它们通常按降序排列。这些奇异值揭示了矩阵中不同方向上的数据“能量”或“重要性”。

5. SVD 的应用:数据降维(主成分分析 PCA 的核心)

SVD 最强大的应用之一是数据降维。通过保留最大的几个奇异值及其对应的奇异向量,我们可以近似原始矩阵,同时显著减少数据量。这正是主成分分析(PCA)的核心思想。

例 2:图像压缩

我们将使用 SVD 来压缩一张灰度图像。图像本质上是一个像素值矩阵。

步骤:
1. 加载图像并转换为灰度图。
2. 对图像矩阵执行 SVD。
3. 选择前 $k$ 个最大的奇异值和对应的奇异向量来重构图像。
4. 比较原始图像和压缩后的图像。

MATLAB 代码:

“`matlab
% 1. 加载图像并转换为灰度图
% 假设你有一张名为 ‘test_image.jpg’ 的图像文件在当前目录下
% 如果没有,可以使用 MATLAB 提供的示例图像
try
img_rgb = imread(‘test_image.jpg’); % 尝试加载用户图片
catch
warning(‘test_image.jpg not found, using example image.’);
img_rgb = imread(‘peppers.png’); % 使用MATLAB自带示例图片
end

% 转换为灰度图 (如果不是灰度图的话)
if size(img_rgb, 3) == 3
img_gray = rgb2gray(img_rgb);
else
img_gray = img_rgb;
end

% 将像素值转换为 double 类型以便进行数学运算
A = double(img_gray);

% 获取图像维度
[m, n] = size(A);

disp([‘原始图像尺寸: ‘, num2str(m), ‘x’, num2str(n)]);

% 2. 对图像矩阵执行 SVD
tic; % 计时开始
[U, S, V] = svd(A);
toc; % 计时结束

% 3. 选择不同数量的奇异值进行重构
k_values = [1, 5, 20, 50, 100]; % 尝试不同的 k 值

figure;
subplot(2, 3, 1);
imshow(uint8(A));
title(‘原始图像’);

for i = 1:length(k_values)
k = k_values(i);

% 截取前 k 个奇异值和对应的奇异向量
U_k = U(:, 1:k);
S_k = S(1:k, 1:k);
V_k = V(:, 1:k);

% 重构图像
A_k_reconstructed = U_k * S_k * V_k';

subplot(2, 3, i + 1);
imshow(uint8(A_k_reconstructed)); % 转换回 uint8 显示
title(['重构图像 (k = ', num2str(k), ')']);

% 计算压缩率(近似)
% 原始数据量: m*n
% 压缩后数据量: m*k + k + k*n (U_k, S_k, V_k)
% 忽略 S_k 对角线以外的0,实际储存 k 个奇异值
original_data_points = m * n;
compressed_data_points = m * k + k + n * k;

fprintf('k = %d, 压缩数据点: %d, 原始数据点: %d, 压缩率: %.2f%%\n', ...
        k, compressed_data_points, original_data_points, ...
        (1 - compressed_data_points / original_data_points) * 100);

end

sgtitle(‘SVD 图像压缩示例’); % 设置整个图窗的标题
“`

实验与观察:

  • 你会发现,随着 k 值的增加,重构的图像越来越接近原始图像。
  • 即使 k 相对较小,我们也能得到一个可识别的图像,这说明 SVD 成功地捕获了图像的主要特征。
  • 通过牺牲一部分图像质量,我们实现了显著的数据压缩。

6. SVD 的其他应用场景

  • 推荐系统: SVD 可以用于用户-物品评分矩阵的分解,从而发现潜在的用户兴趣和物品特征,实现个性化推荐(例如 Netflix 挑战)。
  • 自然语言处理 (NLP): 潜在语义分析 (Latent Semantic Analysis, LSA) 利用 SVD 来发现文档和词语之间的潜在语义关系,解决同义词和多义词问题。
  • 信号处理: SVD 可以用于信号去噪,通过去除小的奇异值对应的分量来滤除噪声。
  • 计算机视觉: 人脸识别(Eigenfaces)、图像去模糊等。

7. 注意事项

  • 计算成本: 对大型矩阵进行 SVD 分解是计算密集型的操作。对于非常大的稀疏矩阵,通常会使用迭代方法来近似计算SVD。
  • 数值稳定性: SVD 是数值稳定的,这使其成为许多应用的首选方法。
  • 唯一性: 奇异值是唯一的,但奇异向量不一定是唯一的(特别是当奇异值重复时)。然而,对于 $U \Sigma V^T$ 的整体重构结果是唯一的。

总结

奇异值分解 (SVD) 是一个强大且用途广泛的数学工具。通过本教程,你应该已经对 SVD 的原理、在 MATLAB 中的实现以及它在数据降维(特别是图像压缩)中的应用有了清晰的理解。掌握 SVD 将为你在数据科学、机器学习和信号处理等领域打开新的大门。


滚动至顶部