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

手把手图解:用Python把‘能量守恒’和‘勾股定理’画出来,理解机器学习降维不丢信息的本质

手把手图解:用Python把‘能量守恒’和‘勾股定理’画出来,理解机器学习降维不丢信息的本质

在机器学习领域,降维技术如PCA(主成分分析)和SVD(奇异值分解)常被用来处理高维数据。但你是否好奇过,为什么这些方法能在减少数据维度的同时,几乎不丢失关键信息?答案藏在数学中的能量守恒勾股定理里。本文将带你用Python代码,从几何视角直观理解这一核心原理。

我们将使用NumPy和Matplotlib,从二维数据点出发,通过可视化展示正交变换如何保持数据的"能量"(方差)不变。这种动手实践的方式,不仅能加深你对PCA原理的理解,还能让你真正掌握降维技术的数学本质。

1. 准备工作与环境配置

在开始之前,确保你的Python环境已安装以下库:

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D

如果你尚未安装这些库,可以使用pip快速安装:

pip install numpy matplotlib

提示:建议使用Jupyter Notebook进行本教程的实践,它能实时显示图形输出,方便交互式学习。

2. 理解数据"能量"的数学定义

在信号处理和机器学习中,"能量"这一概念与物理学中的定义有所不同。这里,我们定义数据点的能量为其到原点距离的平方:

能量 = x₁² + x₂² + ... + xn²

这与勾股定理在多维空间的扩展形式完全一致。让我们用代码生成一些二维数据点并计算它们的能量:

# 生成随机二维数据点 np.random.seed(42) data = np.random.randn(100, 2) * 5 # 100个点,标准差为5 # 计算每个点的能量 energies = np.sum(data**2, axis=1) total_energy = np.sum(energies) print(f"总能量: {total_energy:.2f}")

3. 可视化原始数据及其能量分布

为了更好地理解,我们先绘制这些数据点:

plt.figure(figsize=(10, 6)) plt.scatter(data[:, 0], data[:, 1], c=energies, cmap='viridis') plt.colorbar(label='单个点能量') plt.axhline(0, color='black', linestyle='--') plt.axvline(0, color='black', linestyle='--') plt.title("二维数据点及其能量分布") plt.xlabel("X轴") plt.ylabel("Y轴") plt.grid(True) plt.show()

你会看到点越远离原点,其颜色越亮(能量越高)。所有点的能量总和就是我们要关注的守恒量。

4. 正交变换与能量守恒

正交变换(如旋转)是PCA的核心。这类变换有一个重要特性:保持向量的长度(即能量)不变。让我们创建一个旋转矩阵并应用它:

# 创建旋转矩阵(30度) theta = np.radians(30) rotation_matrix = np.array([ [np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)] ]) # 应用旋转 rotated_data = data @ rotation_matrix # 计算旋转后能量 rotated_energies = np.sum(rotated_data**2, axis=1) rotated_total_energy = np.sum(rotated_energies) print(f"旋转后总能量: {rotated_total_energy:.2f}")

比较旋转前后的总能量,你会发现它们几乎相同(可能有微小差异来自浮点运算)。这就是能量守恒的体现。

5. 从二维到三维的扩展理解

为了更深入理解,我们扩展到三维空间。首先生成一些三维数据:

# 生成三维数据 np.random.seed(42) data_3d = np.random.randn(100, 3) * 5 # 计算能量 energies_3d = np.sum(data_3d**2, axis=1) total_energy_3d = np.sum(energies_3d) print(f"三维数据总能量: {total_energy_3d:.2f}")

然后创建一个三维旋转矩阵并应用:

# 创建绕Z轴旋转45度的矩阵 theta_z = np.radians(45) rotation_z = np.array([ [np.cos(theta_z), -np.sin(theta_z), 0], [np.sin(theta_z), np.cos(theta_z), 0], [0, 0, 1] ]) # 应用旋转 rotated_3d = data_3d @ rotation_z # 验证能量守恒 rotated_energies_3d = np.sum(rotated_3d**2, axis=1) rotated_total_energy_3d = np.sum(rotated_energies_3d) print(f"旋转后三维总能量: {rotated_total_energy_3d:.2f}")

6. 连接PCA:寻找最大能量方向

PCA的核心思想是找到数据中能量(方差)最大的方向。让我们用代码实现一个简化版PCA:

# 计算协方差矩阵 cov_matrix = np.cov(data.T) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # 按特征值大小排序 sorted_indices = np.argsort(eigenvalues)[::-1] eigenvalues = eigenvalues[sorted_indices] eigenvectors = eigenvectors[:, sorted_indices] print("特征值(各主成分的能量):", eigenvalues) print("特征向量(主成分方向):\n", eigenvectors)

第一主成分方向就是能量最大的方向。我们可以将数据投影到这个方向上:

# 投影到第一主成分 principal_component = eigenvectors[:, 0] projected_data = data @ principal_component # 计算投影后能量 projected_energy = np.sum(projected_data**2) print(f"第一主成分保留能量: {projected_energy:.2f}") print(f"能量保留比例: {projected_energy/total_energy:.2%}")

7. 完整可视化:从原始数据到PCA降维

最后,让我们将所有步骤可视化:

plt.figure(figsize=(12, 6)) # 原始数据 plt.subplot(1, 2, 1) plt.scatter(data[:, 0], data[:, 1], alpha=0.6) plt.quiver(0, 0, eigenvectors[0, 0]*eigenvalues[0], eigenvectors[1, 0]*eigenvalues[0], angles='xy', scale_units='xy', scale=1, color='r', label='PC1') plt.quiver(0, 0, eigenvectors[0, 1]*eigenvalues[1], eigenvectors[1, 1]*eigenvalues[1], angles='xy', scale_units='xy', scale=1, color='g', label='PC2') plt.title("原始数据与主成分方向") plt.legend() # 投影后的数据 plt.subplot(1, 2, 2) plt.scatter(projected_data, np.zeros_like(projected_data), alpha=0.6) plt.title("数据在第一主成分上的投影") plt.tight_layout() plt.show()

这个可视化清晰地展示了PCA如何找到数据中能量最大的方向,并将数据投影到这个方向上,同时最大限度地保留了原始数据的能量(方差)。

http://www.jsqmd.com/news/920164/

相关文章:

  • Windows隐藏的“空间救星”:手把手教你用NTFS压缩给C盘以外的分区瘦身(附性能监控方法)
  • 别再只会用Printf了!UE5调试神器GEngine->AddOnScreenDebugMessage保姆级教程(含变量显示与颜色设置)
  • 别再手动复制粘贴了!用Godot的拖放功能5分钟搞定UI数据传递(附完整代码)
  • Motrix WebExtension深度攻略:告别浏览器下载龟速的终极解决方案
  • 告别枯燥K帧:在UE4 Sequencer里用“初识Sequencer”工程高效制作角色路径动画
  • 别再死记硬背了!用C语言和Python两种方式,手把手教你理解Modbus CRC16校验码的生成
  • 别只点灯了!用高云Tang Nano 4K的ARM核跑AI模型,手把手部署GoAI 2.0车辆检测
  • 苏州欧松板源头厂家深度解析:苏州聚亿鑫装饰工程有限公司的技术优势与行业地位,石膏板/家装设计,欧松板源头厂家口碑推荐 - 品牌推荐师
  • 银河麒麟V10远程桌面保姆级教程:从自带功能到x11vnc服务化配置,一步不漏
  • YOLOv5/v8炼丹必看:从IOU到CIOU,手把手教你选对损失函数(附PyTorch代码对比)
  • 别再死记硬背了!用Python仿真带你直观理解SRT除法与On-the-Fly转换
  • 嵌入式GPU加速超声波传感系统eRTIS设计与应用
  • 别再只盯着AIC/BIC了!用Python实战最小描述长度MDL,帮你选对机器学习模型
  • SPSS 25.0 时间序列预测实战:从数据导入到ARIMA模型结果解读,一篇搞定
  • Zotero进阶玩家必备:这7个隐藏技巧,让你管理文献效率翻倍(附Shift键妙用)
  • 不只是数字签名!用Procmon和注册表,深挖Win10文件属性选项卡消失的根因
  • USB PD 3.0协议层消息实战:手把手教你用逻辑分析仪抓包解析
  • 2026年安防系统实测评测:北京数字高清监控/北京无线监控器/北京无线监控系统/三家品牌核心维度对比解析 - 优质品牌商家
  • 告别刻盘时代!用Ventoy打造你的万能系统U盘,一个U盘装遍Win/Linux/PE
  • 3分钟打造你的专属电子书阅读器:Koodo Reader个性化设置完全指南
  • 三步永久保存你的微信聊天记录:iOS数据备份与导出终极方案
  • 别再只盯着游戏了!用UE5的Quixel Bridge和Lumen,零美术基础也能搞出电影级短片
  • 从《XX游戏》的界面设计,聊聊UE5中UI、HUD与UMG的分工协作实战
  • 告别手动点点点:用Selenium IDE录制Edge浏览器操作,一键生成Python测试脚本
  • UE5动画进阶:拆解Lyra Demo中的Animation Warping插件,不只是防滑步那么简单
  • 别再搞错了!用mdadm在Linux上组RAID5,分区和直接挂硬盘区别大了(附详细步骤)
  • 如何做好CTO-首席技术官(CTO应该如何汇报)
  • 保姆级避坑指南:在Ubuntu 20.04上从源码编译Wayland全家桶(Weston+Protocols)
  • 洞察2026年5月廊坊包装印刷市场:高评价直销厂家实力盘点 - 2026年企业资讯
  • 从点亮第一颗灯到运行GBA游戏:我的Tang Nano 4K FPGA开发板实战入门全记录