1. 简介
主成分分析是指将数据中相关性很高的属性/变量转化成彼此相互独立或不相关的新属性/变量,利用较少的新属性/变量(主成分)去解释原来数据中的大部分属性/变量的一种降维方法。
2. 原理
2.1 基础思想
以学校课程为例,用 x1,x2,⋯,xp 表示 p 门课程的成绩变量, c1,c2,⋯,cp 表示各门课程的权重,则成绩的加权和为
s=c1x1+c2x2+⋯+cpxp
现在希望能够选择合适的权重来更好的区分学生的成绩 s1,s2,⋯,sn( n 为学生人数且 n>p)。一般来说,如果这些值很分散,则表明区分的好。故需要寻找这样的加权,使得 s1,s2,⋯,sn 能够尽可能的分散。
而数据的分散程度可以利用方差的大小来体现,设 X1,X2,⋯,Xp 表示以 x1,x2,⋯,xp 为样本观测值的随机变量,规定(否则权值可以无穷大而失去意义) c12+c22+⋯+cp2=1 。在此约束下,若能找到 c1,c2,⋯,cp 使得 Var(c1X1+c2X2+⋯+cpXp) 的值达到最大,则表明此时学生的成绩区分达到最好。
可见,以上问题本质为一个求最优解的优化问题:
c12+c22+⋯+cp2=1max Var(c1X1+c2X2+⋯+cpXp)
求出的最优解 c1,c2,⋯,cp 是一个单位向量,代表一个主成分方向,对应的主成分为 Z=c1X1+c2X2+⋯+cpXp 。
一个主成分不足以代表原来的 p 个变量,故需要寻找第二、三、··· 个主成分。且后面的主成分不应该再包含前面已经求出来的主成分的信息,统计上理解就是主成分间两两之间的协方差为零,几何上理解就是主成分间两两正交。
设 Zi 表示第 i 个主成分,i=1,2,⋯,p,则
Z1=c11X1+c12X2+⋯+c1pXpZ2=c21X1+c22X2+⋯+c2pXp⋮Zp=cp1X1+cp2X2+⋯+cppXp
其中,对于每一个 i,均有 ci12+ci22+⋯+cip2=1。且 (c11,c12,⋯,c1p) 使得 Var(Z1) 的值达到最大;(c21,c22,⋯,c2p) 不仅垂直于 (c11,c12,⋯,c1p),而且使得 Var(Z2) 的值达到最大;(c31,c32,⋯,c3p) 不仅垂直于 (c11,c12,⋯,c1p)和(c21,c22,⋯,c2p),而且使 Var(Z3) 的值达到最大;以此类推得到全部 p 个主成分。
【注意事项】
- 主成分分析的结果受量纲的影响,故实际应用中先将各变量的数据标准化,然后使用协方差矩阵或相关系数矩阵进行分析。
- 使用相关系数矩阵求主成分时,Kaiser 主张将特征值小于 1 的主成分予以放弃(这也是 SPSS 软件的默认值)
- 在实际研究中,由于主成分的目的是为了降维,减少变量个数,故一般选取少量的主成分(不超过 5 或 6 个),只要这些主成分的累计贡献率(定义见下文)能够达到 70%~80% 就行了。
设 p 个变量 X1,X2,⋯,Xp 在第 i 次试验中的取值为 xi1,xi2,⋯,xip(i=1,2,⋯,n),则原数据写成矩阵形式为
X=⎝⎜⎜⎜⎜⎛x11x21⋮xn1x12x22⋮xn2⋯⋯⋱⋯x1px2p⋮xnp⎠⎟⎟⎟⎟⎞
为了保证主成分分析不受量纲的影响,将 X 进行标准化变换
xij~=(xij−xjˉ)/sj
其中,xjˉ、sj 分别为 X 的第 j 列的均值和标准差。
变换后的数据矩阵为
X~=⎝⎜⎜⎜⎜⎛x11~x21~⋮xn1~x12~x22~⋮xn2~⋯⋯⋱⋯x1p~x2p~⋮xnp~⎠⎟⎟⎟⎟⎞
2.2 确定主成分变量
对于自变量的任意一个线性组合 :
z=c1x1~+c2x2~+⋯+cpxp~,∑j=1pcj2=1
其在第 i 次试验中的取值为
zi=c1xi1~+c2xi2~+⋯+cpxip~ (i=1,2,⋯,n)
由于 X~ 已经标准化了,因此
zˉ=n1∑i=1nzi=n1∑i=1n∑j=1pcjxij~=n1∑j=1pcj∑i=1nxij~=0
记 w=(c1,c2,⋯,cp)T,则
M∗=Var(z)=n1∑i=1n(zi−zˉ)2=n1∑i=1nzi2=n1(X~w)T(X~w)
对于新变量 z 来说,如果在 n 次试验下它的取值变化不大,即 z 的 M∗ 较小,则这个新变量 z 可以去掉。反之,如果 z 的 M∗ 较大,则说明该新变量 z 的作用比较明显。因此,我们希望所选择的 ci (i=1,2,⋯,p) 能使 M∗ 达到最大,即使得新变量 z 有较大作用。
如果 XTX 的特征值 λ1≥λ2≥⋯≥λp,它们对应的标准化正交特征向量为 η1,η2,⋯,ηp,则 M∗=(Xw)T(Xw)/n 的最大值在 w=η1 时达到,且最大值为 λ1/n 。此时新变量 z 为
z=x~Tη1
其中 x~=(x1~,x2~,⋯,xp~)。
常记 Z1=x~Tη1 ,并称 Z1 为变量的第一主成分。
一般的,如果已经确定了 k 个主成分:
Zi=x~Tηi (i=1,2,⋯,k)
则第 k+1 个主成分 Zk+1=x~Tw 可由以下两个条件决定:
- wTηi=0, i=1,2,⋯,k, wTw=1;
- 在以上条件下,使得 M∗ 达到最大。
由二次型的条件极值可知,第 k+1 个主成分就是 Zk+1=x~Tηk+1 (i=1,2,⋯,p) 。如此总共可以取到 p 个主成分 Zi=x~Tηi (i=1,2,⋯,p) 。
2.3 选择主成分变量
确定了 p 个主成分后,将标准化后的数据 x1~,x2~,⋯,xp~ 转换成主成分 z1,z2,⋯,zp,令
Z=X~(η1,η2,⋯,ηp)=⎝⎜⎜⎜⎜⎛z11z21⋮zn1z12z22⋮zn2⋯⋯⋱⋯z1pz2p⋮znp⎠⎟⎟⎟⎟⎞
记 Q=(η1,η2,⋯,ηp)p×p,Q 为标准正交阵,且 Z=XQ,则
ZTZ=QTXTXQ=QT(XTX)Q=⎝⎛λ10⋱0λp⎠⎞
由上式可知,XTX 的特征值 λi 度量了第 i 个主成分 zi 在第 n 试验中取值变化的大小。如果 λi≈0,则说明该主成分 zi 在 n 次实验中的取值变化很小,可以选择剔除该主成分。
【筛选方法】
- 首先将 XTX 的特征值按由大到小的次序排序。
- 然后剔除这些特征值 λr+1,λr+2,⋯,λp对应的主成分,这些特征值满足
∑i=r+1pλi<15%∑i=1pλi
即筛选留下的主成分对应的特征值之和所占比重(定义为累计贡献率)要超过 85%。
- 单纯考虑累计贡献率有时是不够的,还需考虑选择的主成分对原始变量的贡献值,定义贡献值为相关系数的平方和。如果选择的主成分为 z1,z2,⋯,zp ,则它们对原始变量 xi~ 的贡献值为
ρi=∑j=1rr2(zj,xi)
这里 r(zj,xi) 表示 zj 与 xi 的相关系数。
3. 步骤
假设进行主成分分析的指标变量有 m 个:x1,x2,⋯,xm;共有 n 个评价对象,第 i 个评价对象的第 j 个指标的取值为 aij,评价矩阵为
A=(aij)n×m
3.1 对原始数据进行标准化
将各指标值转换成标准指标 aij~ :
aij~=sjaij−μj (i=1,2,⋯,n; j=1,2,⋯,m)
其中
μj=n1∑i=1naijsj=n−11∑i=1n(aij−μj)2j=1,2,⋯,m
即 μj,sj 为第 j 个指标的标准均值和样本标准差。对应地,称
xi~=sixi−μi (i=1,2,⋯,m)
为标准化指标变量。标准化后的评价矩阵为
A~=(aij~)n×m
3.2 计算相关系数矩阵 R
相关系数矩阵 R=(rij)m×m,其中
rij=n−1∑k=1naki~⋅akj~ (i,j=1,2,⋯,m)
易知式中 rii=1,rij=rji,rij 是第 i 个指标与第 j 个指标的相关系数。
3.3 计算特征值和特征向量
计算相关系数矩阵 R 的特征值 λ1≥λ2≥⋯≥λm≥0,及对应的特征向量 μ1,μ2,⋯,μm,其中 μj=(μ1j,μ2j,⋯,μmj)T,由特征向量组成 m 个新的指标变量
y1=μ11x1~+μ21x2~+⋯+μm1xm~y2=μ12x1~+μ22x2~+⋯+μm2xm~⋮ym=μ1mx1~+μ2mx2~+⋯+μmmxm~
其中 yi 表示第 i 主成分。即
Y=X~Tμ
其中,X~=((~x1),x2~,⋯,xm~)T,Y=(y1,y2,⋯,ym)T,μ=(μ1,μ2,⋯,μm) 。
标准化后的评价矩阵 A~ 转化为新评价矩阵 B~:
B~=A~μ
3.4 选择 p (p≤m) 个主成分
计算特征值 λj (j=1,2,⋯,m) 的信息贡献率和累计贡献率。称
bj=∑k=1mλkλj (j=1,2,⋯,m)
为主成分 yj 的信息贡献率;称
αp=∑k=1mλk∑k=1pλk
为主成分 y1,y2,⋯,yp 的累计贡献率,当 αp 接近1(αp=0.85/0.90/0.95)时,选择前 p 个指标变量 y1,y2,⋯,yp 作为 p 个主成分,代替原来的 m 个指标变量。选择该 p 个主成分后,新评价矩阵 C~ 为:
C~=B~(n×p)
3.5 计算综合评价值
定义综合得分为
z=∑j=1pbjyj
其中 bj 为第 j 个主成分的信息贡献;则 n 个评价对象的综合评价值向量为
Z=C~b
其中,b=(b1,b2,⋯,bp)T 。
然后便可以依据该评价值向量对这 n 个对象进行综合评价。
4. 代码实现
4.1 MatLab 代码实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| data=zscore(data);
R=corrcoef(data);
[x,y,z]=pcacov(R);
p = 5;
C = data*x; C = C(:,1:p);
Z = C*z(1:p)/100;
|
1 2 3 4 5 6 7 8 9 10 11
| data=zscore(data);
[x,C,y]=pca(data);
p = 5;
z = y/sum(y);
Z = C*z(1:p);
|