1、特征值与特征向量
在了解SVD奇异矩阵前,先回顾一下特征值与特征向量。假设矩阵
A
A
A为n阶方阵,向量
v
i
v_i
vi满足:
A
v
i
=
λ
v
i
Av_i=λv_i
Avi=λvi
用所有特征值构成的对角矩阵
Σ
\Sigma
Σ 和所有特征向量构成的矩阵
V
V
V 来表示与A的关系:
A
=
V
Σ
V
−
1
A=V\Sigma V^{-1}
A=VΣV−1
因此只要满足上面的等式,我们便可认为V是矩阵A的特征向量组成的矩阵,称λ为特征值,
v
i
v_i
vi为特征向量之一。
求出特征值和特征向量有什么好处呢? 就是可以将矩阵A特征分解。如果我们求出了矩阵A的n个特征值
λ
1
≤
λ
2
≤
.
.
.
≤
λ
n
λ_1≤λ_2≤...≤λ_n
λ1≤λ2≤...≤λn,以及这n个特征值所对应的特征向量
(
v
1
,
v
2
,
.
.
.
v
n
)
(v_1,v_2,...v_n)
(v1,v2,...vn),如果这n个特征向量线性无关(通常需要实对称矩阵,且特征值不相同),且满足
∣
∣
v
i
∣
∣
2
=
1
||v_i||^2=1
∣∣vi∣∣2=1 即向量标准化, 有
v
i
T
v
i
=
1
v_i^Tv_i=1
viTvi=1,此时V的n个特征向量为标准正交基,即
V
−
1
=
V
T
V^{-1}=V^T
V−1=VT,则我们称矩阵
V
V
V 是酉矩阵 。那么矩阵A就可以用下式的特征分解表示:
A
=
V
Σ
V
T
A = VΣV^T
A=VΣVT
下面可以用代码来验证上述情况
A = X = np.array([[-1,-4,1],[-4,3,0],[1,0,2]])
A
featureMatrix = np.linalg.eig(A)[1]
featureMatrix
# 由特征向量组成的矩阵
featureValue = np.linalg.eig(A)[0]
# 特征值,与特征向量一一对应
featureValue
diag_mat = np.diag(featureValue)
# 由特征值组成的对角落矩阵
a = featureMatrix @ diag_mat @ featureMatrix.T
np.round(a,0)
我们可以发现,二者是等价的。注意:上式要保证A是实对称矩阵,这样特征向量之间才会相互正交且都为单位向量
2、SVD的定义
SVD也是对矩阵进行分解,但是和特征分解不同,SVD并不要求要分解的矩阵为方阵。假设我们的矩阵A是一个m×n的矩阵,那么我们定义矩阵A的SVD为:
A
=
U
Σ
V
T
A = UΣV^T
A=UΣVT
其中U是一个m×m的矩阵,Σ是一个m×n的矩阵,除了主对角线上的元素以外全为0,主对角线上的每个元素都称为奇异值,V是一个n×n的矩阵。U和V都是酉矩阵,即满足
U
T
U
=
I
U^TU=I
UTU=I;
V
T
V
=
I
V^TV=I
VTV=I 。下图可以很形象的看出上面SVD的定义:
V
V
V 是
实
对
称
矩
阵
A
T
A
实对称矩阵A^TA
实对称矩阵ATA的特征向量组成的矩阵,
U
U
U 是
实
对
称
矩
阵
A
A
T
实对称矩阵AA^T
实对称矩阵AAT的特征向量组成的矩阵,有人要问了,这是为啥??
这里只对U推导,过程如下:
A
=
U
Σ
V
T
,
A
T
=
V
Σ
U
T
A = UΣV^T, A^T=VΣU^T
A=UΣVT,AT=VΣUT
A
A
T
=
U
Σ
V
T
V
Σ
U
T
AA^T=UΣV^TVΣU^T
AAT=UΣVTVΣUT
已知U是酉矩阵$,得到下式:
A
A
T
=
U
Σ
2
U
T
AA^T=UΣ^2U^T
AAT=UΣ2UT
对应上一节内容,可得矩阵U是实对称矩阵AA^T的特征矩阵。习惯上叫
U
U
U 为左奇异矩阵,
V
V
V 为右奇异矩阵;进一步我们可以发现奇异值与特征值的关系:
σ
2
是
A
A
T
特
征
值
\sigma^2 是AA^T特征值
σ2是AAT特征值
σ
2
=
λ
,
需
要
注
意
正
负
号
关
系
{\sigma}^2=λ,需要注意正负号关系
σ2=λ,需要注意正负号关系
如果你不喜欢这种推导方式,别急,还有一种方法:
A
V
=
U
Σ
V
T
V
=
U
Σ
AV=UΣV^TV=UΣ
AV=UΣVTV=UΣ
则
A
V
i
/
U
i
=
σ
i
,
对
应
元
素
相
除
就
行
则AV_i / U_i = \sigma_i, 对应元素相除就行
则AVi/Ui=σi,对应元素相除就行
下面给个具体案例:
A
=
(
0
1
1
1
1
0
)
A = \begin{pmatrix} 0 & 1 \\ 1 & 1 \\ 1 & 0 \end{pmatrix}
A=⎝⎛011110⎠⎞
A
A
T
=
(
1
1
0
1
2
1
0
1
1
)
AA^T= \begin{pmatrix} 1 & 1 & 0 \\ 1 & 2 & 1 \\0 & 1 & 1\end{pmatrix}
AAT=⎝⎛110121011⎠⎞
A
T
A
=
(
2
1
1
2
)
A^TA= \begin{pmatrix} 2 & 1 \\ 1 & 2\end{pmatrix}
ATA=(2112)
V
=
(
0.70710678
−
0.70710678
0.70710678
0.70710678
)
V= \begin{pmatrix} 0.70710678 & -0.70710678\\ 0.70710678 & 0.70710678\end{pmatrix}
V=(0.707106780.70710678−0.707106780.70710678)
U
=
(
−
4.08248290
e
−
01
−
8.16496581
e
−
01
−
4.08248290
e
−
01
7.07106781
e
−
01
2.61239546
e
−
16
−
7.07106781
e
−
01
5.77350269
e
−
01
−
5.77350269
e
−
01
5.77350269
e
−
01
)
U= \begin{pmatrix} -4.08248290e-01 & -8.16496581e-01 & -4.08248290e-01 \\ 7.07106781e-01 & 2.61239546e-16 & -7.07106781e-01 \\5.77350269e-01 & -5.77350269e-01 & 5.77350269e-01\end{pmatrix}
U=⎝⎛−4.08248290e−017.07106781e−015.77350269e−01−8.16496581e−012.61239546e−16−5.77350269e−01−4.08248290e−01−7.07106781e−015.77350269e−01⎠⎞
A V / U = λ = − 1.7320508066304454 , 1 AV/U=λ = -1.7320508066304454,1 AV/U=λ=−1.7320508066304454,1
Σ = ( − 1.7320508066304454 0 0 1 0 0 ) \Sigma= \begin{pmatrix} -1.7320508066304454 & 0 \\ 0& 1 \\0 & 0\end{pmatrix} Σ=⎝⎛−1.732050806630445400010⎠⎞,最好是具体的一一对应去求解
U Σ V T = ( 0 1 1 1 1 0 ) U\Sigma V^T= \begin{pmatrix} 0 & 1 \\ 1 & 1 \\ 1 & 0 \end{pmatrix} UΣVT=⎝⎛011110⎠⎞。
import numpy as np
A = np.array([[0,1],[1,1],[1,0]])
uTmp = A @ A.T
vTmp = A.T @ A
V = np.linalg.eig(vTmp)[1]
U = np.linalg.eig(uTmp)[1]
svd = np.array([[-1.7320508066304454,0],[0,1],[0,0]])
3、SVD应用
- 第一:SVD可以把主要特征分解,即取前面那些大的奇异值,这样可以做推荐系统,把所有特征映射成矩阵,通过主要特征找到重要信息,然后决定是否推荐。
- 第二:在做图片识别时,肯定有前景和背景,而背景在做识别起到的作用很小,于是我们取其大的特征值,在原来信息上损失一部分(但该部分可能不重要,占比极低),减少数据量,或者数据量不足时也能识别。
4、主成分分析PCA
PCA(principal components analysis)即主成分分析技术,又称主分量分析。主成分分析也称主分量分析,旨在利用降维的思想,把多指标转化为少数几个综合指标。
在统计学中,主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成分)上,第二大方差在第二个坐标(第二主成分)上,依次类推。如下图,原来的x2维度携带的信息量很少,将坐标转换成w1,w2,仅用w1坐标便可表示大部分信息。
附上图片代码
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x = np.arange(0,5,0.01)
e = 0.35*np.random.normal(0,1,len(x))
y = x + e
y_bar = np.mean(y)
x_bar = np.mean(x)
ax.scatter(x, y)
ax.annotate('o', # ⽂本内容
xy=(x_bar+1, y_bar+1.05), # 箭头指向位置
xytext=(x_bar, y_bar), # ⽂本位置
fontsize=12,
arrowprops=dict(facecolor='black', width=1, color='red',headwidth=6, headlength=8, shrink=10)) # 箭头
ax.annotate('o', # ⽂本内容
xy=(x_bar-0.3, y_bar+1.2), # 箭头指向位置
xytext=(x_bar, y_bar), # ⽂本位置
fontsize=12,
arrowprops=dict(facecolor='black', width=1, color='red',headwidth=6, headlength=8, shrink=10)) # 箭头
plt.show()
降维策略:在投影方向获得最大方差(数据区分度高)
注意:这里w1,w2都是单位向量,表示新坐标系的基底
1、中心化,目的是方便计算,中心点为新坐标轴原点。首先我们对数据做一个中心化处理,即
X
−
n
p
.
m
e
a
n
(
X
)
X-np.mean(X)
X−np.mean(X)
2、
x
(
i
)
⋅
w
1
x^{(i)}·w_1
x(i)⋅w1 表示样本中心化后在w1坐标上投影长度。
我们希望投影方差最大,即:
m
a
x
∑
i
=
1
n
(
x
(
i
)
⋅
w
1
)
2
max\sum_{i=1}^n{(x^{(i)}·w_1)}^2
maxi=1∑n(x(i)⋅w1)2
m
a
x
∑
i
=
1
n
(
x
(
i
)
⋅
w
1
)
T
(
x
(
i
)
⋅
w
1
)
max\sum_{i=1}^n(x^{(i)}·w_1)^T(x^{(i)}·w_1)
maxi=1∑n(x(i)⋅w1)T(x(i)⋅w1)
=
m
a
x
∑
i
=
1
n
w
1
T
x
(
i
)
⋅
T
x
(
i
)
⋅
w
1
=max\sum_{i=1}^nw_1^T{x^{(i)}·}^Tx^{(i)}·w_1
=maxi=1∑nw1Tx(i)⋅Tx(i)⋅w1
=
m
a
x
[
w
1
T
∑
i
=
1
n
x
(
i
)
⋅
T
x
(
i
)
⋅
w
1
]
=max[w_1^T\sum_{i=1}^n{x^{(i)}·}^Tx^{(i)}·w_1]
=max[w1Ti=1∑nx(i)⋅Tx(i)⋅w1]
=
m
a
x
(
w
1
T
Σ
w
1
)
,
Σ
是
X
的
协
方
差
矩
阵
=max (w_1^T\Sigma w_1),\Sigma是X的协方差矩阵
=max(w1TΣw1),Σ是X的协方差矩阵
假设最大值为 λ,则有
λ
=
(
w
1
T
Σ
w
1
)
λ = (w_1^T\Sigma w_1)
λ=(w1TΣw1)
λ
⋅
w
1
=
w
1
w
1
T
Σ
w
1
=
Σ
w
1
λ·w_1= w_1w_1^T\Sigma w_1=\Sigma w_1
λ⋅w1=w1w1TΣw1=Σw1
因此等价于λ 的最大值就是协方差矩阵特征值
Σ
\Sigma
Σ 矩阵主对角线上的最大元素。我们想降到多少维,只需将特征值从大到小排序,然后取其特征值对应的特征向量
w
i
w_i
wi.
新坐标值
z
(
i
)
=
w
1
T
x
(
i
)
z^{(i)} = w_1^Tx^{(i)}
z(i)=w1Tx(i)
上面只是把二维的放在一维,更高维度的缩放,只需把 w 1 w_1 w1改写成W即可 Z = W T X Z = W^TX Z=WTX,其中矩阵 W W W 对应的是协方差矩阵 Σ \Sigma Σ 排序后的特征向量矩阵。
上面推导仅是个人的简易推导,详细内容看参考链接,如有不对的对方您可以详细指出,定当改正!