当前位置: 首页 > news >正文

Day 20 奇异值SVD分解

@浙大疏锦行

特征降维的非特征筛选方法。

先回顾一下昨天的特征筛选方法:方差筛选,皮尔逊相关系数筛选,基于L1正则化的lasso筛选,树模型重要性,shap重要性特征筛选,递归特征消除RFE

今日知识点(SVD奇异值分解):

一、线代概念回顾:

考研数学中与特征值分解相关的题目主要集中在以下几类:

1. 计算特征值和特征向量:通过特征方程求解。

2. 矩阵对角化:判断矩阵是否可对角化,并求对角化矩阵。

3. 利用特征值分解求矩阵幂或函数:通过分解简化高次幂计算。

4. 证明题:如证明某些矩阵性质与特征值的关系。

正交矩阵:列向量正交且单位化,在 SVD 中用于旋转或反射(U 和 V)。

特征值与特征向量:描述矩阵在某些方向上的缩放特性,是计算奇异值的基础。

对称矩阵:具有实特征值和正交特征向量,SVD 通过构造 利用其性质。

矩阵分解:将复杂矩阵分解为简单矩阵乘积,是降维和数据分析的核心工具。

奇异值分解(SVD)的输入和输出:

  • 输入:一个任意的矩阵 A,尺寸为 m×n(其中 m 是行数,n 是列数,可以是矩形矩阵,不必是方阵)。

奇异值分解(SVD)得到的三个矩阵 U、Σ 和 V^T 各有其特定的意义和用途,下面我简要说明它们的作用:

  1. U(左奇异向量矩阵)

    • 是一个 m×m 的正交矩阵,列向量是矩阵 A A^T 的特征向量。
    • 作用:表示原始矩阵 A 在行空间(样本空间)中的主方向或基向量。简单来说,U 的列向量描述了数据在行维度上的 “模式” 或 “结构”。
    • 应用:在降维中,U 的前几列可以用来投影数据到低维空间,保留主要信息(如在图像处理中提取主要特征)。
  2. Σ(奇异值矩阵)

    • 是一个 m×n 的对角矩阵,对角线上的值是奇异值(singular values),按降序排列,非负。
    • 作用:奇异值表示原始矩阵 A 在每个主方向上的 “重要性” 或 “能量”。较大的奇异值对应更重要的特征,较小的奇异值对应噪声或次要信息。
    • 应用:通过选择前 k 个较大的奇异值,可以实现降维,丢弃不重要的信息(如数据压缩、去噪)。
  3. V^T(右奇异向量矩阵的转置)

    • 是 V 的转置,V 是一个 n×n 的正交矩阵,列向量是矩阵 A^T A 的特征向量。
    • 作用:表示原始矩阵 A 在列空间(特征空间)中的主方向或基向量。简单来说,V 的列向量描述了数据在列维度上的 “模式” 或 “结构”。
    • 应用:类似 U,V 的前几列可以用来投影数据到低维空间,提取主要特征。

整体作用

  • 结合起来,A = U Σ V^T 意味着原始矩阵 A 可以被分解为一系列主方向(U 和 V)和对应的权重(Σ)的组合。这种分解揭示了数据的内在结构。
  • 主要应用
    • 降维:通过保留前 k 个奇异值及其对应的 U 和 V 的列向量,可以近似重建 A,减少数据维度(如 PCA 的基础)。
    • 数据压缩:如图像压缩,丢弃小的奇异值以减少存储空间。
    • 去噪:小的奇异值往往对应噪声,丢弃它们可以提高数据质量。
    • 推荐系统:如矩阵分解,用于预测用户评分矩阵中的缺失值。

简单来说,U、Σ 和 V^T 提供了数据的核心结构信息,帮助我们在保留主要信息的同时简化数据处理。

  • 输出:SVD 将矩阵 A 分解为三个矩阵的乘积形式,即 A = U Σ V^T,其中:
    • U:一个 m×m 的正交矩阵,列向量是 A A^T 的特征向量,称为左奇异向量矩阵。
    • Σ:一个 m×n 的对角矩阵,对角线上的元素是非负的奇异值(singular values),通常按降序排列,表示 A 的 “重要性” 或 “能量”。
    • V^T:一个 n×n 的正交矩阵的转置,V 的列向量是 A^T A 的特征向量,称为右奇异向量矩阵。

奇异值的应用

奇异值分解(SVD)将原始矩阵 A 分解为 A = UΣV^T,这种分解是等价的,用这三个矩阵相乘可完全重构 A,没有信息损失。

但实际应用中,通常不用保留所有奇异值和对应向量,而是通过筛选规则选排序靠前的,实现降维或数据压缩。核心思路如下:

  1. 奇异值的排序
    Σ 矩阵中,奇异值按降序排列。靠前的通常较大,代表数据中最重要的信息或主要变化方向;靠后的较小,代表次要信息或噪声。
    奇异值大小反映对应向量对原始矩阵 A 的贡献程度。

  2. 筛选规则
    可根据需求保留前 k 个奇异值(k 小于原始矩阵秩),丢弃剩余较小的。
    常见规则:

    • 固定数量:直接选前 k 个(如前 10 个)。
    • 累计方差贡献率:算奇异值的平方(代表方差),选累计贡献率达阈值(如 95%)的前 k 个。
    • 奇异值下降幅度:观察下降 “拐点”,在下降明显变缓处截断。
  3. 降维与近似
    保留前 k 个奇异值后,取 U 的前 k 列(U_k,m×k)、Σ 的前 k 个奇异值(Σ_k,k×k)、V^T 的前 k 行(V_k^T,k×n)。
    近似矩阵为 A_k = U_kΣ_kV_k^T,这是 A 的低秩近似,保留主要信息,丢弃次要信息或噪声。
    该方法常用于降维(如 PCA)、图像压缩、推荐系统等领域。

  4. 对应的向量
    U 和 V 的列向量分别是左右奇异向量。保留前 k 个奇异值时,U_k 的列向量代表数据在行空间的主要方向,V_k 的列向量代表在列空间的主要方向。
    这些向量与奇异值一起,构成数据的主要 “模式” 或 “结构”。

总结:SVD 分解后原始矩阵等价,通过筛选靠前的奇异值和对应向量,可实现降维,保留主要信息,减少计算量和噪声影响。这是许多降维算法(如 PCA)和数据处理技术的基础。

# 数据集的划分
from sklearn.model_selection import train_test_split
# 准备标签和特征
X = data_encoded.drop(TARGET_COLUMN, axis=1)
y = data_encoded[TARGET_COLUMN]
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 新增:在SVD分解前对数据集进行标准化处理
from sklearn.preprocessing import StandardScaler
scaler_svd = StandardScaler()
X_train_scaled = scaler_svd.fit_transform(X_train)
X_test_scaled = scaler_svd.transform(X_test)
print(f"标准化后训练集形状: {X_train_scaled.shape}")
print(f"标准化后测试集形状: {X_test_scaled.shape}")# 对标准化后的训练集进行 SVD 分解
U_train, sigma_train, Vt_train = np.linalg.svd(X_train_scaled, full_matrices=False)
print(f"Vt_train 矩阵形状: {Vt_train.shape}")# 选择保留的奇异值数量 k
k = 10
Vt_k = Vt_train[:k, :]  # 保留前 k 行
print(f"保留 k={k} 后的 Vt_k 矩阵形状: {Vt_k.shape}")# 降维训练集:X_train_reduced = X_train_scaled @ Vt_k.T
X_train_reduced = X_train_scaled @ Vt_k.T
print(f"降维后训练集形状: {X_train_reduced.shape}")# 使用相同的 Vt_k 对测试集进行降维:X_test_reduced = X_test_scaled @ Vt_k.T
X_test_reduced = X_test_scaled @ Vt_k.T
print(f"降维后测试集形状: {X_test_reduced.shape}")# 训练模型(以逻辑回归为例)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(random_state=42)
model.fit(X_train_reduced, y_train)# 预测并评估
from sklearn.metrics import accuracy_score
y_pred = model.predict(X_test_reduced)
accuracy = accuracy_score(y_test, y_pred)
print(f"测试集准确率: {accuracy}")# 计算训练集的近似误差
X_train_approx = U_train[:, :k] @ np.diag(sigma_train[:k]) @ Vt_k
error = np.linalg.norm(X_train - X_train_approx, 'fro') / np.linalg.norm(X_train, 'fro')
print(f"训练集近似误差 (Frobenius 范数相对误差): {error}")# 可选:尝试不同的k值,观察准确率和误差变化
print("\n尝试不同的k值:")
for k in [5, 10, 15, 20, X_train.shape[1]]:Vt_k = Vt_train[:k, :]X_train_reduced = X_train @ Vt_k.TX_test_reduced = X_test @ Vt_k.Tmodel = LogisticRegression(random_state=42)model.fit(X_train_reduced, y_train)y_pred = model.predict(X_test_reduced)accuracy = accuracy_score(y_test, y_pred)X_train_approx = U_train[:, :k] @ np.diag(sigma_train[:k]) @ Vt_kerror = np.linalg.norm(X_train - X_train_approx, 'fro') / np.linalg.norm(X_train, 'fro')print(f"k={k}: 准确率={accuracy:.4f}, 近似误差={error:.6f}")
26
标准化后训练集形状: (242, 25)
标准化后测试集形状: (61, 25)
Vt_train 矩阵形状: (25, 25)
保留 k=10 后的 Vt_k 矩阵形状: (10, 25)
降维后训练集形状: (242, 10)
降维后测试集形状: (61, 10)
测试集准确率: 0.8688524590163934
训练集近似误差 (Frobenius 范数相对误差): 0.9371979703408998尝试不同的k值:
k=5: 准确率=0.8525, 近似误差=0.966833
k=10: 准确率=0.8689, 近似误差=0.937198
k=15: 准确率=0.8689, 近似误差=0.905244
k=20: 准确率=0.8689, 近似误差=0.884977

    http://www.lryc.cn/news/615598.html

    相关文章:

  1. 前端懒加载技术全面解析
  2. 衰减器的计算
  3. 【文献阅读】我国生态问题鉴定与国土空间生态保护修复方向
  4. BeanDefinition 与 Bean 生命周期(面试高频考点)
  5. C#异步编程双利器:异步Lambda与BackgroundWorker实战解析
  6. 104-基于Flask的优衣库销售数据可视化分析系统
  7. Python day39
  8. PG靶机 - Shiftdel
  9. 大语言模型提示工程与应用:前沿提示工程技术探索
  10. AcWing 4579. 相遇问题
  11. Horse3D引擎研发笔记(三):使用QtOpenGL的Shader编程绘制彩色三角形
  12. 企业级高性能web服务器
  13. 香橙派 RK3588 部署千问大模型 Qwen2-VL-2B 推理视频
  14. Kubernetes CronJob bug解决
  15. 前端工程化:从构建工具到性能监控的全流程实践
  16. 应用层Http协议(1)
  17. Spring框架基础
  18. 黑马SpringAI项目-聊天机器人
  19. 力扣热题100------70.爬楼梯
  20. Day38--动态规划--322. 零钱兑换,279. 完全平方数,139. 单词拆分,56. 携带矿石资源(卡码网),背包问题总结
  21. 原生Vim操作大全
  22. 大模型“涌现”背后的暗线——规模、数据、目标函数的三重协奏
  23. 算法_python_学习记录_02
  24. linux 操作ppt
  25. Uipath Studio中邮件自动化
  26. HTML全景效果实现
  27. Android 开发问题:The specified child already has a parent.
  28. 202506 电子学会青少年等级考试机器人五级器人理论真题
  29. NX二次开发——面有关的函数
  30. C++的结构体指针