引
PPCA 通过高斯过程给出了普通PCA一个概率解释,这是很有意义的。论文还利用PPCA进行缺失数据等方面的处理(不过这方面主要归功于高斯过程吧)。
t
=
W
x
+
μ
+
ϵ
t = Wx + \mu + \epsilon
t=Wx+μ+ϵ
其中
t
∈
R
d
t \in \mathbb{R}^d
t∈Rd为观测变量,也就是样本,而
x
∈
R
q
x \in \mathbb{R}^q
x∈Rq是隐变量,
W
∈
R
d
×
q
W \in \mathbb{R}^{d \times q}
W∈Rd×q将
x
,
t
x,t
x,t二者联系起来。另外,
ϵ
\epsilon
ϵ是噪声。
令 S = 1 N ∑ n = 1 N ( t n − μ ) ( t n − μ ) T S = \frac{1}{N} \sum \limits_{n=1}^N (t_n -\mu )(t_n - \mu)^T S=N1n=1∑N(tn−μ)(tn−μ)T是样本协方差矩阵,其中 μ \mu μ是样本均值。论文的主要工作,就是将 S S S的列空间和 W W W联系起来。
主要内容
假设
ϵ
∼
N
(
0
,
σ
2
I
)
\epsilon \sim N(0, \sigma^2 I)
ϵ∼N(0,σ2I),
 
x
∼
N
(
0
,
I
)
\: x \sim N(0, I)
x∼N(0,I),二者独立。那么,容易知道
t
t
t在
x
x
x已知的情况下的条件概率为:
t
∣
x
∼
N
(
W
x
+
μ
,
σ
2
I
)
t|x \sim N(Wx + \mu, \sigma^2I)
t∣x∼N(Wx+μ,σ2I)
然后论文指出,通过其可求得
t
t
t的边际分布:
t
∼
N
(
μ
,
C
)
t \sim N(\mu, C)
t∼N(μ,C)
其中
C
=
W
W
T
+
σ
2
I
C = WW^T + \sigma^2 I
C=WWT+σ2I。这个证明,在贝叶斯优化中有提过,不过我发现,因为
t
=
W
x
+
μ
+
ϵ
t=Wx+\mu + \epsilon
t=Wx+μ+ϵ,是服从正态分布随机变量的线性组合,所以
t
t
t也服从正态分布,所以通过
E
(
t
)
E(t)
E(t)和
E
(
(
t
−
E
(
t
)
)
(
t
−
E
(
t
)
)
T
)
E((t-E(t))(t-E(t))^T)
E((t−E(t))(t−E(t))T)也可以得到
t
t
t的分布。
其似然函数
L
L
L为:
将
W
,
σ
W,\sigma
W,σ视为参数,我们可以得到其极大似然估计:
其中
U
q
U_{q}
Uq的列是
S
S
S的主特征向量,而
Λ
q
\Lambda_q
Λq的对角线元素为特征向量对应的特征值
λ
1
,
…
,
λ
q
\lambda_1, \ldots, \lambda_q
λ1,…,λq(为所有特征值的前
q
q
q个,否则
W
W
W将成为鞍点),
R
∈
R
q
×
q
R \in \mathbb{R}^{q \times q}
R∈Rq×q是一个旋转矩阵。注意到,
W
M
L
W_{ML}
WML的列向量并不一定正交。
这部分的推导见附录。
同样的,我们可以推导出,
x
x
x在
t
t
t已知的情况下的条件分布:
x
∣
t
∼
N
(
M
−
1
W
T
(
t
−
μ
)
,
σ
2
M
−
1
x|t \sim N(M^{-1}W^T(t-\mu),\sigma^2 M^{-1}
x∣t∼N(M−1WT(t−μ),σ2M−1
其中
M
=
W
T
W
+
σ
2
I
M = W^TW+\sigma^2I
M=WTW+σ2I
这个推导需要利用贝叶斯公式:
p
(
x
∣
t
)
=
p
(
t
∣
x
)
p
(
t
)
p
(
t
)
p(x|t) = \frac{p(t|x)p(t)}{p(t)}
p(x∣t)=p(t)p(t∣x)p(t)
为什么要提及这个东西,因为可以引出一个很有趣的性质,注意到
x
∣
t
x|t
x∣t的均值为:
M
−
1
W
T
(
t
−
u
)
M^{-1}W^T(t-u)
M−1WT(t−u)
令
W
=
W
M
L
W = W_{ML}
W=WML,且假设
σ
2
→
0
\sigma^2 \rightarrow 0
σ2→0,那么均值就成为:
(
W
M
L
T
W
M
L
)
−
1
W
M
L
T
(
t
−
u
)
(W_{ML}^TW_{ML})^{-1}W_{ML}^T(t-u)
(WMLTWML)−1WMLT(t−u)
实际上就是
(
t
−
u
)
(t-u)
(t−u)在主成分载荷向量上的正交投影,当然这里不要计较
W
M
L
T
W
M
L
W_{ML}^TW_{ML}
WMLTWML是否可逆。这就又将PPCA与普通的PCA联系在了一起。
EM算法求解
论文给出了 W W W的显式解(虽然有点地方不是很明白),也给出了如何利用EM算法来求解。
构造似然估计:
对
x
n
x_n
xn求条件期望(条件概率为
p
(
x
n
∣
t
n
,
W
,
σ
2
)
p(x_n|t_n,W,\sigma^2)
p(xn∣tn,W,σ2)):
M
M
M步是对上述
W
,
σ
W,\sigma
W,σ求极大值,注意
<
⋅
>
<\cdot>
<⋅>里面的
M
,
σ
M, \sigma
M,σ是已知的(实际上,用
M
′
,
σ
′
M', \sigma'
M′,σ′来表述更加合适):
有更加简练的表述形式:
符号虽然多,但是推导并不麻烦,自己推导的时候并没有花多大工夫。
附录
极大似然估计
已知对数似然函数为:
先考察对
W
W
W的微分:
d
L
=
−
N
2
{
d
∣
C
∣
∣
C
∣
+
d
t
r
(
C
−
1
S
)
}
\begin{array}{ll} \mathrm{d}L = -\frac{N}{2}\{\frac{\mathrm{d}|C|}{|C|} + \mathrm{dtr}(C^{-1}S)\} \end{array}
dL=−2N{∣C∣d∣C∣+dtr(C−1S)}
d
∣
C
∣
∣
C
∣
=
t
r
(
C
−
1
d
C
)
=
t
r
[
C
−
1
(
d
W
W
T
+
W
d
W
T
)
]
=
2
t
r
[
W
T
C
−
1
d
W
]
\begin{array}{ll} \frac{\mathrm{d}|C|}{|C|} &= \mathrm{tr}(C^{-1}\mathrm{d}C) \\ &= \mathrm{tr}[C^{-1}(\mathrm{d}WW^T+W\mathrm{d}W^T)] \\ &= 2\mathrm{tr}[W^TC^{-1}\mathrm{d}W] \\ \end{array}
∣C∣d∣C∣=tr(C−1dC)=tr[C−1(dWWT+WdWT)]=2tr[WTC−1dW]
d
t
r
(
C
−
1
S
)
=
t
r
(
d
C
−
1
S
)
=
−
t
r
(
C
−
1
[
d
C
]
C
−
1
S
)
=
−
t
r
(
C
−
1
S
C
−
1
d
C
)
=
−
2
t
r
(
W
T
C
−
1
S
C
−
1
d
W
)
\begin{array}{ll} \mathrm{dtr}(C^{-1}S) &= \mathrm{tr}(\mathrm{d}C^{-1}S) \\ &= -\mathrm{tr}(C^{-1}[\mathrm{d}C]C^{-1}S) \\ &= -\mathrm{tr}(C^{-1}SC^{-1}\mathrm{d}C) \\ &= -2\mathrm{tr}(W^TC^{-1}SC^{-1}\mathrm{d}W) \\ \end{array}
dtr(C−1S)=tr(dC−1S)=−tr(C−1[dC]C−1S)=−tr(C−1SC−1dC)=−2tr(WTC−1SC−1dW)
所以,要想取得极值,需满足:
C
−
1
W
=
C
−
1
S
C
−
1
W
⇒
S
C
−
1
W
=
W
C^{-1}W = C^{-1}SC^{-1}W \\ \Rightarrow \quad SC^{-1}W=W
C−1W=C−1SC−1W⇒SC−1W=W
论文说这个方程有三种解:
-
W = 0 W=0 W=0,0解,此时对数似然函数取得最小值(虽然我没看出来)。
-
C = S C=S C=S:
W W T + σ 2 I = S ⇒ W W T = S − σ 2 WW^T + \sigma^2 I = S \\ \Rightarrow WW^T = S-\sigma^2 WWT+σ2I=S⇒WWT=S−σ2
其解为:
W = U S ( Λ S − σ 2 I ) 1 / 2 R W = U_{S} (\Lambda_S-\sigma^2I)^{1/2}R W=US(ΛS−σ2I)1/2R
其中 S = U S Λ U S T S = U_S \Lambda U_S^T S=USΛUST。 -
第三种,也是最有趣的解, S C − 1 W = W SC^{-1}W=W SC−1W=W但是 W ≠ 0 , C ≠ S W \ne 0, C \ne S W̸=0,C̸=S。假设 W = U L V T W=ULV^T W=ULVT,其中 U ∈ R d × q U \in \mathbb{R}^{d \times q} U∈Rd×q, L ∈ R q × q L \in \mathbb{R}^{q \times q} L∈Rq×q为对角矩阵, V ∈ R q × q V \in \mathbb{R}^{q \times q} V∈Rq×q。通过一系列的变换(我没有把握能完成这部分证明,感觉好像是对的),可以得到:
S U L = U ( σ 2 L + L 2 ) L SUL = U(\sigma^2L+L^2)L SUL=U(σ2L+L2)L
于是 S u j = ( σ 2 I + l j 2 ) u j Su_j = (\sigma^2I + l_j^2)u_j Suj=(σ2I+lj2)uj,其中 u j u_j uj为 U U U的第j列, l j l_j lj为 L L L的第j个对角线元素。因此, u j u_j uj就成了 S S S的对应特征值 λ j = σ 2 + l j 2 \lambda_j = \sigma^2 + l_j^2 λj=σ2+lj2的特征向量(注意到这个特征值是必须大于等于 σ 2 \sigma^2 σ2)。于是,有:
W = U q ( K q − σ 2 I ) 1 / 2 R W = U_q(K_q-\sigma^2I)^{1/2}R W=Uq(Kq−σ2I)1/2R
其中:
k j = { λ j 对 应 特 征 值 u j σ 2 k_j = \left \{ \begin{array}{ll} \lambda_j & 对应特征值u_j \\ \sigma^2 \end{array} \right . kj={λjσ2对应特征值uj
实际上就是 k j = λ j k_j=\lambda_j kj=λj
注意,上面的分析只能说明其为驻定解,事实上 U q U_q Uq只说明了其为 S S S的特征向量,而没有限定是哪些特征向量。
将解
W
=
U
q
(
K
q
−
σ
2
I
)
1
/
2
R
W = U_q(K_q-\sigma^2I)^{1/2}R
W=Uq(Kq−σ2I)1/2R代入对数似然函数可得(
C
=
W
W
T
+
σ
2
I
C = WW^T+\sigma^2 I
C=WWT+σ2I):
其中
q
′
q'
q′是非零
l
1
,
…
,
l
q
′
l_1,\ldots,l_{q'}
l1,…,lq′的个数。
上面的是蛮好证明的,注意
{
⋅
}
\{\cdot\}
{⋅}中第2项和第4项和为
ln
∣
C
∣
\ln |C|
ln∣C∣,第3,5项构成
t
r
(
C
−
1
S
)
\mathrm{tr}(C^{-1}S)
tr(C−1S)。
对
σ
\sigma
σ求极值,可得:
且是极大值,因为显然
σ
→
0
\sigma \rightarrow 0
σ→0会导致
L
→
−
∞
L \rightarrow - \infty
L→−∞。代入原式可得:
最大化上式等价于最小化下式:
注意到,上式只与被舍弃的
l
j
=
0
l_j=0
lj=0的
λ
j
\lambda_j
λj有关,又
λ
i
≥
σ
2
,
i
=
1
,
…
,
q
\lambda_i \ge \sigma^2, i=1,\ldots, q
λi≥σ2,i=1,…,q,再结合(18),可以知道最小的特征值一定是被舍弃的。但是论文说,应当是最小的
d
−
q
′
d-q'
d−q′个特征值作为被舍弃的(因为这些特征值必须在一块?)。
仔细想来,似然函数可以写成:
L
=
−
N
2
{
d
ln
(
2
π
)
+
∑
j
=
1
q
ln
(
λ
j
)
+
1
σ
2
∑
j
=
q
+
1
d
λ
j
+
(
d
−
q
)
ln
(
σ
2
)
+
q
}
L = -\frac{N}{2} \{d \ln (2\pi) + \sum \limits_{j=1}^q \ln (\lambda_j) + \frac{1}{\sigma^2}\sum \limits_{j=q+1}^d \lambda_j + (d-q)\ln (\sigma^2) + q\}
L=−2N{dln(2π)+j=1∑qln(λj)+σ21j=q+1∑dλj+(d−q)ln(σ2)+q}
好吧,还是不知道该如何证明。
代码
"""
瞎写的,测试结果很诡异啊
"""
import numpy as np
class PPCA:
def __init__(self, data, q):
self.__data = np.array(data, dtype=float)
self.__n, self.__p = data.shape
self.__mean = np.mean(self.data, 0)
self.q = q
assert q < self.__p, "Invalid q"
@property
def data(self):
return self.__data
@property
def n(self):
return self.__n
@property
def p(self):
return self.__p
def explicit(self):
data = self.data - self.__mean
S = data.T @ data / self.n
value, vector = np.linalg.eig(S)
U = vector[:, :self.q]
sigma = np.mean(value[self.q:])
newvalue = value[:self.q] - sigma
return U * newvalue
def EM(self):
data = self.data - self.__mean
S = data.T @ data / self.n
W_old = np.random.randn(self.p, self.q)
sigma = np.random.randn()
count = 0
while True:
count += 1
M = W_old.T @ W_old + sigma
M_inv = np.linalg.inv(M)
W_new = S @ W_old @ np.linalg.inv(sigma + M_inv @ W_old.T @ S @ W_old)
sigma_new = np.trace(S - S @ W_old @ M_inv @ W_new.T) / self.p
if np.sum(np.abs(W_new - W_old)) / np.sum(np.abs(W_old)) < 1e-13 and \
np.abs(sigma_new - sigma) < 1e-13:
return W_new
else:
W_old = W_new
sigma = sigma_new