SVD 原理

奇异值分解(Singular Value Decomposition)是线性代数中一种重要的矩阵分解,也是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域。

有一个×的实数矩阵,我们想要把它分解成如下的形式:$A = U\Sigma V^T$

其中和均为单位正交阵,即有$=$和$=$,称为左奇异矩阵,称为右奇异矩阵,Σ仅在主对角线上有值,我们称它为奇异值,其它元素均为0。

上面矩阵的维度分别为$U \in R^{m\times m}$,$\ \Sigma \in R^{m\times n}$,$\ V \in R^{n\times n}$。

一般地Σ有如下形式

$$

\Sigma =

\left[

\begin{matrix}

\sigma_1 & 0 & 0 & 0 & 0\

0 & \sigma_2 & 0 & 0 & 0\

0 & 0 & \ddots & 0 & 0\

0 & 0 & 0 & \ddots & 0\

\end{matrix}

\right]_{m\times n}

$$

$_$ 越大意味着对应的 $′$ 的特征值 $\sigma_j^2$ 越大, 从而其主成分 (principal component) $_$ 的样本方差越大, 我们把方差大视为提供了更多信息.

求解U, Σ, V

假设我们的矩阵A是一个m×n的矩阵,则$A^TA$是方阵,求其特征值及特征向量:

$(A^TA)v_i = \lambda_i v_i$

得到矩阵$A^TA$的n个特征值和对应的n个特征向量$v$



$ATA=V\SigmaTU^TU\Sigma V^T$ =$V\Sigma^T\Sigma V^T= V\Sigma2VT$

将特征向量$v$张成一个$n×n$的矩阵$V$,就是SVD公式里面的$V$矩阵,$V$中的每个特征向量叫做$A$的右奇异向量。

同理:$(AA^T)u_i = \lambda_i u_i$,可得$U$矩阵。

求得$U , V$,然后求Σ,因Σ为奇异值矩阵,所以只需要求出每个奇异值$σ$即可。

$A=U\Sigma V^T \Rightarrow AV=U\Sigma V^TV \Rightarrow $

$AV=U\Sigma \Rightarrow Av_i = \sigma_i u_i \Rightarrow \sigma_i=Av_i / u_i$

其实特征值矩阵等于奇异值矩阵的平方,也就是说特征值和奇异值满足如下关系:

$\sigma_i = \sqrt{\lambda_i}$

所以不用$\sigma_i = Av_i / u_i$也可以通过求出$A^TA$的特征值取平方根来求奇异值。

SVD算法


输入:样本数据

输出:左奇异矩阵,奇异值矩阵,右奇异矩阵

1 计算特征值: 特征值分解$AA^T$,其中$A \in \mathbf{R}^{m\times n}$为原始样本数据

$AA^T=U\Sigma \SigmaTUT$

得到左奇异矩阵$U \in \mathbf{R}^{m \times m}$和奇异值矩阵$\Sigma' \in \mathbf{R}^{m \times m}$

2 间接求部分右奇异矩阵: 求$V' \in \mathbf{R}^{m \times n}$

利用A=UΣ′V′可得

$V' = (U\Sigma')^{-1}A = (\Sigma'){-1}UTA$

3 返回U, Σ′, V′,分别为左奇异矩阵,奇异值矩阵,右奇异矩阵。


Python 求解SVD

from numpy import array
from numpy import diag
from numpy import zeros
from scipy.linalg import svd
# define a matrix
A = array([
[1,2,3,4,5,6,7,8,9,10],
[11,12,13,14,15,16,17,18,19,20],
[21,22,23,24,25,26,27,28,29,30]])
print(A)
>>> A
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30]])
# Singular-value decomposition
U, s, VT = svd(A)
# create m x n Sigma matrix
Sigma = zeros((A.shape[0], A.shape[1]))
# populate Sigma with n x n diagonal matrix
Sigma[:A.shape[0], :A.shape[0]] = diag(s)
# select
n_elements = 2
Sigma = Sigma[:, :n_elements]
VT = VT[:n_elements, :]
# reconstruct
B = U.dot(Sigma.dot(VT))
print(B)
>>> B
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[11., 12., 13., 14., 15., 16., 17., 18., 19., 20.],
[21., 22., 23., 24., 25., 26., 27., 28., 29., 30.]])
# transform
T = U.dot(Sigma)
print(T)
>>> T
array([[-18.52157747, 6.47697214],
[-49.81310011, 1.91182038],
[-81.10462276, -2.65333138]])
T = A.dot(VT.T)
print(T)
[[-18.52157747   6.47697214]
[-49.81310011 1.91182038]
[-81.10462276 -2.65333138]]

参考:

https://www.cnblogs.com/pinard/p/6251584.html

https://www.cnblogs.com/endlesscoding/p/10033527.html

最新文章

  1. MongoDB实现分页(两种方法)
  2. [LintCode] Longest Common Prefix 最长共同前缀
  3. 7.SpringMVC注解优化
  4. Django~urls.py--->views.py
  5. java JDK8 学习笔记——第13章 时间与日期
  6. 解决VS2010无法打开,提示无法找到atl100.dll的方法
  7. window2003安全设置
  8. BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛
  9. Spring AOP体系学习总结:
  10. 工作总结:VS2010/MFC编程入门之十六(对话框:消息对话框)
  11. HIVE快速入门
  12. Eratosthenes筛选法计算质数
  13. 练习 jquery+Ajax+Json 绑定数据 分类: asp.net 练习 jquery+Ajax+Json 绑定数据 分类: asp.net
  14. 通过无线连接的方式来做 Appium 自动化
  15. html常用的知识点以及混合框架
  16. Spring详解(八)------事务管理
  17. SSL延迟有多大 (Https)
  18. pyDes库 实现python的des加密
  19. 多个Firefox共存&&彻底关闭自动更新
  20. servlet的方法解析

热门文章

  1. java+eclipse安装及配置
  2. PCIe Tandem PROM 方法
  3. 还在担心CC攻击? 让我们来了解它, 并尽可能将其拒之服务之外.
  4. Java LRU实现方式
  5. spring boot 自动装配的原理
  6. runnable 和 callable 有什么区别
  7. SaltStack项目实战(一)
  8. SpringCloud个人笔记-01-Eureka初体验
  9. 8_根轨迹_Part2_根轨迹手绘技巧
  10. 国际化相对时间格式化API:Intl.RelativeTimeFormat