降维方法:PCA&SVD

个人觉得关于PCA(主成分分析)和SVD(矩阵奇异值分解)两篇不错的博客:

PCA:http://www.cnblogs.com/pinard/p/6239403.html

SVD:http://www.cnblogs.com/pinard/p/6251584.html

简单来说:PCA是将高维数据在低维方向上投影从而达到降维的目的,SVD是将矩阵分解为低维矩阵的乘积。

两者都是建立在矩阵的特征值和特征向量这一基石上,即:Ax=x。

1)PCA具体过程如下:

假设有一组数据{(xi,yi)|i=1,2,3....}

为这组数据得到协方差矩阵

A降维以后为B,则B=rA

r为X最大的特征值对应的特征向量.


2)SVD具体过程如下:

假设有矩阵A

矩阵A的SVD分解如下:
A=U*S*V
其中:
U=的特征向量构成的矩阵
V=的特征向量构成的矩阵
S=的特征值开根构成的矩阵

下面看一个直观的例子,你会切身发现SVD的神奇之处:

>>> import numpy as np
>>> A=np.random.randint(0,10,size=[5,4])
>>> A
array([[1, 1, 1, 2],
       [5, 9, 9, 7],
       [3, 9, 6, 5],
       [7, 1, 6, 5],

       [0, 8, 4, 4]])

>>> from numpy import linalg as la
>>> U,S,V=la.svd(A)
>>> U
array([[-0.10392588,  0.0687753 ,  0.81642429,  0.20828833, -0.52396252],
       [-0.65996272,  0.04593935, -0.20733647, -0.58621402, -0.41917001],
       [-0.52059928, -0.26035621, -0.30230549,  0.74754328, -0.1047925 ],
       [-0.36667027,  0.81085029,  0.11978263,  0.13425103,  0.41917001],
       [-0.38493886, -0.51758669,  0.42979818, -0.19006526,  0.60255689]])
>>> S
array([23.25896126,  7.62618526,  1.13390704,  0.75912737])
>>> V
array([[-0.32384203, -0.60944962, -0.55492431, -0.46449598],
       [ 0.68098994, -0.68065743,  0.22486304,  0.14964883],
       [-0.254603  , -0.18712759, -0.3752939 ,  0.87138687],

       [ 0.60543897,  0.36091535, -0.70756633, -0.05033531]])

取S的前4列重构为S1

>>> S1=np.eye(len(S))*S
>>> S1
array([[23.25896126,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  7.62618526,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  1.13390704,  0.        ],

       [ 0.        ,  0.        ,  0.        ,  0.75912737]])

>>> a=np.dot(U[:,:4],S1)

由S的前4列最终生成的B(与原始矩阵A基本一样)

>>> B=np.dot(a,V)
>>> B
array([[ 1.000000e+00,  1.000000e+00,  1.000000e+00,  2.000000e+00],
       [ 5.000000e+00,  9.000000e+00,  9.000000e+00,  7.000000e+00],
       [ 3.000000e+00,  9.000000e+00,  6.000000e+00,  5.000000e+00],
       [ 7.000000e+00,  1.000000e+00,  6.000000e+00,  5.000000e+00],

       [-8.491496e-16,  8.000000e+00,  4.000000e+00,  4.000000e+00]])


作为对比,取S的前两列重构为S2

>>> S2=np.eye(2)*S[:2]
>>> S2
array([[23.25896126,  0.        ],

       [ 0.        ,  7.62618526]])

由S的前两列生成矩阵B2(B2与A相比信息有所丢失,但仍然保留的大部分信息)

>>> a1=np.dot(U[:,:2],S2)

>>> B2=np.dot(a1,V[:2,:])
>>> B2
array([[1.13996811, 1.11616623, 1.45930657, 1.20127315],
       [5.20956983, 9.11661759, 8.59689342, 7.18246353],
       [2.56915072, 8.73104277, 6.27288452, 5.32726381],
       [6.9728783 , 0.98863392, 6.12308396, 4.88677603],
       [0.21143607, 8.14327107, 4.08080961, 3.56806601]])







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UCASer_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值