假设在 n n n维空间内有 m m m个点{ x ( 1 ) , x ( 2 ) , … … , x ( m ) x^{(1)}, x^{(2)}, ……, x^{(m)} x(1),x(2),……,x(m) }, 为了降低维度,对于每一个 n n n维向量的样本点 x ( i ) x^{(i)} x(i),我们希望找到一个对应 x ( i ) x^{(i)} x(i)的 l l l维编码向量 c ( i ) c^{(i)} c(i)。
假设编码函数为 c = f ( x ) c = f_{(x)} c=f(x),通过这个编码函数将原始的 m m m维数据降维至 l l l维。
假设解码函数为 g ( c ) = g ( f ( x ) ) ≈ x g_{(c)} = g_{(f_{(x)})}\approx x g(c)=g(f(x))≈x,通过将上一步得到的编码向量解码至 n n n维并与原始向量作比较得到误差。
用矩阵形式表示函数,则 g ( c ) = D c g_{(c)}=Dc g(c)=Dc,其中 D D D是一个 n × l n \times l n×l的矩阵。
但是我们发现,如果我们按比例缩小所有点对应的编码向量 c c c中的第 i i i个位置的元素 c i c_{i} ci,那么只要等比例放大 D : , i D_{:, i} D:,i,则解码后的结果不变,如:
假设 n = 3 , m = 4 , l = 2 n = 3, m = 4, l = 2 n=3,m=4,l=2,即样本点有4个,它们的维度为3,经过编码后,它们的维度被降低到了2维。
C 1 = [ 1 2 3 4 5 6 7 8 ] C_{1}= \left[\begin{matrix}1 & 2 & 3 & 4\\5 & 6 & 7 & 8\\\end{matrix}\right] C1=[15263748]
D 1 = [ 1 2 4 5 7 8 ] D_{1} = \left[ \begin{matrix}1 & 2\\4 & 5\\7 & 8 \end{matrix}\right] D1=⎣⎡147258⎦⎤
则通过 g ( c ) = D c g_{(c)}=Dc g(c)=Dc解码可得
g ( c ) 1 = [ 11 14 17 20 29 28 47 56 47 62 77 92 ] g_{(c)1}= \left[\begin{matrix}11 & 14 & 17 & 20\\29 & 28 & 47 & 56\\47 & 62 & 77 & 92\\\end{matrix}\right] g(c)1=⎣⎡112947142862174777205692⎦⎤
而在按0.5的比例缩小所有样本点的初始向量的第一个维度后,
C 2 = [ 0.5 1 1.5 2 5 6 7 8 ] C_{2}= \left[\begin{matrix}0.5 & 1 & 1.5 & 2\\5 & 6 & 7 & 8\\\end{matrix}\right] C2=[0.55161.5728]
此时只要将 D 1 D_{1} D1的第一列放大两倍至 D 2 D_{2} D2:
D 2 = [ 2 2 8 5 14 8 ] D_{2} = \left[ \begin{matrix}2 & 2\\8 & 5\\14 & 8 \end{matrix}\right] D2=⎣⎡2814258⎦⎤
即可得:
g ( c ) 2 = [ 11 14 17 20 29 28 47 56 47 62 77 92 ] = g ( c ) 1 g_{(c)2}= \left[\begin{matrix}11 & 14 & 17 & 20\\29 & 28 & 47 & 56\\47 & 62 & 77 & 92\\\end{matrix}\right]=g_{(c)1} g(c)2=⎣⎡112947142862174777205692⎦⎤=g(c)1
因此,每个样本点编码后的向量不唯一。
为了使问题具有唯一解,我们限制 D D D中所有列向量都有单位范数。
为了使编码问题更加简单, P C A PCA PCA限制 D D D的列向量彼此正交。
为了为每个样本点寻找一个最优编码向量 c ∗ c^{*} c∗,我们使用 L 2 L2 L2范数的平方来衡量原始向量 x x x和重构向量 g ( c ∗ ) g_{(c^{*})} g(c∗)的距离。
即对于一个样本点来说,有:
c ∗ = a r g m i n c ∣ ∣ x − g ( c ) ∣ ∣ 2 2 c^{*}=\mathop{argmin}\limits_{c}||x-g_{(c)}||_{2}^{2} c∗=cargmin∣∣x−g(c)∣∣22
= ( x − g ( c ) ) T ( x − g ( c ) ) =(x-g_{(c)})^{T}(x-g_{(c)}) =(x−g(c))T(x−g(c))
= x T x − x T g ( c ) − g ( c ) T x + g ( c ) T g ( c ) =x^{T}x-x^{T}g_{(c)}-g_{(c)}^{T}x+g_{(c)}^{T}g_{(c)} =xTx−xTg(c)−g(c)Tx+g(c)Tg(c)
由于 x T g ( c ) x^{T}g_{(c)} xTg(c)和 g ( c ) T x g_{(c)}^{T}x g(c)Tx都是标量,故二者相等。且由于第一项 x T x x^{T}x xTx不依赖于 c c c,可以忽略,所以:
c ∗ = a r g m i n c − 2 x T g ( c ) + g ( c ) T g ( c ) c^{*}=\mathop{argmin}\limits_{c}-2x^{T}g_{(c)}+g_{(c)}^{T}g_{(c)} c∗=cargmin−2xTg(c)+g(c)Tg(c)
用矩阵形式表示 g ( c ) g_{(c)} g(c)后,得到:
c ∗ = a r g m i n c − 2 x T D c + c T D T D c c^{*}=\mathop{argmin}\limits_{c}-2x^{T}Dc+c^{T}D^{T}Dc c∗=cargmin−2xTDc+cTDTDc
由于 D T D = I l D^{T}D=I_{l} DTD=Il,
c ∗ = a r g m i n c − 2 x T D c + c T c c^{*}=\mathop{argmin}\limits_{c}-2x^{T}Dc+c^{T}c c∗=cargmin−2xTDc+cTc
将 − 2 x T D c + c T D T D c -2x^{T}Dc+c^{T}D^{T}Dc −2xTDc+cTDTDc对 c c c求导得:
▽ c ( − 2 x T D c + c T c ) = 0 \bigtriangledown_{c}(-2x^{T}Dc+c^{T}c)=0 ▽c(−2xTDc+cTc)=0
− 2 D T x + 2 c = 0 -2D^{T}x+2c=0 −2DTx+2c=0
c = D T x c=D^{T}x c=DTx
故编码操作被化简为一个简单的矩阵-向量乘法操作。即:
f ( x ) = D T x f_{(x)}=D^{T}x f(x)=DTx
进一步,PCA解码操作为
r ( x ) = g ( D T x ) = D D T x r_{(x)}=g_{(D^{T}x)}=DD^{T}x r(x)=g(DTx)=DDTx
接下来,我们要挑选编码矩阵 D D D。
因为要用相同的矩阵D对所有点进行编码,我们不能再孤立地看待每个点。反之,我们必须最小化所有维数和所有点上的误差矩阵的 F r o b e n i u s Frobenius Frobenius范数,即:
D ∗ = a r g m i n D ∑ i , j ( x j ( i ) − r ( x ( i ) ) j ) 2 subject to D D T = I l D^{*}=\mathop{argmin}\limits_{D}\sqrt{\sum_{i,j}{(x_{j}^{(i)}-r(x^{(i)})_{j})^2}}\text{\quad subject to }DD^{T}=I_{l} D∗=Dargmini,j∑(xj(i)−r(x(i))j)2subject to DDT=Il
首先,我们考虑 l = 1 l=1 l=1的情况,即将 n n n维原始向量编码为1维向量。此时 D D D为一个单一向量 d d d。则问题被简化为:
d ∗ = a r g m i n d ∑ i ∣ ∣ x ( i ) − d d T x ( i ) ∣ ∣ 2 2 subject to ∣ ∣ d ∣ ∣ 2 = 1 d^{*}=\mathop{argmin}\limits_{d}\sum_{i}{||x^{(i)}-dd^{T}x^{(i)}||_{2}^2}\text{\quad subject to }||d||_{2}=1 d∗=dargmini∑∣∣x(i)−ddTx(i)∣∣22subject to ∣∣d∣∣2=1
通常,标量 d T x ( i ) d^{T}x^{(i)} dTx(i)应放在向量 d d d的左边,且考虑到标量的转置和其自身相等,上式可以写作:
d ∗ = a r g m i n d ∑ i ∣ ∣ x ( i ) − x ( i ) T d d ∣ ∣ 2 2 subject to ∣ ∣ d ∣ ∣ 2 = 1 d^{*}=\mathop{argmin}\limits_{d}\sum_{i}{||x^{(i)}-x^{(i)T}dd||_{2}^2}\text{\quad subject to }||d||_{2}=1 d∗=dargmini∑∣∣x(i)−x(i)Tdd∣∣22subject to ∣∣d∣∣2=1
此时,将表示各点的 m m m个向量上下堆叠成一个 m × n m\times n m×n的矩阵,记为 X X X,其中, X i , : = x ( i ) T X_{i, :}=x^{(i)T} Xi,:=x(i)T。所以这个问题可以被重新表述为:
d ∗ = a r g m i n d ∣ ∣ X − X d d T ∣ ∣ F 2 subject to ∣ ∣ d ∣ ∣ 2 = 1 d^{*}=\mathop{argmin}\limits_{d}||X-Xdd^{T}||_{F}^2\text{\quad subject to }||d||_{2}=1 d∗=dargmin∣∣X−XddT∣∣F2subject to ∣∣d∣∣2=1
此处由 x ( i ) − x ( i ) T d d x^{(i)}-x^{(i)T}dd x(i)−x(i)Tdd变为 X − X d d T X-Xdd^{T} X−XddT是合理的,例如, n = 3 , m = 3 n=3, m=3 n=3,m=3,设:
x ( 1 ) = [ 1 1 1 ] x ( 2 ) = [ 2 2 2 ] x ( 3 ) = [ 3 3 3 ] x^{(1)}= \left[ \begin{matrix}1 \\1 \\1 \end{matrix}\right]\; x^{(2)}= \left[ \begin{matrix}2 \\2 \\2 \end{matrix}\right]\; x^{(3)}= \left[ \begin{matrix}3 \\3 \\3 \end{matrix}\right] x(1)=⎣⎡111⎦⎤x(2)=⎣⎡222⎦⎤x(3)=⎣⎡333⎦⎤
d = [ 5 5 5 ] d= \left[ \begin{matrix}5 \\5 \\5\end{matrix}\right] d=⎣⎡555⎦⎤
则:
X = [ 1 1 1 2 2 2 3 3 3 ] X= \left[ \begin{matrix}1&1&1 \\2&2&2 \\3&3&3 \end{matrix}\right] X=⎣⎡123123123⎦⎤
x ( 1 ) − x ( 1 ) T d d = [ 1 1 1 ] − [ 1 1 1 ] [ 5 5 5 ] [ 5 5 5 ] = [ − 74 − 74 − 74 ] x^{(1)}-x^{(1)T}dd=\left[ \begin{matrix}1 \\1 \\1 \end{matrix}\right]- \left[ \begin{matrix}1 &1 &1 \end{matrix}\right] \left[ \begin{matrix}5 \\5 \\5 \end{matrix}\right] \left[ \begin{matrix}5 \\5 \\5 \end{matrix}\right]= \left[ \begin{matrix}-74 \\-74 \\-74 \end{matrix}\right] x(1)−x(1)Tdd=⎣⎡111⎦⎤−[111]⎣⎡555⎦⎤⎣⎡555⎦⎤=⎣⎡−74−74−74⎦⎤
同理可得:
x ( 2 ) − x ( 2 ) T d d = [ − 149 − 149 − 149 ] x ( 3 ) − x ( 3 ) T d d = [ − 224 − 224 − 224 ] x^{(2)}-x^{(2)T}dd=\left[ \begin{matrix}-149 \\-149 \\-149 \end{matrix}\right]\; x^{(3)}-x^{(3)T}dd=\left[ \begin{matrix}-224 \\-224 \\-224 \end{matrix}\right] x(2)−x(2)Tdd=⎣⎡−149−149−149⎦⎤x(3)−x(3)Tdd=⎣⎡−224−224−224⎦⎤
而
X − X d d T = [ 1 1 1 2 2 2 3 3 3 ] − [ 15 30 45 ] [ 5 5 5 ] = [ − 74 − 74 − 74 − 149 − 149 − 149 − 224 − 224 − 224 ] X-Xdd^{T}=\left[ \begin{matrix}1&1&1 \\2&2&2 \\3&3&3 \end{matrix}\right]- \left[ \begin{matrix}15 \\30 \\45 \end{matrix}\right] \left[ \begin{matrix}5 &5 &5 \end{matrix}\right]= \left[ \begin{matrix}-74&-74&-74 \\-149&-149&-149 \\-224&-224&-224 \end{matrix}\right] X−XddT=⎣⎡123123123⎦⎤−⎣⎡153045⎦⎤[555]=⎣⎡−74−149−224−74−149−224−74−149−224⎦⎤
故可以用 X − X d d T X-Xdd^{T} X−XddT代替 x ( i ) − x ( i ) T d d x^{(i)}-x^{(i)T}dd x(i)−x(i)Tdd。
暂时不考虑约束,此 F r o b e n i u s Frobenius Frobenius范数可做以下简化:
a r g m i n d ∣ ∣ X − X d d T ∣ ∣ F 2 \mathop{argmin}\limits_{d}||X-Xdd^{T}||_{F}^2 dargmin∣∣X−XddT∣∣F2
= a r g m i n d T r ( ( X − X d d T ) T ( X − X d d T ) ) =\mathop{argmin}\limits_{d}Tr((X-Xdd^{T})^{T}(X-Xdd^{T})) =dargminTr((X−XddT)T(X−XddT))
= a r g m i n d T r ( X T X ) − T r ( X T X d d T ) − T r ( d d T X T X ) + T r ( d d T X T X d d T ) =\mathop{argmin}\limits_{d}Tr(X^{T}X)-Tr(X^{T}Xdd^{T})-Tr(dd^{T}X^{T}X)+Tr(dd^{T}X^{T}Xdd^{T}) =dargminTr(XTX)−Tr(XTXddT)−Tr(ddTXTX)+Tr(ddTXTXddT)
= a r g m i n d − 2 T r ( X T X d d T ) + T r ( X T X d d T d d T ) =\mathop{argmin}\limits_{d}-2Tr(X^{T}Xdd^{T})+Tr(X^{T}Xdd^{T}dd^{T}) =dargmin−2Tr(XTXddT)+Tr(XTXddTddT)
这些化简利用的性质有,
1)与 d d d无关的项不影响 a r g m i n argmin argmin。
2)循环改变迹运算中相乘矩阵的顺序不影响结果。
此时,我们再来考虑约束条件
a r g m i n d − 2 T r ( X T X d d T ) + T r ( X T X d d T d d T ) subject to d T d = 1 \mathop{argmin}\limits_{d}-2Tr(X^{T}Xdd^{T})+Tr(X^{T}Xdd^{T}dd^{T})\text{\quad subject to } d^{T}d=1 dargmin−2Tr(XTXddT)+Tr(XTXddTddT)subject to dTd=1
= a r g m i n d − 2 T r ( X T X d d T ) + T r ( X T X d d T ) subject to d T d = 1 =\mathop{argmin}\limits_{d}-2Tr(X^{T}Xdd^{T})+Tr(X^{T}Xdd^{T})\text{\quad subject to } d^{T}d=1 =dargmin−2Tr(XTXddT)+Tr(XTXddT)subject to dTd=1
= a r g m i n d − T r ( X T X d d T ) subject to d T d = 1 =\mathop{argmin}\limits_{d}-Tr(X^{T}Xdd^{T})\text{\quad subject to } d^{T}d=1 =dargmin−Tr(XTXddT)subject to dTd=1
= a r g m a x d T r ( X T X d d T ) subject to d T d = 1 =\mathop{argmax}\limits_{d}Tr(X^{T}Xdd^{T})\text{\quad subject to } d^{T}d=1 =dargmaxTr(XTXddT)subject to dTd=1
= a r g m a x d T r ( d T X T X d ) subject to d T d = 1 =\mathop{argmax}\limits_{d}Tr(d^{T}X^{T}Xd)\text{\quad subject to } d^{T}d=1 =dargmaxTr(dTXTXd)subject to dTd=1
故这个优化问题可以通过特征分解来求解。具体来讲,最优的 d d d是 X T X X^{T}X XTX最大特征值对应的特征向量。
以上推导特定于 l = 1 l=1 l=1的情况,仅得到了一个主成分。更一般地,当我们需要得到主成分的基时,矩阵 D D D由前 l l l个最大的特征值对应的特征向量组成。
在求特征向量的时候,要对 X T X X^{T}X XTX经行矩阵分解操作,下面列举两种方法:
如果一个向量v是矩阵A的特征向量,将一定可以表示成下面的形式:
其中,λ是特征向量v对应的特征值,一个矩阵的一组特征向量是一组正交向量。
对于矩阵A,有一组特征向量v,将这组向量进行正交化单位化,就能得到一组正交单位向量。特征值分解,就是将矩阵A分解为如下式:
其中,Q是矩阵A的特征向量组成的矩阵, Σ \Sigma Σ则是一个对角阵,对角线上的元素就是特征值。
奇异值分解是一个能适用于任意矩阵的一种分解的方法,对于任意矩阵A总是存在一个奇异值分解:
假设A是一个 m ∗ n m*n m∗n的矩阵,那么得到的U是一个 m ∗ m m*m m∗m的方阵,U里面的正交向量被称为左奇异向量。 Σ \Sigma Σ是一个 m ∗ n m*n m∗n的矩阵, Σ \Sigma Σ除了对角线其它元素都为0,对角线上的元素称为奇异值。 V T V^T VT是 V V V的转置矩阵,是一个 n ∗ n n*n n∗n的矩阵,它里面的正交向量被称为右奇异值向量。而且一般来讲,我们会将 Σ \Sigma Σ上的值按从大到小的顺序排列。
SVD分解矩阵A的步骤:
(1) 求 A A T AA^T AAT的特征值和特征向量,用单位化的特征向量构成 U U U。
(2) 求 A T A A^TA ATA的特征值和特征向量,用单位化的特征向量构成 V V V。
(3) 将 A A T AA^T AAT或者 A T A A^TA ATA的特征值求平方根,然后构成 Σ \Sigma Σ。
用PCA给鸢尾花数据集中的四个特征进行降维操作。
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = load_iris()
y = iris.target
X = iris.data
#调用PCA
pca = PCA(n_components=2) #实例化
pca = pca.fit(X) #拟合模型
X_dr = pca.transform(X) #获取新矩阵
#要展示三种分类的分布,需要对三种鸢尾花分别绘图
colors = ['red', 'black', 'orange']
names = iris.target_names
plt.figure()
for i in [0, 1, 2]:
plt.scatter(X_dr[y == i, 0] #布尔索引切片
,X_dr[y == i, 1]
,alpha=.7 #指画出的图像的透明度
,c=colors[i]
,label=names[i]
)
plt.legend()#图例
plt.title('PCA of IRIS dataset')
plt.show()
#属性explained_variance_,查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小)
pca.explained_variance_ # 方差从大到小排列,第一个最大,依次减小
#属性explained_variance_ratio,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比
#又叫做可解释方差贡献率
pca.explained_variance_ratio_
pca = PCA(n_components, svd_solver, random_state):
n_components的可选参数:
svd_solver的可选参数:
而参数random_state在参数svd_solver的值为"arpack" or “randomized"的时候生效,可以控制这两种SVD模式中的随机模式。通常我们就选用"auto”,所以一般用不到这个参数。
PCA和SVD涉及了大量的矩阵计算,两者都是运算量很大的模型,但其实,SVD有一种惊人的数学性质,即是它可以不计算协方差矩阵,直接找出一个新特征向量组成的n维空间,而这个n维空间就是奇异值分解后的右矩阵 V T V^T VT。
右奇异矩阵 V T V^T VT有着如下性质:
k k k就是n_components,是我们降维后希望得到的维度。若X为(m,n)的特征矩阵,就是结构为(n,n)的矩阵,取这个矩阵的前k行(进行切片),即将V转换为结构为(k,n)的矩阵。而 V ( k , n ) T V_{(k,n)}^T V(k,n)T与原特征矩阵X相乘,即可得到降维后的特征矩阵X_dr。也就是说,奇异值分解可以不计算协方差矩阵等等结构复杂计算冗长的矩阵,就直接求出新特征空间和降维后的特征矩阵。
在sklearn中,矩阵 U U U和 Σ \Sigma Σ虽然会被计算出来,但完全不会被用到,也无法调取查看或者使用,因此我们可以认为, U U U和 Σ \Sigma Σ在PCA.fit()过后就被遗弃了。奇异值分解追求的仅仅是 V V V,只要有了 V V V,就可以计算出降维后的特征矩阵。在transform过程之后,fit中奇异值分解的结果除了 V ( k , n ) V(k,n) V(k,n)以外,就会被舍弃,而 V ( k , n ) V(k,n) V(k,n)会被保存在属性components_ 当中,可以调用查看:
PCA(2).fit(X).components_
可以用这个函数看最终降维得到的新的特征空间的样子,比如对人脸图像降维后,得到的特征空间应该为五官或轮廓等。
另外,使用接口inverse_transform可以将降维后的数据还原回原始数据(不会完全还原):
X_inverse = pca.inverse_transform(X_dr)
基于此,我们可以使用PCA算法对数据进行降噪处理。
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
digits = load_digits()
digits.data.shape # (1797, 64)
set(digits.target.tolist()) # 查看target有哪几个数
digits.images.shape # (1797, 8, 8)
def plot_digits(data):
#data的结构必须是(m,n),并且n要能够被分成(8,8)这样的结构
fig, axes = plt.subplots(4,10,figsize=(10,4)
,subplot_kw = {"xticks":[],"yticks":[]}
)
for i, ax in enumerate(axes.flat):
ax.imshow(data[i].reshape(8,8),cmap="binary")
plot_digits(digits.data)
rng = np.random.RandomState(42)
#在指定的数据集中,随机抽取服从正态分布的数据
#两个参数,分别是指定的数据集,和从这个数据集中抽取出来的正太分布的方差
noisy = rng.normal(digits.data,2)
plot_digits(noisy)
得到图像:
pca = PCA(0.5,svd_solver='full').fit(noisy)
X_dr = pca.transform(noisy)
X_dr.shape # (1797, 6)
without_noise = pca.inverse_transform(X_dr)
plot_digits(without_noise)