机器学习-PCA降维【手撕】

降维算法

降维算法中的”降维“,指的是降低特征矩阵中特征的数量,其目的是为了让算法运算更快,效果更好,同时可以方便数据可视化。过高的维度特征维度的特征矩阵无法通过可视化,数据的性质也就比较难理解。其中主要用到的降维方法为PCA和SVD

PCA

在降维中,我们会减少特征的数量,这意味着删除数据,数据量变少则表示模型可以获取的信息会变少,模型的表现可能会因此受影响。同时,在高维数据中,必然有一些特征是不带有效的信息的(比如噪音),或者有一些特征带有的信息和其他特征的信息是重复的。我们希望能够找到一种方法来帮助我们衡量特征上所带的信息量,让我们在降维过程中,能偶既减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的,新特征矩阵。
为了让降维后的特征能够包含最大差异性的主成分方向,我们通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值特征向量,选择特征值最大的k个特征所对应的特征向量组成的矩阵。这样就可以讲数据矩阵转换到新的空间中,实现数据特征的降维。

计算得到协方差矩阵的特征值特征向量有两种方法:特征值分解协方差矩阵、奇异值分解协方差矩阵,所以PCA主要有两种方法:
基于特征值分解协方差矩阵实现PCA算法、基于SVD分解协方差矩阵实现PCA算法。

特征值分解协方差矩阵

样本方差:

\bar{x} = \frac{1}{n} \sum^N_{i=1}x_i 

样本方差:

S^2 = \frac{1}{n-1}\sum^N_{i=1}(x_i - \bar{x})^2

样本X和Y的协方差:

Cov(X,Y) = E[(X-E(X))(Y-E(Y))] = \frac{1}{n-1} \sum^n_(i=1)(x_i - \bar{x})(y_i - \bar{y})
import numpy as npdata_npy = np.array(data)# 使用 numpy 按步骤实现 PCA
data_cov = np.cov(data_npy, rowvar=False)  
# 将列也就是样本的特征看作变量,计算它们的协方差,我们得到的应该是一个 6 * 6 的矩阵
# 对协方差矩阵进行特征值分解
eigenvalue, eigenvector = np.linalg.eig(data_cov)  
# eigenvalue: 特征值,eigenvector: 特征向量print(eigenvalue,'\n', eigenvector)'''# 将特征值排序
sorted_id = sorted(range(len(eigenvalue)), key=lambda k: eigenvalue[k], reverse=True)  
# 返回降序排列好的特征值对应的索引
# 假设我们降到 2 维,即取最前面的两个特征向量
w = np.array([eigenvector[sorted_id[0]], eigenvector[sorted_id[1]]])

SVD分解协方差矩阵

相较于特征值分解只适用于方阵,奇异值分解适合所有实数矩阵。设 m ∗ n m*n mn实矩阵 A A A,可将其分解为

A = U \Sigma V^T

其中, U U U是满足 U T U = I U^TU=I UTU=I的m阶矩阵, U U U是满足 V T V = I V^TV=I VTV=I的n阶矩阵。 Σ \Sigma Σ m ∗ n m*n mn的矩阵,其中 ( Σ ) i i = σ i (\Sigma )_{ii} = \sigma_i (Σ)ii=σi,其位置元素均为0, σ i \sigma_i σi均为非负实数且满足 σ 1 ≥ σ 2 ≥ σ 3 ≥ . . . ≥ 0 \sigma_1 \ge \sigma_2 \ge \sigma_3 \ge ...\ge 0 σ1σ2σ3...0

其中 U U U的列向量陈伟矩阵 A A A的左奇异向量, V V V的列向量矩阵 A A A的右奇异向量。 σ i \sigma_i σi就是矩阵 A A A的奇异值,其个数等于 A A A的秩。

接下来我们看如何计算 U , Σ , V U,\Sigma , V U,Σ,V
首先将要分解的 m × n m×n m×n的矩阵 A A A乘上它的转置,我们就可以得到一个 m × m m×m m×m的方阵 ( A A T ) (AA^T) (AAT)。那么是方阵的话我们就可以对其进行特征值分解,得到 ( A A T ) U = λ i U (AA^T)U={\lambda_{i}U} (AAT)U=λiU。这里的 U U U就是我们需要的那个 U U U
同上一步,接下来将 A A A的转置乘上它本身,得到一个 n × n n×n n×n的方阵 ( A T A ) (A^TA) (ATA)。同样进行特征值分解,得到 ( A T A ) V = λ i V (A^TA)V = \lambda_i V (ATA)V=λiV 就可计算得到 V V V由:

A = U\Sigma V^T  \Longrightarrow AV = U\Sigma V ^TV \Longrightarrow AV = U \Sigma \Longrightarrow  
\begin{pmatrix}  a_{11} & \cdots & a_{1n} \\  \vdots & \ddots & \vdots \\  a_{m1} & \cdots & a_{mn}  
\end{pmatrix}  (v_1,v_2,...v_n) = (u_1, u_2,...u_n) \Sigma

通过最后得出矩阵方程我们就可以解出 σ i \sigma_i σi,至此我们对 A A A的奇异值分解就结束了。

A = np.array([[1, 2, 8], [-1, 5, 10], [0, 2, 9], [2, 1, 7], [0, 3, 10]])  # shape: (5, 3)
s = np.linalg.svd(A)  # 返回包含三个元素的tuple, 依次是U、Sigma和V^T
'''
(array([[-0.39725362, -0.28034428,  0.20685827, -0.83712199, -0.14153824],[-0.52944196,  0.68764079,  0.41136745,  0.16104935, -0.22733515],[-0.44192138, -0.11186842, -0.71914378,  0.15421894, -0.50123816],[-0.33830158, -0.65916459,  0.4473559 ,  0.49908567, -0.04289846],[-0.50213375,  0.039303  , -0.26587853,  0.02049123,  0.821709  ]]),array([20.78369486,  3.16909449,  0.99743079]),array([[-0.02619432, -0.29687997, -0.95455547],[-0.72144086,  0.66660144, -0.18752494],[ 0.69198045,  0.68374323, -0.23164251]]))
'''
# 根据公式验证结果
Sigma = np.array([[s[1][0], 0, 0], [0, s[1][1], 0], [0, 0, s[1][2]], [0, 0, 0], [0, 0, 0]])  # Sigma形状是(m, n), 即(5, 3)
A_ = np.linalg.multi_dot([s[0], Sigma, s[2]])
print(np.allclose(A, A_))
# True

参考

https://zhuanlan.zhihu.com/p/620573209

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

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

相关文章

浅谈拨测在网络安全中的应用

在当今数字化时代,网络安全成为各个行业和组织关注的焦点。为了保障网络的稳定性和信息的安全,拨测安全性成为一种日益重要的工具。本文将介绍拨测在网络安全中的应用: 1.威胁模拟 通过威胁模拟,拨测安全性可以模拟各种网络攻击&a…

初谈C++:命名空间、输入输出

文章目录 前言C关键字命名空间命名空间的作用命名空间定义命名空间的使用 C的输入&输出 前言 什么是C? C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时&#…

mockjs(3)

mockjs(1) mockjs(2) 这篇主要是Mock.random工具类,前段要用的话主要是在模版中的占位符。mockjs(1)里面的3.2 6 Mock.random Mock.Random 是一个工具类,用于生成各种随机数据。 …

数据结构与算法-绪论

1 绪论 程序 数据结构 算法数据的逻辑结构 四种: 线性结构树形结构图状结构集合结构 数据的存储结构 (逻辑结构在存储器中的映像)常见的有: 数组链表栈队列树堆散列表图 基本数据类型: intfloatdoublecharbool 算法…

Wpf 使用 Prism 实战开发Day15

用户登录和注册接口 一.创建用户登录注册控制器&#xff08;LoginController&#xff09; /// <summary>/// 用户登录注册控制器/// </summary>[ApiController][Route("api/[controller]/[action]")]public class LoginController: ControllerBase{} 二.…

houdini fft 使用三层for each结构 以及for 问题

for each 中 使用 attrib wrangle detail时&#xff0c;不连接foreach_count1&#xff0c;只运行一次 for each 问题 merge eachiteration 对结构进行合并 transform 位置的移动针对的是原位置对原点的距离&#xff0c;而非移动后置0后再移

vivado I/O和时钟规划是定义和分析、I/O和时钟规划阶段、RTL前I/O规划、RTL I/O规划、网表I/O规划、实施设计的最终I/O验证

介绍 I/O和时钟规划是定义和分析 FPGA/自适应SoC和印刷电路板&#xff08;PCB&#xff09;&#xff0c;并分配各种互连信号到设备的物理引脚。这个过程包括PCB设计者、FPGA设计者和系统设计者有以下关注点和要求&#xff1a; •简化关键信号连接&#xff0c;以缩短信号长度并…

Hotspot源码解析-第22章-vtable和itable的重新初始化

第22章-vtable和itable的重新初始化 这个函数的调用流程是 init.cpp->init_globals() universe.cpp->universe_post_init() bool universe_post_init() {// 防止二次初始化assert(!is_init_completed(), "Error: initialization not yet completed!");Univ…

【C++】list容器功能模拟实现

介绍 上一次介绍了list队容器的迭代器模拟&#xff0c;这次模拟实现list的简单功能&#xff0c;尤其要注意构造函数、析构函数、以及赋值运算符重载的实现。 list容器需要接纳所有类型的数据&#xff0c;因此&#xff0c;结构设置与迭代器设置同理&#xff0c;需要引入结点&…

Python中的open与JSON的使用

目录 1 使用 open 函数进行文件操作 2 使用 json 模块进行 JSON 数据处理&#xff1a; 2.1 写入JSON 文件 2.2 读取JSON 文件 在 Python 中&#xff0c;open 函数和 json 模块常用于文件的读写和 JSON 数据的处理。 1 使用 open 函数进行文件操作 open 函数用于打开文件…

复现NAS with RL时pytorch的相关问题

optimizer.zero_grad()是什么&#xff1f; optimizer.zero_grad()是PyTorch中的一个操作&#xff0c;它用于清零所有被优化变量&#xff08;通常是模型的参数&#xff09;的梯度。 在PyTorch中&#xff0c;当你计算某个张量的梯度时&#xff08;比如通过调用.backward()函数&…

“智汇语言·驭领未来”——系列特辑:LLM大模型信息获取与企业应用变革

“智汇语言驭领未来”——系列特辑&#xff1a;LLM大模型信息获取与企业应用变革 原创 认真的飞速小软 飞速创软 2024-01-16 09:30 发表于新加坡 本期引言 LLM&#xff08;Large Language Model&#xff09;大型语言模型以其自然语言理解和生成能力&#xff0c;正以前所未有的…

libtorch学习第六

构建卷积网络 #include<torch/torch.h> #include<torch/script.h> #include<iostream>using std::cout; using std::endl;class LinearBnReluImpl : public torch::nn::Module { private:torch::nn::Linear ln{ nullptr };torch::nn::BatchNorm1d bn{ nullp…

在jetson上对fastdeploy进行源码编译(完整版)

文章目录 准备工作下载飞桨推理库编译代码可能遇到的问题Could NOT find PythonNo CMAKE_CUDA_COMPILER could be found.准备工作 jetpackcudaopencv下载飞桨推理库 根据jetpack的版本选择对应的推理库版本 https://www.paddlepaddle.org.cn/inference/v2.6/guides/install/do…

开源的测试平台快2千星了,能带来多少收益呢

最近看了下自己去年初开源的测试平台&#xff0c;star一起算的话也到1.7k了&#xff1a; 做开源的初心一方面是想把自己的理解和思想展示出来&#xff0c;另一方面是想进一步打造个人IP&#xff0c;提升影响力&#xff08;其实这个想法很早之前就有了&#xff0c;计划过无数次但…

Day 28 | 回溯 93.复原IP地址 、78.子集 、 90.子集II

93.复原IP地址 题目 文章讲解 视频讲解 思路&#xff1a;每轮开始的位置需要变化就需要设置start class Solution {List<String> result new ArrayList<>();public List<String> restoreIpAddresses(String s) {if (s.length() < 4 ||s.length() >…

2765. 最长交替子数组 ( leetcode 01 - 23 每日 )

链接 : 最长交替子数组 思路 : 对于每个起点&#xff0c;都是x,x1,x,x1....这样的循环&#xff0c;那么枚举每个起点模拟即可 &#xff1b; 代码 : class Solution {public int alternatingSubarray(int[] nums) {int ans 0-1 ;int n nums.length , i 0 ; while(i &…

高精度运算合集,加减乘除,快速幂,详细代码,OJ链接

文章目录 零、前言一、加法高精度加法步骤P1601 AB 二、减法高精度减法步骤P2142 高精度减法 三、乘法高精度乘法步骤P1303 A*B 四、除法高精度除法步骤P1480 A/B 五、高精度快速幂麦森数 零、前言 高精度运算是某些题目涉及大数值运算且范围超出语言内置类型允许范围时采取的处…

服务器数据恢复—服务器进水导致阵列中磁盘同时掉线的数据恢复案例

服务器数据恢复环境&#xff1a; 数台服务器数台存储阵列柜&#xff0c;共上百块硬盘&#xff0c;划分了数十组lun。 服务器故障&检测&#xff1a; 外部因素导致服务器进水&#xff0c;进水服务器中一组阵列内的所有硬盘同时掉线。 北亚数据恢复工程师到达现场后发现机房内…

从0开始学习C++ 第十三课:结构体和联合体

第十三课&#xff1a;结构体和联合体 学习目标&#xff1a; 理解结构体的基本概念和如何定义结构体。学习如何使用结构体来组织相关数据。了解联合体的概念及其与结构体的不同点。 学习内容&#xff1a; 结构体 概念&#xff1a; 结构体是C中用于表示一组相关数据的复合数据…