【深度学习与大模型基础】第7章-特征分解与奇异值分解
一、特征分解
特征分解(Eigen Decomposition)是线性代数中的一种重要方法,广泛应用于计算机行业的多个领域,如机器学习、图像处理和数据分析等。特征分解将一个方阵分解为特征值和特征向量的形式,帮助我们理解矩阵的结构和性质。
1. 特征分解的定义
对于一个 n×n 的方阵 A ,如果存在一个非零向量 v 和一个标量 λ ,使得:
则称 λ 为矩阵 A 的特征值,v 为对应的特征向量。
特征分解将矩阵 A 分解为:
其中:
-
Q 是由特征向量组成的矩阵,
-
Λ 是由特征值组成的对角矩阵。
2. 计算机行业中的应用示例
(1)主成分分析(PCA)
PCA 是一种降维技术,广泛应用于数据压缩和可视化。其核心思想是通过特征分解找到数据的主要方向(特征向量),并将数据投影到这些方向上,从而减少维度。
-
步骤:
-
计算数据的协方差矩阵。
-
对协方差矩阵进行特征分解,得到特征值和特征向量。
-
选择前 kk 个最大特征值对应的特征向量,构建投影矩阵。
-
将原始数据投影到低维空间。
-
-
示例:在图像处理中,PCA 可以用于人脸识别,通过降维提取主要特征,减少计算复杂度。
(2)图像压缩
在图像处理中,特征分解可以用于压缩图像。例如,奇异值分解(SVD)是特征分解的推广形式,可以将图像矩阵分解为特征值和特征向量的组合,通过保留主要特征值来实现压缩。
-
示例:将一张图像表示为矩阵,通过 SVD 分解并保留前 kk 个奇异值,可以大幅减少存储空间,同时保留图像的主要信息。
(3)推荐系统
在推荐系统中,特征分解可以用于矩阵分解(Matrix Factorization),例如协同过滤算法。通过将用户-物品评分矩阵分解为用户特征矩阵和物品特征矩阵,可以预测用户对未评分物品的偏好。
-
示例:Netflix 的推荐系统通过分解用户-电影评分矩阵,找到潜在的用户偏好和电影特征,从而推荐个性化内容。
(4)图分析与网络
在图论中,图的拉普拉斯矩阵(Laplacian Matrix)的特征分解可以用于社区检测、图分割等任务。特征向量反映了图的结构信息。
-
示例:在社交网络分析中,通过特征分解可以识别社区结构,发现用户群体的聚集模式。
3. python演示特征分解
import numpy as np
import matplotlib.pyplot as plt
# 定义一个矩阵
A = np.array([[3, 1], [1, 2]])
# 进行特征分解
eigenvalues, eigenvectors = np.linalg.eig(A)
# 打印特征值和特征向量
print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)
# 可视化特征向量
plt.figure(figsize=(6, 6))
plt.quiver(0, 0, eigenvectors[0, 0], eigenvectors[1, 0], angles='xy', scale_units='xy', scale=1, color='r', label=f'特征向量 1 (特征值: {eigenvalues[0]:.2f})')
plt.quiver(0, 0, eigenvectors[0, 1], eigenvectors[1, 1], angles='xy', scale_units='xy', scale=1, color='b', label=f'特征向量 2 (特征值: {eigenvalues[1]:.2f})')
# 设置图形属性
plt.xlim(-2, 3)
plt.ylim(-2, 3)
plt.axhline(0, color='black',linewidth=0.5)
plt.axvline(0, color='black',linewidth=0.5)
plt.grid(color = 'gray', linestyle = '--', linewidth = 0.5)
plt.title('特征向量可视化')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.axis('equal')
plt.show()
二、奇异值分解
奇异值分解(Singular Value Decomposition, SVD)是线性代数中的一种重要矩阵分解方法,广泛应用于计算机行业的多个领域,如数据降维、图像处理、推荐系统和自然语言处理等。SVD 将一个矩阵分解为三个特定矩阵的乘积,能够揭示数据的潜在结构和模式。
1. 奇异值分解的定义
对于一个 m×n 的矩阵 A,SVD 将其分解为:
其中:
-
U 是一个 m×m 的正交矩阵,其列向量称为左奇异向量。
-
Σ 是一个 m×n 的对角矩阵,其对角线上的非负元素称为奇异值(通常按从大到小排列)。
-
V 是一个 n×n 的正交矩阵,其列向量称为右奇异向量。
2. 计算机行业中的应用示例
(1)图像压缩
SVD 可以用于图像压缩,通过保留主要的奇异值来近似表示图像,从而减少存储空间。
-
步骤:
-
将图像表示为矩阵 A。
-
对 A 进行 SVD 分解,得到 U、Σ 和 V。
-
保留前 k个最大的奇异值,其余置为零,得到近似矩阵
。
-
使用
近似表示原始图像。
-
-
示例:一张 1000×1000的图像可以通过 SVD 压缩为仅保留前 50 个奇异值的近似图像,大幅减少存储空间,同时保留主要视觉信息。
(2)推荐系统
SVD 在推荐系统中用于矩阵分解(Matrix Factorization),通过分解用户-物品评分矩阵来预测用户对未评分物品的偏好。
-
步骤:
-
将用户-物品评分矩阵 R 分解为 R≈UΣ
。
-
通过低秩近似找到潜在的用户特征和物品特征。
-
使用分解后的矩阵预测用户对未评分物品的评分。
-
-
示例:Netflix 的推荐系统通过 SVD 分解用户-电影评分矩阵,找到用户和电影的潜在特征,从而推荐个性化内容。
(3)自然语言处理(NLP)
在 NLP 中,SVD 可以用于潜在语义分析(Latent Semantic Analysis, LSA),通过分解词-文档矩阵来捕捉词语和文档之间的潜在关系。
-
步骤:
-
构建词-文档矩阵 A,其中每行表示一个词,每列表示一个文档,元素表示词频或 TF-IDF 值。
-
对 A进行 SVD 分解,得到 U、Σ 和 V。
-
使用低秩近似表示词和文档的潜在语义空间。
-
-
示例:在搜索引擎中,LSA 可以通过 SVD 捕捉词语之间的语义关系,提高搜索结果的相关性。
(4)数据降维
SVD 可以用于高维数据的降维,例如在主成分分析(PCA)中,SVD 是计算主成分的核心步骤。
-
步骤:
-
对数据矩阵 AA进行中心化处理。
-
对中心化后的矩阵进行 SVD 分解。
-
选择前 k个奇异值对应的左奇异向量,将数据投影到低维空间。
-
-
示例:在机器学习中,SVD 可以用于减少特征维度,提高模型训练效率并避免过拟合。
3. python演示奇异值分解
import numpy as np
import matplotlib.pyplot as plt
# 定义一个矩阵
A = np.array([[3, 1], [1, 2]])
# 进行奇异值分解
U, S, VT = np.linalg.svd(A)
# 打印奇异值和奇异向量
print("奇异值:", S)
print("左奇异向量矩阵 U:\n", U)
print("右奇异向量矩阵 VT:\n", VT)
# 可视化左奇异向量
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.quiver(0, 0, U[0, 0], U[1, 0], angles='xy', scale_units='xy', scale=1, color='r', label=f'左奇异向量 1')
plt.quiver(0, 0, U[0, 1], U[1, 1], angles='xy', scale_units='xy', scale=1, color='b', label=f'左奇异向量 2')
plt.xlim(-1, 1)
plt.ylim(-1, 1)
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
plt.grid(color='gray', linestyle='--', linewidth=0.5)
plt.title('左奇异向量可视化')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.axis('equal')
# 可视化右奇异向量
plt.subplot(1, 2, 2)
plt.quiver(0, 0, VT[0, 0], VT[1, 0], angles='xy', scale_units='xy', scale=1, color='g', label=f'右奇异向量 1')
plt.quiver(0, 0, VT[0, 1], VT[1, 1], angles='xy', scale_units='xy', scale=1, color='m', label=f'右奇异向量 2')
plt.xlim(-1, 1)
plt.ylim(-1, 1)
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
plt.grid(color='gray', linestyle='--', linewidth=0.5)
plt.title('右奇异向量可视化')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.axis('equal')
plt.tight_layout()
plt.show()