前言
最近实现了一个简单的pca+svm
模型, 同时参考了一些关于pca
和svm
的比较优秀的博客介绍,为了加深自己的理解,记录下来自己的学习历程。
pca
算法介绍
通过阅读优秀的博客 PCA介绍, 自己对主成分分析算法有了较为深刻的理解。大家也可以去看下,内容写的比较详细。
PCA
全称是 Principal Component Analysis
, 该算法的作用是对高维的向量数据进行降维,例如对于
m
×
n
m \times n
m×n 的矩阵
x
\mathbf{x}
x, 该矩阵含有
n
n
n 个
m
m
m 维的列向量,那么通过主成分分析,我们可以将每个列向量用更为简洁的方式去表示,即用
k
k
k 维的列向量去表示,其中
k
<
m
k < m
k<m, 同时尽可能保留之前的数据信息。
降维前的矩阵
(
x
11
x
12
x
13
⋯
x
1
n
x
21
x
22
x
23
⋯
x
2
n
⋮
⋮
⋮
⋱
x
m
1
x
m
2
x
m
3
⋯
x
m
n
)
\left( \begin{matrix} x_{11} & x_{12} & x_{13} & \cdots & x_{1n} \\ x_{21} & x_{22} & x_{23} & \cdots & x_{2n} \\ \vdots & \vdots & \vdots & \ddots \\ x_{m1} & x_{m2} & x_{m3} & \cdots & x_{mn} \end{matrix} \right)
⎝⎜⎜⎜⎛x11x21⋮xm1x12x22⋮xm2x13x23⋮xm3⋯⋯⋱⋯x1nx2nxmn⎠⎟⎟⎟⎞
降维后的矩阵
(
x
11
x
12
x
13
⋯
x
1
n
x
21
x
22
x
23
⋯
x
2
n
⋮
⋮
⋮
⋱
x
k
1
x
k
2
x
k
3
⋯
x
k
n
)
\left( \begin{matrix} x_{11} & x_{12} & x_{13} & \cdots & x_{1n} \\ x_{21} & x_{22} & x_{23} & \cdots & x_{2n} \\ \vdots & \vdots & \vdots & \ddots \\ x_{k1} & x_{k2} & x_{k3} & \cdots & x_{kn} \end{matrix}\right)
⎝⎜⎜⎜⎛x11x21⋮xk1x12x22⋮xk2x13x23⋮xk3⋯⋯⋱⋯x1nx2nxkn⎠⎟⎟⎟⎞
向量表示与基变换
内积
内积的概念:两个向量的点乘运算结果.
对于给定的两个向量
A
,
B
A, B
A,B, 其内积计算为:
(
A
,
B
)
=
(
a
1
,
a
2
,
⋯
,
a
n
)
T
⋅
(
b
1
,
b
2
,
⋯
,
b
n
)
=
a
1
b
1
+
a
2
b
2
+
⋯
+
a
n
b
n
(A, B) = (a_1,a_2, \cdots, a_n)^{T} \cdot (b_1, b_2, \cdots, b_n)=a_1b_1+a_2b_2+\cdots+a_nb_n
(A,B)=(a1,a2,⋯,an)T⋅(b1,b2,⋯,bn)=a1b1+a2b2+⋯+anbn内积的几何意义:向量
A
A
A 在向量
B
B
B 上的投影与向量
B
B
B 的模的乘积。推导过程可以参考博客, 那么我们就不难知道一个向量与单位向量的内积就是该向量在单位向量上的投影
向量空间的基
向量空间的基是一组可以线性表示空间中全部向量的向量集合,在二维的笛卡尔平面直角坐标系中, ( 0 , 1 ) , ( 1 , 0 ) (0,1), (1,0) (0,1),(1,0) 可以作为基,在该坐标系中的每个点 ( x , y ) (x, y) (x,y)都可以用 x ⋅ ( 1 , 0 ) + y ⋅ ( 0 , 1 ) x \cdot(1, 0) + y \cdot (0, 1) x⋅(1,0)+y⋅(0,1) 表示,之所以通常选择 ( 1 , 0 ) (1,0) (1,0) 和 ( 0 , 1 ) (0,1) (0,1) 为基,是因为它们分别是 x x x 和 y y y 轴正方向上的单位向量,因此就使得二维平面上点坐标和向量一一对应,非常方便。例如我们可以选择 ( 1 2 , 1 2 ) (\frac{1}{\sqrt{2}}, \frac{1}{\sqrt{2}}) (21,21)和 ( − 1 2 , 1 2 ) (\frac{-1}{\sqrt{2}}, \frac{1}{\sqrt{2}}) (2−1,21)作为二维坐标平面的一组基,根据内积的几何意义,我们可以得到在原始基下坐标为 ( 1 , 3 ) (1, 3) (1,3) 的新的坐标表示为 ( 4 2 , 2 2 ) (\frac{4}{\sqrt{2}}, \frac{2}{\sqrt{2}}) (24,22)。示意图如下:
基变换
前面的基变换过程可以表示矩阵相乘的形式:
( 1 2 1 2 − 1 2 1 2 ) ( 1 3 ) = ( 4 2 2 2 ) \left( \begin{matrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ -\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ \end{matrix} \right) \left( \begin{matrix} 1 \\ 3 \end{matrix} \right)= \left( \begin{matrix} \frac{4}{\sqrt{2}}\\ \frac{2}{\sqrt{2}} \end{matrix} \right) (21−212121)(13)=(2422)
观察我们可以总结如下:原向量空间一组基下的坐标向量和由新的基组成的矩阵相乘可以得到新的基下的坐标向量,其中新的基组合中每个基向量都是矩阵的行向量,推而广之,我们可以多个原向量空间一组基下的坐标向量分别作为列向量构成一个矩阵与由新的基向量组成的矩阵相乘得到对应的新的坐标向量表示。
下式表示的是通过新的向量空间基表示的矩阵 V = ( v 1 T ; v 2 T ; ⋯ v k T ; ) V = (\mathbf{v_1}^{T};\mathbf{v_2}^{T}; \cdots \mathbf{v_k}^{T};) V=(v1T;v2T;⋯vkT;)与 4 个原空间向量基下(示例中只有 x , y , z x, y, z x,y,z三维)的坐标向量相乘得到新的 k k k维的坐标向量。
一般的如果
k
=
3
k=3
k=3,那么变换前后的维度没有变化,数据信息也没有什么损失,但是如果
k
k
k是一个小于原先维度3的非零整数,那么就会出现数据信息损失的情况,PCA
算法的本质思想就是要找到一个合适的矩阵将原先的数据映射到新的空间向量基下的向量表示,合适的评估标准就是尽可能做到使得前后数据损失小。
(
v
11
v
12
v
13
v
21
v
22
v
23
⋮
⋮
⋮
v
k
1
v
k
2
v
k
3
)
(
x
1
x
2
x
3
x
4
y
1
y
2
y
3
y
4
z
1
z
2
z
3
z
4
)
=
(
u
1
1
u
2
1
u
3
1
u
4
1
u
1
2
u
2
2
u
3
2
u
4
2
⋮
⋮
⋮
⋮
u
1
k
u
2
k
u
3
k
u
4
k
)
\left( \begin{matrix} v_{11} & v_{12} & v_{13} \\ v_{21} & v_{22} & v_{23} \\ \vdots & \vdots & \vdots \\ v_{k1} & v_{k2} & v_{k3} \\ \end{matrix} \right) \left( \begin{matrix} x_1 & x_2 & x_3 & x_4\\ y_1 & y_2 & y_3 & y_4\\ z_1 & z_2 & z_3 & z_4\\ \end{matrix} \right)= \left( \begin{matrix} u^{1}_{1} & u^{1}_{2} & u^{1}_{3} & u^{1}_{4} \\ u^{2}_{1} & u^{2}_{2} & u^{2}_{3} & u^{2}_{4} \\ \vdots & \vdots & \vdots & \vdots \\ u^{k}_{1} & u^{k}_{2} & u^{k}_{3} & u^{k}_{4} \\ \end{matrix} \right)
⎝⎜⎜⎜⎛v11v21⋮vk1v12v22⋮vk2v13v23⋮vk3⎠⎟⎟⎟⎞⎝⎛x1y1z1x2y2z2x3y3z3x4y4z4⎠⎞=⎝⎜⎜⎜⎛u11u12⋮u1ku21u22⋮u2ku31u32⋮u3ku41u42⋮u4k⎠⎟⎟⎟⎞
PCA 算法数学推导
前面我们已经知道PCA
算法的关键是要找到一个矩阵使得变换后的数据能够尽量保留原始的信息。先从最简单的例子思考这个问题,对于一个二维平面上的数据点,如果我们要降到一维,那么直观上我们会选择一条直线,使得二维空间上的点能够在这条直线上的投影尽可能分散,因为如果如果都集中到直线的一小段范围内,显然数据之间的区分就不太明显了,也即原始数据信息受到了一定的损失。
上面的问题可以转化为一个数学问题:寻找一组基,使得数据变换后,方差值最大。
过程如下:
- 首先是中心化处理,也就是将数据的每个维度上均值为0,例如有4个向量,那么这4个向量的第一个维度上的元素均值为0,其它维度也一样。
- 计算协方差。对于从二维降到一维上的问题比较简单,我们只需要找到一个方向使得投影在该方向上的数据方差最大。但是如果是更高维的话,我们需要找到多个这样的方向。根绝方差最大我们可以先确定第一个方向,那么第二个方向也按照方差最大的思路去找,显然可能会出现和第一个方向相同的情况,那么这两个方向显然就表示了重复表示的信息,而不符合尽量表示更多数据信息的目的,因此我们希望要找的方向能够和之前的方向都正交,用协方差解释的话就是对于方向1投影得到的数据变量
X
X
X 和 方向2上投影得到的数据变量
Y
Y
Y 的协方差为0.由于之前每个维度已经中心化处理,那么协方差计算可以表示为
C o v ( X , Y ) = 1 n ∑ i = 1 n x i y i Cov(X, Y)=\frac{1}{n} \sum ^{n} _{i=1} {x_iy_i} Cov(X,Y)=n1i=1∑nxiyi - 那么原来降维问题的优化目标可以总结为:将一组 m m m维向量降为 k k k维,其目标是选择 k k k个(模为1)正交基,使得原始数据变换到这组基上后,每两维度间协方差为0,而维度上的方差则尽可能大(在正交的约束下,取最大的 k k k个方差)。
现在我们的思路就更加明确了,但是还没有得到一个可行的方法。
上面提到了一个重要的协方差的概念,对于三维空间上的多个向量按照列组成的矩阵 X X X, 我们可以由下式得到任意两个维度上的协方差:
1
n
X
X
T
=
(
x
1
x
2
x
3
⋯
x
n
y
1
y
2
y
3
⋯
y
n
z
1
z
2
z
3
⋯
z
n
)
(
x
1
y
1
z
1
x
2
y
2
z
2
x
3
y
3
z
3
⋮
⋮
⋮
x
n
y
n
z
n
)
=
(
1
n
∑
i
=
1
n
x
i
2
1
n
∑
i
=
1
n
x
i
y
i
1
n
∑
i
=
1
n
x
i
z
i
1
n
∑
i
=
1
n
y
i
x
i
1
n
∑
i
=
1
n
y
i
2
1
n
∑
i
=
1
n
y
i
z
i
1
n
∑
i
=
1
n
z
i
x
i
1
n
∑
i
=
1
n
z
i
y
i
1
n
∑
i
=
1
n
z
i
2
)
\frac{1}{n}XX^T= \left( \begin{matrix} x_1 & x_2 & x_3 & \cdots & x_n\\ y_1 & y_2 & y_3 & \cdots & y_n\\ z_1 & z_2 & z_3 & \cdots & z_n\\ \end{matrix} \right) \left( \begin{matrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \\ \vdots & \vdots & \vdots \\ x_n & y_n & z_n \end{matrix} \right)= \left( \begin{matrix} \frac{1}{n}\sum^{n} _{i=1} {x_i}^{2} & \frac{1}{n}\sum^{n} _{i=1} {x_i y_i} & \frac{1}{n}\sum^{n} _{i=1} {x_i z_i} \\ \frac{1}{n}\sum^{n} _{i=1} {y_i}{x_i} & \frac{1}{n}\sum^{n} _{i=1} {y_i}^{2} & \frac{1}{n}\sum^{n} _{i=1} {y_i z_i} \\ \frac{1}{n}\sum^{n} _{i=1} {z_i}{x_i} & \frac{1}{n}\sum^{n} _{i=1} {z_i y_i} & \frac{1}{n}\sum^{n} _{i=1} {z_i}^{2} \\ \end{matrix} \right)
n1XXT=⎝⎛x1y1z1x2y2z2x3y3z3⋯⋯⋯xnynzn⎠⎞⎝⎜⎜⎜⎜⎜⎛x1x2x3⋮xny1y2y3⋮ynz1z2z3⋮zn⎠⎟⎟⎟⎟⎟⎞=⎝⎛n1∑i=1nxi2n1∑i=1nyixin1∑i=1nzixin1∑i=1nxiyin1∑i=1nyi2n1∑i=1nziyin1∑i=1nxizin1∑i=1nyizin1∑i=1nzi2⎠⎞
注意这里的每个维度已经中心化处理, 得到的矩阵是一个对角矩阵,且对角线上的元素是每个维度的方差,非对角线的上的元素是维度之间的协方差。那么我们的优化目标就更进一步明确为:将变换后的数据构成的矩阵经过上面的计算过程后能够对角化,即除了对角线上的元素都为0,且对角线上的元素按照从大到小进行排列。但是这样还是不太可行,因为我们总不能一个一个试来得到空间向量基。
重要的一点来了:原协方差矩阵和基变换后的协方差矩阵存在密切的关系。
有什么关系呢?
假设原始数据矩阵为 X X X, 基变换后的矩阵 Y = U X Y=UX Y=UX,这里的 U U U 就是我们要求的新的空间向量基,那么基变换后的协方差矩阵
1
n
Y
Y
T
=
1
n
(
U
X
)
(
U
X
)
T
=
1
n
(
U
X
)
(
X
T
U
T
)
=
U
(
1
n
X
X
T
)
U
T
\frac{1}{n}YY^T= \frac{1}{n}(UX)(UX)^{T}=\frac{1}{n}(UX)(X^TU^T)=U(\frac{1}{n}XX^T)U^T
n1YYT=n1(UX)(UX)T=n1(UX)(XTUT)=U(n1XXT)UT
可见我们要得到的使得基变换后协方差矩阵对角化的空间向量基
U
U
U 也是能够将原来的协方差矩阵对角化的矩阵。
即:
U
−
1
X
X
T
U
=
Λ
=
(
λ
1
⋱
λ
m
)
U^{-1}{XX^T}U=\Lambda= \left( \begin{matrix} \lambda_1 & & \\ & \ddots & \\ & & \lambda_m \end{matrix} \right)
U−1XXTU=Λ=⎝⎛λ1⋱λm⎠⎞
(
λ
1
,
λ
2
,
⋯
,
λ
m
)
\left(\lambda_1, \lambda_2, \cdots,\lambda_m \right)
(λ1,λ2,⋯,λm)是协方差矩阵的特征值,分别对应
m
m
m 个正交的单位向量。
实对称矩阵有三个性质:
- 实对称矩阵的特征值都是实数
- 实对称矩阵不同特征值对应的特征向量必定正交,对于一般矩阵只能保证线性无关
- 实对称矩阵的多重( k k k)特征值对应的线性无关的特征向量也恰好有 k k k个。
基于以上我们可以很容易的根据已有的原数据协方差矩阵求出其特征向量,并取前几个特征值较大的特征向量组成变换基,进而可以进行降维。
基于sklearn
库的pca
实现
pca
算法已经很好的封装在sklearn
库里了,直接调用相关的函数就可以实现。
from sklearn.decomposition import PCA
: 从sklearn中导入PCA类
PCA
类介绍
PCA(n_components=None, *, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None
n_components
: 可以取大于0的正整数, 此时表示降低到多少维度,也可以取小数,此时将自动选取维度数,使得该维度下方差能够高于指定比例。
copy
: 如果为 False
,则数据在训练过程中会被改变,此时使用fit(x).transform(x)
将不会应得的结果,而应该使用fit_transform
,如果True
,则训练过程是在数据副本上进行的,原始数据不会改变。
其它参数还未涉及,待补
pca
方法属性的一些说明
fit(x)
:使用数据 x
训练PCA
模型,并返回训练好的PCA
对象。
其中 x.shape()=(n_samples, n_features)
fit_transform(x)
:训练PCA
模型,并应用到数据
x
x
x 上。
transform(x)
:将训练好的模型应用到数据
x
x
x 上。