Python基础学习-Day20

目录

  • 奇异值分解(SVD)的输入和输出
  • 奇异值的应用
  • 实际案例
    • 1. 问题分析
    • 2. 解决方案:对测试集应用相同的变换
    • 3. 为什么不能对测试集单独做 SVD?
    • 4. 代码示例:训练集和测试集的 SVD 降维
    • 6. 实际操作中的注意事项

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

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

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

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

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

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

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

整体作用

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

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

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

奇异值的应用

奇异值分解(SVD)后,原始矩阵 A A A 被分解为 A = U Σ V T A = U \Sigma V^T A=UΣVT,这种分解是等价的,意味着通过 U U U Σ \Sigma Σ V T V^T VT 的乘积可以完全重构原始矩阵 A A A,没有任何信息损失。

但在实际应用中,我们通常不需要保留所有的奇异值和对应的向量,而是可以通过筛选规则选择排序靠前的奇异值及其对应的向量来实现降维或数据压缩。以下是这个过程的核心思想:

  1. 奇异值的排序

    • Σ \Sigma Σ 矩阵中,奇异值(对角线上的值)是按降序排列的。靠前的奇异值通常较大,代表了数据中最重要的信息或主要变化方向;靠后的奇异值较小,代表次要信息或噪声。
    • 奇异值的大小反映了对应向量对原始矩阵 A A A 的贡献程度。
  2. 筛选规则

    • 我们可以根据需求选择保留前 k k k 个奇异值( k k k 是一个小于原始矩阵秩的数),并丢弃剩余的较小奇异值。
    • 常见的筛选规则包括:
      • 固定数量:直接选择前 k k k 个奇异值(例如,前 10 个)。
      • 累计方差贡献率:计算奇异值的平方(代表方差),选择累计方差贡献率达到某个阈值(如 95%)的前 k k k 个奇异值。
      • 奇异值下降幅度:观察奇异值下降的“拐点”,在下降明显变缓的地方截断。
  3. 降维与近似

    • 保留前 k k k 个奇异值后,我们只取 U U U 矩阵的前 k k k 列(记为 U k U_k Uk,尺寸为 m × k m \times k m×k)、 Σ \Sigma Σ 矩阵的前 k k k 个奇异值(记为 Σ k \Sigma_k Σk,尺寸为 k × k k \times k k×k)、以及 V T V^T VT 矩阵的前 k k k 行(记为 V k T V_k^T VkT,尺寸为 k × n k \times n k×n)。
    • 近似矩阵为 A k = U k Σ k V k T A_k = U_k \Sigma_k V_k^T Ak=UkΣkVkT,这个矩阵是原始矩阵 A A A 的低秩近似,保留了主要信息,丢弃了次要信息或噪声。
    • 这种方法在降维(如主成分分析 PCA)、图像压缩、推荐系统等领域非常常用。
  4. 对应的向量

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

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

实际案例

在机器学习中,如果对训练集进行 SVD 降维后训练模型,而测试集的特征数量与降维后的训练集不一致(测试集仍保持原始特征数量),该如何处理?

1. 问题分析

  • 训练集降维:假设训练集有 1000 个样本,50 个特征,通过 SVD 降维后保留 k = 10 k=10 k=10 个特征,得到形状为 (1000, 10) 的新数据。模型基于这 10 个特征进行训练。
  • 测试集问题:测试集假设有 200 个样本,仍然是 50 个特征。如果直接输入测试集到模型中,特征数量不匹配(模型期望 10 个特征,测试集有 50 个),会导致错误。
  • 核心问题:如何确保测试集也能被正确地降维到与训练集相同的 k k k 个特征空间?

2. 解决方案:对测试集应用相同的变换

在机器学习中,降维(如 SVD、PCA 等)是一种数据预处理步骤。训练集和测试集必须经过相同的变换,以确保数据分布一致。具体到 SVD,步骤如下:

  1. 训练阶段:对训练集 X t r a i n X_{train} Xtrain 进行 SVD 分解,得到 U U U, Σ \Sigma Σ, 和 V T V^T VT,并保存 V T V^T VT 矩阵(或其前 k k k 行)用于降维变换。
  2. 测试阶段:使用从训练集得到的 V T V^T VT 矩阵,将测试集 X t e s t X_{test} Xtest 投影到相同的低维空间,得到降维后的测试数据。
  3. 原因 V T V^T VT 矩阵定义了从原始特征空间到低维特征空间的映射关系,测试集必须使用相同的映射以保持一致性。

数学上,假设训练集 SVD 分解为 X t r a i n = U Σ V T X_{train} = U \Sigma V^T Xtrain=UΣVT,我们保留前 k k k 个奇异值对应的 V k T V_k^T VkT(形状为 k × 50 k \times 50 k×50)。测试集降维公式为:
X t e s t _ r e d u c e d = X t e s t ⋅ V k T . T X_{test\_reduced} = X_{test} \cdot V_k^T.T Xtest_reduced=XtestVkT.T
其中 V k T . T V_k^T.T VkT.T V k T V_k^T VkT 的转置(形状为 50 × k 50 \times k 50×k), X t e s t X_{test} Xtest 是形状为 (n_test, 50) 的测试集矩阵,降维后 X t e s t _ r e d u c e d X_{test\_reduced} Xtest_reduced 的形状为 (n_test, k)


3. 为什么不能对测试集单独做 SVD?

  • 如果对测试集单独进行 SVD,会得到不同的 V T V^T VT 矩阵,导致测试集和训练集的低维空间不一致,模型无法正确处理测试数据。
  • 训练集的 V T V^T VT 矩阵代表了训练数据的特征映射规则,测试集必须遵循相同的规则,否则会引入数据泄漏或不一致性问题。

4. 代码示例:训练集和测试集的 SVD 降维

以下是一个完整的代码示例,展示如何对训练集进行 SVD 降维,训练模型,并对测试集应用相同的降维变换。


import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score# 设置随机种子以便结果可重复
np.random.seed(42)# 模拟数据:1000 个样本,50 个特征
n_samples = 1000
n_features = 50
X = np.random.randn(n_samples, n_features) * 10  # 随机生成特征数据
y = (X[:, 0] + X[:, 1] > 0).astype(int)  # 模拟二分类标签# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f"训练集形状: {X_train.shape}")
print(f"测试集形状: {X_test.shape}")# 对训练集进行 SVD 分解
U_train, sigma_train, Vt_train = np.linalg.svd(X_train, full_matrices=False)
print(f"Vt_train 矩阵形状: {Vt_train.shape}")# 选择保留的奇异值数量 k
k = 10
Vt_k = Vt_train[:k, :]  # 保留前 k 行,形状为 (k, 50)
print(f"保留 k={k} 后的 Vt_k 矩阵形状: {Vt_k.shape}")# 降维训练集:X_train_reduced = X_train @ Vt_k.T
X_train_reduced = X_train @ Vt_k.T
print(f"降维后训练集形状: {X_train_reduced.shape}")# 使用相同的 Vt_k 对测试集进行降维:X_test_reduced = X_test @ Vt_k.T
X_test_reduced = X_test @ Vt_k.T
print(f"降维后测试集形状: {X_test_reduced.shape}")# 训练模型(以逻辑回归为例)
model = 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)
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}")

在这里插入图片描述

6. 实际操作中的注意事项

  1. 标准化数据:在进行 SVD 之前,通常需要对数据进行标准化(均值为 0,方差为 1),以避免某些特征的量纲差异对降维结果的影响。可以使用 sklearn.preprocessing.StandardScaler

    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)
    

    注意:scaler 必须在训练集上 fit,然后对测试集只用 transform,以避免数据泄漏。

  2. 选择合适的 k k k:可以通过累计方差贡献率(explained variance ratio)选择 k k k,通常选择解释 90%-95% 方差的 k k k 值。代码中可以计算:

    explained_variance_ratio = np.cumsum(sigma_train**2) / np.sum(sigma_train**2)
    print(f"前 {k} 个奇异值的累计方差贡献率: {explained_variance_ratio[k-1]}")
    
  3. 使用 sklearn 的 TruncatedSVDsklearn 提供了 TruncatedSVD 类,专门用于高效降维,尤其适合大规模数据。它直接计算前 k k k 个奇异值和向量,避免完整 SVD 的计算开销。

    from sklearn.decomposition import TruncatedSVD
    svd = TruncatedSVD(n_components=k, random_state=42)
    X_train_reduced = svd.fit_transform(X_train)
    X_test_reduced = svd.transform(X_test)
    print(f"累计方差贡献率: {sum(svd.explained_variance_ratio_)}")
    

@浙大疏锦行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年 全新 AI 编程工具 Cursor 安装使用教程

一、Cursor 软件下载 首选,登录Cursor官网,进行软件下载,官网下载地址如下: Cursor AI IDE 下载 二、Cursor软件安装配置 此处以Windows10系统安装为例,下载完成之后,右键安装包,以管理员身份…

[vue]error:0308010C:digital envelope routines::unsupported

npm run dev 报错: \node_modules\webpack\hot\dev-server.jsnode:internal/crypto/hash:71 this[kHandle] new _Hash(algorithm, xofLen); Error: error:0308010C:digital envelope routines::unsupported opensslErrorStack: [ error:03000086:digital env…

开放的力量:新零售生态的共赢密码

当某头部生鲜平台向供应商开放销售预测系统后,合作伙伴的库存周转率竟提升12%——这个反常识的案例,正在重塑商业竞争的底层逻辑。 生态共建三板斧 ▌模块化设计:像搭积木一样开放 • 乐高式API架构:30%接口支持自由组合&#xff…

深入理解Spring缓存注解:@Cacheable与@CacheEvict

在现代应用程序开发中,缓存是提升系统性能的重要手段。Spring框架提供了一套简洁而强大的缓存抽象,其中Cacheable和CacheEvict是两个最常用的注解。本文将深入探讨这两个注解的工作原理、使用场景以及最佳实践。 1. Cacheable注解 基本概念 Cacheable…

[python] 函数3-python内置函数

一 内置函数 导入:import builtins 1.1 查看内置函数 大写字母开头的一般是内置变量小写的一般是内置函数 import builtins print(dir(builtins)) 1.2 abs() 求绝对值 print(abs(-10)) 1.3 sum()求和 不能直接用纯数字,因为不是可迭代对象 运算时只要一个是浮点数,结果就…

QT异步线程通信

在使用 QThreadPool 提交任务后,如果你需要知道任务何时完成,并且需要使用任务的执行结果,可以通过以下几种方式来实现: 1. 使用信号和槽 QRunnable 提供了一个 finished() 信号,当任务执行完成后会发出。你可以在任…

利用并行处理提高LabVIEW程序执行速度

在 LabVIEW 编程中,提升程序执行速度是优化系统性能的关键,而并行处理技术则是实现这一目标的有力武器。通过合理运用并行处理,不仅能加快程序运行,还能增强系统的稳定性和响应能力。下面将结合实际案例,深入探讨如何利…

机器学习第三讲:监督学习 → 带答案的学习册,如预测房价时需要历史价格数据

机器学习第三讲:监督学习 → 带答案的学习册,如预测房价时需要历史价格数据 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署&#xff1…

Open CASCADE学习|实现裁剪操作

1. 引言 Open CASCADE (简称OCC) 是一个功能强大的开源几何建模内核,广泛应用于CAD/CAM/CAE领域。裁剪操作作为几何建模中的基础功能,在模型编辑、布尔运算、几何分析等方面有着重要作用。本文将全面探讨Open CASCADE中的裁剪操作实现原理、应用场景及具…

【redis】分片方案

Redis分片(Sharding)是解决单机性能瓶颈的核心技术,其本质是将数据分散存储到多个Redis节点(实例)中,每个实例将只是所有键的一个子集,通过水平扩展提升系统容量和性能。 分片的核心价值 性能提…

RGB矩阵照明系统详解及WS2812配置指南

RGB矩阵照明系统详解及WS2812配置指南 一、RGB矩阵照明简介 RGB矩阵照明是一种强大的功能,允许使用外部驱动器驱动的RGB LED矩阵为键盘增添绚丽的灯光效果。该系统与RGBLIGHT功能无缝集成,因此您可以使用与RGBLIGHT相同的键码来控制它,操作…

[250509] x-cmd 发布 v0.5.11 beta:x ping 优化、AI 模型新增支持和语言变量调整

目录 X-CMD 发布 v0.5.11 beta📃Changelog🧩 ping🧩 openai🧩 gemini🧩 asdf🧩 mac✅ 升级指南 X-CMD 发布 v0.5.11 beta 📃Changelog 🧩 ping 调整 x ping 默认参数为 bing.com&a…

嵌入式开发学习日志Day17

第十一章 结构体与共用体 一、结构体 1、结构体 一般形式 【struct 标识符】 结构体中的标识符一般首字母大写; 【.】结构体成员运算符; 优先级 1 级 结合方向:从左至右; 【->】:指向结构体成员运算符&#x…

发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真)

发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真) 一,异常事件和程序备份加载1,常见异常事件2,零点复归介绍3,程序备份-加载(未整理)二,`ROBOGUIDE`离线仿真1,仿真软件简介及安装步骤(未整理)2,机器人==导入与工具==与==工件添加==2.1,机器人导入(未整…

青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备

青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备 一、Rust核心特性应用场景开发工具社区与生态 二、Rust 和 Python 比较1. **内存安全与并发编程**2. **性能**3. **零成本抽象**4. **跨平台支持**5. **社区与生态系统**6. **错误处理**7. **安全性**适用场景总结 三、…

Java反射 八股版

目录 一、核心概念阐释 1. Class类 2. Constructor类 3. Method类 4. Field类 二、典型应用场景 1. 框架开发 2. 单元测试 3. JSON序列化/反序列化 三、性能考量 四、安全与访问控制 1. 安全管理器限制 2. 打破封装性 3. 安全风险 五、版本兼容性问题 六、最佳…

操作系统的初步了解

目录 引言:什么是操作系统? 一、设计操作系统的目的 二、操作系统是做什么的: 操作系统主要有四大核心任务: 1. 管理硬件 2. 运行软件 3. 存储数据 4. 提供用户界面 如何理解操作系统的管理呢? 1. 什么是操作…

Mkdocs页面如何嵌入PDF

嵌入PDF 嵌入PDF代码 &#xff0c;注意PDF的相对地址 <iframe src"../个人简历.pdf (相对地址)" width"100%" height"800px" style"border: 1px solid #ccc; overflow: auto;"></iframe>我的完整代码&#xff1a; <d…

链表结构深度解析:从单向无头到双向循环的实现全指南

上篇博客实现动态顺序表时&#xff0c;我们会发现它存在许多弊端&#xff0c;如&#xff1a; • 中间/头部的插⼊删除&#xff0c;时间复杂度为O(N) • 增容需要申请新空间&#xff0c;拷⻉数据&#xff0c;释放旧空间。会有不⼩的消耗。 • 增容⼀般是呈2倍的增⻓&#xff0c;…

@PostConstruct @PreDestroy

PostConstruct 是 Java EE&#xff08;现 Jakarta EE&#xff09;中的一个注解&#xff0c;用于标记一个方法在对象初始化完成后立即执行。它在 Spring 框架、Java Web 应用等场景中广泛使用&#xff0c;主要用于资源初始化、依赖注入完成后的配置等操作。 1. 基本作用 执行时…