news 2026/7/12 13:14:29

DAY24 奇异值SVD分解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DAY24 奇异值SVD分解

一、SVD的实际价值

1.计算效率提升

  • 特征从n维降至k维(k<n)

  • 减少模型参数数量

  • 加快训练和预测速度

2.模型泛化能力

  • 去除噪声和冗余信息

  • 可能提高模型在测试集上的表现

  • 减少过拟合风险

二、实际书写思路及其代码

针对心脏并数据集我们进行了相应的SVD分解并比较了其在准确率上的差异。

# 先运行之前预处理好的代码 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report, confusion_matrix warnings.filterwarnings("ignore") # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False df = pd.read_csv(r'D:\Python60DaysChallenge-main\heart.csv') X = df.iloc[:, :-1] y = df.iloc[:, -1] # 切分数据 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}") print(f"原始特征数: {X_train.shape[1]}\n") # ===================== 1. 原始数据(不标准化) ===================== print("=== 1. 原始数据模型(不标准化)===") model_original = LogisticRegression(random_state=42, max_iter=1000) model_original.fit(X_train, y_train) y_pred_original = model_original.predict(X_test) accuracy_original = accuracy_score(y_test, y_pred_original) print(f"准确率: {accuracy_original:.4f}") # 原始数据分类报告 print("分类报告:") print(classification_report(y_test, y_pred_original)) print() # ===================== 2. SVD降维 + 标准化 ===================== print("\n=== 2. SVD降维 + 标准化模型 ===") # 标准化数据 from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 对标准化后的训练集进行SVD分解 U_train, sigma_train, Vt_train = np.linalg.svd(X_train_scaled, full_matrices=False) print(f"奇异值数量: {len(sigma_train)}") # 通过累计方差贡献率选择k(只使用训练集信息) cumulative_variance_ratio = np.cumsum(sigma_train**2) / np.sum(sigma_train**2) k = np.argmax(cumulative_variance_ratio >= 0.95) + 1 print(f"选择k={k},累计方差贡献率: {cumulative_variance_ratio[k-1]:.4f}") print(f"特征从 {X_train.shape[1]} 维降至 {k} 维") # 绘制累计方差贡献率图 plt.figure(figsize=(10, 6)) plt.plot(range(1, len(cumulative_variance_ratio) + 1), cumulative_variance_ratio, 'b-', linewidth=2) plt.axhline(y=0.95, color='r', linestyle='--', label='95% 方差线') plt.axvline(x=k, color='g', linestyle='--', label=f'k={k}') plt.xlabel('奇异值数量') plt.ylabel('累计方差贡献率') plt.title('累计方差贡献率曲线') plt.legend() plt.grid(True) plt.show() # 降维 - 正确使用Vt_k Vt_k = Vt_train[:k, :] # 形状: (k, n_features) print(f"Vt_k形状: {Vt_k.shape}") # 对训练集和测试集进行降维 X_train_reduced = X_train_scaled @ Vt_k.T # 等价于: np.dot(X_train_scaled, Vt_k.T) X_test_reduced = X_test_scaled @ Vt_k.T print(f"降维后训练集形状: {X_train_reduced.shape}") print(f"降维后测试集形状: {X_test_reduced.shape}") # 验证降维的维度 print(f"验证: 训练集从 {X_train_scaled.shape} 降维到 {X_train_reduced.shape}") print(f"验证: 测试集从 {X_test_scaled.shape} 降维到 {X_test_reduced.shape}") # 训练SVD降维后的模型 model_svd = LogisticRegression(random_state=42, max_iter=1000) model_svd.fit(X_train_reduced, y_train) y_pred_svd = model_svd.predict(X_test_reduced) accuracy_svd = accuracy_score(y_test, y_pred_svd) print(f"准确率: {accuracy_svd:.4f}") # SVD降维分类报告 print("分类报告:") print(classification_report(y_test, y_pred_svd)) print() # ===================== 性能对比 ===================== print("\n" + "="*50) print("模型性能对比总结:") print("="*50) print(f"1. 原始数据模型准确率: {accuracy_original:.4f}") print(f"2. SVD降维模型准确率: {accuracy_svd:.4f}") print(f"准确率变化: {accuracy_svd - accuracy_original:+.4f}") if accuracy_svd > accuracy_original: print(f"SVD降维提高了准确率 {(accuracy_svd - accuracy_original)*100:.2f}%") elif accuracy_svd < accuracy_original: print(f"SVD降维降低了准确率 {(accuracy_original - accuracy_svd)*100:.2f}%") else: print("SVD降维对准确率无影响") # ===================== 混淆矩阵可视化 ===================== fig, axes = plt.subplots(1, 2, figsize=(14, 5)) # 原始数据混淆矩阵 cm_original = confusion_matrix(y_test, y_pred_original) sns.heatmap(cm_original, annot=True, fmt='d', cmap='Blues', ax=axes[0]) axes[0].set_title(f'原始数据模型\n准确率: {accuracy_original:.4f}') axes[0].set_xlabel('预测标签') axes[0].set_ylabel('真实标签') # SVD降维混淆矩阵 cm_svd = confusion_matrix(y_test, y_pred_svd) sns.heatmap(cm_svd, annot=True, fmt='d', cmap='Blues', ax=axes[1]) axes[1].set_title(f'SVD降维模型\n准确率: {accuracy_svd:.4f}') axes[1].set_xlabel('预测标签') axes[1].set_ylabel('真实标签') plt.tight_layout() plt.show() # ===================== 计算近似误差 ===================== print("\n" + "="*50) print("SVD降维质量评估:") print("="*50) # 重建训练集 Sigma_k = np.diag(sigma_train[:k]) X_train_reconstructed = U_train[:, :k] @ Sigma_k @ Vt_k # 计算重构误差 frobenius_error = np.linalg.norm(X_train_scaled - X_train_reconstructed, 'fro') frobenius_original = np.linalg.norm(X_train_scaled, 'fro') relative_error = frobenius_error / frobenius_original print(f"重构误差 (Frobenius范数): {frobenius_error:.6f}") print(f"相对重构误差: {relative_error:.6f}") print(f"信息保留率: {(1 - relative_error)*100:.2f}%") # ===================== 不同k值性能分析 ===================== print("\n" + "="*50) print("不同k值下的模型性能:") print("="*50) accuracies_by_k = [] k_range = range(1, min(15, len(sigma_train)) + 1) for k_test in k_range: Vt_k_test = Vt_train[:k_test, :] X_train_reduced_test = X_train_scaled @ Vt_k_test.T X_test_reduced_test = X_test_scaled @ Vt_k_test.T model_test = LogisticRegression(random_state=42, max_iter=1000) model_test.fit(X_train_reduced_test, y_train) y_pred_test = model_test.predict(X_test_reduced_test) accuracy_test = accuracy_score(y_test, y_pred_test) accuracies_by_k.append(accuracy_test) variance_ratio = cumulative_variance_ratio[k_test-1] if k_test == k: print(f"k={k_test:2d} (自动选择) | 准确率: {accuracy_test:.4f} | 方差贡献率: {variance_ratio:.4f}") else: print(f"k={k_test:2d} | 准确率: {accuracy_test:.4f} | 方差贡献率: {variance_ratio:.4f}") # 找到最佳k值 best_idx = np.argmax(accuracies_by_k) best_k = k_range[best_idx] best_accuracy = accuracies_by_k[best_idx] print(f"\n最佳k值: k={best_k}, 准确率: {best_accuracy:.4f}") print(f"与自动选择的k={k}相比: 准确率{best_accuracy-accuracies_by_k[k-1]:+.4f}") # 绘制不同k值下的准确率 plt.figure(figsize=(10, 6)) plt.plot(k_range, accuracies_by_k, 'o-', linewidth=2, markersize=8, color='blue') plt.axvline(x=k, color='r', linestyle='--', label=f'自动选择 k={k}', linewidth=2) plt.axvline(x=best_k, color='green', linestyle='--', label=f'最佳 k={best_k}', linewidth=2) plt.axhline(y=accuracy_original, color='orange', linestyle='--', label=f'原始数据准确率: {accuracy_original:.4f}', linewidth=2) plt.xlabel('k值(保留的奇异值数量)', fontsize=12) plt.ylabel('测试集准确率', fontsize=12) plt.title('不同k值下的SVD模型准确率', fontsize=14) plt.legend(loc='best') plt.grid(True, alpha=0.3) plt.tight_layout() plt.show()

运行结果:

注意:

1.SVD不是简单地"去除"某些原始特征

  • SVD创建了新的主成分(线性组合)

  • 每个主成分是所有原始特征的加权组合

  • 去除的是主成分,不是原始特征

2.k=4时的情况

  • 保留了4个主成分

  • 这4个主成分解释了数据的大部分变异

  • 丢弃了9个主成分(对应较小的奇异值)

@浙大疏锦行

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 1:59:17

暖通净化空调恒温恒湿项目:PLC 与触摸屏上位机程序探秘

暖通净化空调恒温恒湿项目包括PLC程序和触摸屏上位机程序。 标准化很好的内部用的函数都封装成了标准块一套很好的学习资料。在暖通净化空调恒温恒湿项目里&#xff0c;PLC 程序和触摸屏上位机程序就像项目运转的左膀右臂&#xff0c;承担着关键任务。先聊聊 PLC 程序&#xff…

作者头像 李华
网站建设 2026/7/11 10:31:11

第30章 Shell 正则表达式实战:精准匹配字符串、日志与配置项

本章导语:正则表达式是文本处理的"瑞士军刀",是 Linux 系统管理和数据处理的核心技能。掌握正则表达式,你将能够精准匹配和处理各种复杂的文本模式,从日志分析到配置文件管理,从数据清洗到格式验证,无所不能。本章将通过丰富的实战案例,帮助你彻底掌握正则表达…

作者头像 李华
网站建设 2026/7/11 12:35:24

音视频学习(七十二):视频压缩:分块与预处理

分块与预处理是视频压缩&#xff08;编码&#xff09;流程的起点&#xff0c;它的目标是将原始的、高冗余的视频数据转换成适合高效压缩的格式和基本处理单元。这一阶段的工作质量直接影响后续运动估计、变换编码和量化等步骤的效率和最终的压缩比与图像质量。 预处理的核心目标…

作者头像 李华
网站建设 2026/7/12 18:01:02

AMD Ryzen性能调优:快速掌握处理器调试工具的使用技巧

AMD Ryzen性能调优&#xff1a;快速掌握处理器调试工具的使用技巧 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

作者头像 李华
网站建设 2026/7/12 14:15:27

深蓝词库转换:轻松打通全平台输入法数据壁垒

深蓝词库转换&#xff1a;轻松打通全平台输入法数据壁垒 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 想要实现搜狗、百度、QQ、微软等主流输入法之间的词库自由迁…

作者头像 李华
网站建设 2026/7/12 15:46:24

(新卷,200分)- 最小传输时延Ⅱ(Java JS Python)

(新卷,200分)- 最小传输时延Ⅱ&#xff08;Java & JS & Python&#xff09;题目描述有M*N的节点矩阵&#xff0c;每个节点可以向8个方向&#xff08;上、下、左、右及四个斜线方向&#xff09;转发数据包&#xff0c;每个节点转发时会消耗固定时延&#xff0c;连续两个…

作者头像 李华