#机器学习--实例--主成分分析
引言
本系列博客旨在为机器学习(深度学习)提供数学理论基础。因此内容更为精简,适合二次学习的读者快速学习或查阅。
主成分分析(PCA)介绍
主成分分析(principal components analysis,PCA)是一个简单的机器学习算法,能够在损失精度尽可能少的前提下,对数据进行有损压缩。
推导过程
假设有矩阵
A
m
,
n
A_{m,n}
Am,n ,我们希望通过一个函数
f
f
f 对其进行有损压缩,即
C
l
,
n
=
f
(
A
m
,
n
)
(
l
≤
m
)
C_{l,n}=f(A_{m,n})(l\le m)
Cl,n=f(Am,n)(l≤m) 。压缩后,我们希望能够通过一个函数
g
g
g 对其进行最大程度的还原,即
A
m
,
n
≈
g
(
C
l
,
n
)
A_{m,n}\approx g(C_{l,n})
Am,n≈g(Cl,n)。
为了使问题简化,我们令解码函数
g
(
C
l
,
n
)
=
D
m
,
l
C
l
,
n
g(C_{l,n})=D_{m,l}C_{l,n}
g(Cl,n)=Dm,lCl,n ,在此假设下,我们需要找到编码函数
f
f
f ,使得信息损失最小,即:
arg min
C
∣
∣
D
C
−
A
∣
∣
F
\argmin_{C}||DC-A||_{F}
Cargmin∣∣DC−A∣∣F
=
>
arg min
C
∣
∣
D
C
−
A
∣
∣
F
2
=>\argmin_{C}||DC-A||_{F}^{2}
=>Cargmin∣∣DC−A∣∣F2
=
>
arg min
C
T
r
[
(
D
C
−
A
)
(
D
C
−
A
)
T
]
=>\argmin_{C}Tr[(DC-A)(DC-A)^{T}]
=>CargminTr[(DC−A)(DC−A)T]
=
>
arg min
C
T
r
(
D
C
C
T
D
T
−
D
C
A
T
−
A
C
T
D
T
+
A
A
T
)
=>\argmin_{C}Tr(DCC^{T}D^{T}-DCA^{T}-AC^{T}D^{T}+AA^{T})
=>CargminTr(DCCTDT−DCAT−ACTDT+AAT)
=
>
arg min
C
T
r
(
D
C
C
T
D
T
)
−
2
T
r
(
D
C
A
T
)
=>\argmin_{C}Tr(DCC^{T}D^{T})-2Tr(DCA^{T})
=>CargminTr(DCCTDT)−2Tr(DCAT)
求导,令导数为
0
得:
D
T
D
C
=
D
T
A
求导,令导数为0得:D^{T}DC=D^{T}A
求导,令导数为0得:DTDC=DTA
为了确保矩阵
D
D
D 的唯一性,令
D
D
D 中所有列向量均互为单位正交向量,即
D
T
D
=
I
l
D^{T}D=I_{l}
DTD=Il,有
C
=
D
T
A
C=D^{T}A
C=DTA,即
f
(
A
)
=
D
T
A
f(A)=D^{T}A
f(A)=DTA 。至此编码函数找到了,最后一步需要找到矩阵
D
D
D ,使得编码解码后的信息损失最小,即:
arg min
D
∣
∣
A
−
D
D
T
A
∣
∣
F
,
s
.
t
.
D
T
D
=
I
l
\argmin_{D}||A-DD^{T}A||_{F},s.t.D^{T}D=I_{l}
Dargmin∣∣A−DDTA∣∣F,s.t.DTD=Il
=
>
arg min
D
∣
∣
A
−
D
D
T
A
∣
∣
F
2
,
s
.
t
.
D
T
D
=
I
l
=>\argmin_{D}||A-DD^{T}A||^{2}_{F},s.t.D^{T}D=I_{l}
=>Dargmin∣∣A−DDTA∣∣F2,s.t.DTD=Il
=
>
arg min
D
T
r
[
(
A
−
D
D
T
A
)
(
A
−
D
D
T
A
)
T
]
,
s
.
t
.
D
T
D
=
I
l
=>\argmin_{D}Tr[(A-DD^{T}A)(A-DD^{T}A)^{T}],s.t.D^{T}D=I_{l}
=>DargminTr[(A−DDTA)(A−DDTA)T],s.t.DTD=Il
=
>
arg min
D
T
r
(
A
A
T
−
2
A
A
T
D
D
T
+
A
A
T
D
D
T
D
D
T
)
,
s
.
t
.
D
T
D
=
I
l
=>\argmin_{D}Tr(AA^{T}-2AA^{T}DD^{T}+AA^{T}DD^{T}DD^{T}),s.t.D^{T}D=I_{l}
=>DargminTr(AAT−2AATDDT+AATDDTDDT),s.t.DTD=Il
=
>
arg min
D
−
T
r
(
A
A
T
D
D
T
)
,
s
.
t
.
D
T
D
=
I
l
=>\argmin_{D}-Tr(AA^{T}DD^{T}),s.t.D^{T}D=I_{l}
=>Dargmin−Tr(AATDDT),s.t.DTD=Il
根据拉格朗日乘数法,有:
arg min
D
−
T
r
(
A
A
T
D
D
T
)
+
λ
(
D
T
D
−
I
l
)
根据拉格朗日乘数法,有:\argmin_{D}-Tr(AA^{T}DD^{T})+\lambda(D^{T}D-I_{l})
根据拉格朗日乘数法,有:Dargmin−Tr(AATDDT)+λ(DTD−Il)
求导,令导数为
0
得:
A
A
T
D
=
λ
D
求导,令导数为0得:AA^{T}D=\lambda D
求导,令导数为0得:AATD=λD
最终我们得出结论,
D
l
,
n
D_{l,n}
Dl,n 就是由矩阵
A
A
T
AA^{T}
AAT 的
l
l
l 个单位特征向量所构成的。若有不懂,请回顾前面的线性代数基础部分。
代码实现
import numpy as np
class PCAModel:
def __init__(self):
self.d = None
def fit(self, x, target_l):
"""
填充训练数据,进行主成分分析
:param x: 训练数据矩阵,每一个列向量为一条训练数据
:param target_l: 目标维度,应小于矩阵x中列向量的长度
"""
if target_l >= x.shape[0]:
raise ValueError("target_l should greater than x.shape[0]")
features, f_vec = np.linalg.eig(np.matmul(x, x.T))
self.d = f_vec[:, :target_l]
def transform(self, x):
"""
对数据x进行降维
"""
return np.matmul(self.d.T, x)
def reverse_transform(self, x):
"""
对数据x进行还原
"""
return np.matmul(self.d, x)
train_x = np.array([[1,2],[3,4],[5,6]])
print(train_x)
# [[1 2]
# [3 4]
# [5 6]]
model = PCAModel()
model.fit(tran_x, 2)
result = model.transform(train_x)
print(result)
# [[-5.90229186 -7.47652631]
# [ 0.40367167 -0.3186758 ]]
pred_y = model.reverse_transform(result)
print(pred_y)
# [[1. 2.]
# [3. 4.]
# [5. 6.]]
从运行结果中可以看出,对数据进行压缩后能够完美进行还原。