NumPy - 奇异值分解



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

奇异值分解,通常缩写为 SVD,是线性代数中的一种矩阵分解技术。SVD 将一个矩阵分解成三个其他矩阵,捕捉原始矩阵的重要属性。

例如,如果你有一个矩阵 A,则 SVD 表示为:

A = UΣVT

这里,UV 是正交矩阵,Σ 是对角矩阵。

U 的列称为左奇异向量,V 的列(或 VT 的行)称为右奇异向量,Σ 的元素为奇异值。

NumPy 中的 SVD

NumPy 提供了 `numpy.linalg.svd()` 函数来计算矩阵的奇异值分解。让我们来看一个例子。

示例

在这个例子中,矩阵 A 被分解成三个矩阵:UΣ(表示为奇异值数组 S)和 VT

import numpy as np

# Define a 3x3 matrix
A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# Compute the Singular Value Decomposition
U, S, VT = np.linalg.svd(A)

print("Matrix U:\n", U)
print("Singular values:", S)
print("Matrix V^T:\n", VT)

以下是获得的输出:

Matrix U:
[[-0.21483724  0.88723069  0.40824829]
 [-0.52058739  0.24964395 -0.81649658]
 [-0.82633754 -0.38794278  0.40824829]]
Singular values: [1.68481034e+01 1.06836951e+00 4.41842475e-16]
Matrix V^T:
[[-0.47967118 -0.57236779 -0.66506441]
 [-0.77669099 -0.07568647  0.62531805]
 [-0.40824829  0.81649658 -0.40824829]]

理解各个组成部分

SVD 的各个组成部分具有特定的属性和作用,如下所示:

  • 矩阵 U:U 的列是 A 的左奇异向量。这些向量构成 A 的列空间的正交基。
  • 奇异值:Σ 的对角线元素是 A 的奇异值。这些值给出 A 沿相应奇异向量的作用大小。
  • 矩阵 VTVT 的行是 A 的右奇异向量。这些向量构成 A 的行空间的正交基。

重建原始矩阵

你可以从它的 SVD 组成部分重建原始矩阵 A。在 NumPy 中,你可以使用 `numpy.dot()` 函数进行矩阵乘法来实现这一点。

示例

在下面的例子中,我们正在重建原始矩阵 "A":

import numpy as np

# Define a 3x3 matrix
A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# Compute the Singular Value Decomposition
U, S, VT = np.linalg.svd(A)

# Create the diagonal matrix Σ from the singular values
Sigma = np.zeros((3, 3))
np.fill_diagonal(Sigma, S)

# Reconstruct the original matrix
A_reconstructed = np.dot(U, np.dot(Sigma, VT))

print("Original matrix:\n", A)
print("Reconstructed matrix:\n", A_reconstructed)

使用其 SVD 组成部分成功地重建了原始矩阵 A,证明了分解的准确性。

Original matrix:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
Reconstructed matrix:
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]

SVD 的应用

SVD 是一种强大的工具,具有许多应用,例如:

  • 降维:在数据分析和机器学习中,SVD 用于在保留重要信息的同时减少维数。
  • 图像压缩:SVD 用于通过减少存储图像所需的数据量来压缩图像。
  • 降噪:SVD 可以通过识别和丢弃小的奇异值来帮助去除数据中的噪声。
  • 信号处理:在信号处理中,SVD 用于分析和滤波信号。
  • 推荐系统:SVD 用于推荐系统来预测用户偏好。

示例:使用 SVD 进行图像压缩

让我们来看一个如何使用 SVD 进行图像压缩的例子。我们将使用灰度图像,并通过仅保留最重要的奇异值来压缩它:

import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color

# Load a sample image and convert it to grayscale
image = color.rgb2gray(data.astronaut())  
# Compute the Singular Value Decomposition
U, S, VT = np.linalg.svd(image, full_matrices=False)

# Retain only the first k singular values
k = 50
U_k = U[:, :k]
S_k = np.diag(S[:k])
VT_k = VT[:k, :]

# Reconstruct the compressed image
image_compressed = np.dot(U_k, np.dot(S_k, VT_k))

# Plot the original and compressed images
plt.figure(figsize=(10, 5))

plt.subplot(1, 2, 1)
plt.title("Original Image")
plt.imshow(image, cmap='gray')
plt.axis('off')

plt.subplot(1, 2, 2)
plt.title(f"Compressed Image with k={k}")
plt.imshow(image_compressed, cmap='gray')
plt.axis('off')

plt.show()

原始图像和压缩后的图像并排显示,展示了 SVD 如何在保留其基本特征的同时减小图像大小。

SVD Compression

SVD 的优点

SVD 提供了一些优点,例如:

  • 数值稳定性:SVD 数值稳定,可以处理病态矩阵。
  • 最佳低秩逼近:SVD 提供矩阵的最佳低秩逼近,使其成为降维的理想选择。
  • 鲁棒性:SVD 对数据中的微小扰动具有鲁棒性。
  • 通用性:SVD 可以应用于任何矩阵,无论其属性如何。
广告