主成分分析(PCA)

主成分分析(Principal Component Analysis,PCA)是一种常见的数据降维方法,其目的是在“信息”损失较小的前提下,将高维的数据转换到低维,从而减小计算量。

首先从一张图来直观感受下:

pca

图中蓝色的点为样本点,每个样本点有二维特征,图中展示的就是将二维特征降成一维特征。图中中心的小白点是所有样本点的中心,过这个中心点为可以画出无数条直线,样本点在这条直线上的投影就是降维后的数据。那么选择这条直线的标准是什么呢?标准就是样本点在直线上的投影要尽可能地分散,对应到数学形式上就是方差最大。下面进行数学推导。

数学推导

样本\(X=[x_1, x_2,...,x_n]\),其中\(x_i \in R^p\),即每个样本是\(p\)维的。现在我们进行降维操作,通过一个矩阵变换来实现: \[y_i=Wx_i \qquad其中y_i\in R^q\] 其中 \[W=\left[\begin{matrix} \omega ^T_1 \\ \vdots \\ \omega ^T_q \end{matrix}\right] \in R^{q \times q}\] 这样一来,相当于把\(x_i\)\(p\)维数据降到\(y_i\)\(q\)维(\(q<p\)),整个问题也变成了如何得到\(W\)

如果将式子展开得到如下形式: \[\begin{aligned} Y &= WX\\ &= \left[ \begin{matrix} \omega ^T_1 \\ \omega ^T_2 \\ \vdots \\ \omega ^T_q \end{matrix} \right] \times \begin{matrix} [x_1 & x_2 & \cdots & x_n] \end{matrix} \\ &= \left[\begin{matrix} \omega ^T_1 x_1 & \omega ^T_1 x_2 & \cdots & \omega ^T_1 x_n \\ \omega ^T_2 x_1 & \omega ^T_2 x_2 & \cdots & \omega ^T_2 x_n \\ \vdots & \vdots & \ddots & \vdots \\ \omega ^T_q x_1 & \omega ^T_q x_2 & \cdots & \omega ^T_q x_n \end{matrix}\right] \\ &= \begin{matrix} [y_1 & y_2 & \cdots & y_n] \end{matrix} \end{aligned}\] 现在假设其中一个\(\omega _i\)\(\omega\),其中一个样本点\(x_i\)\(x\),注意\(\omega\)\(x\)都是\(p\)维的,那么: \[ \omega ^T x = \omega \cdot x = |\omega||x|cos\theta \] 其中可以对\(\omega\)进行缩放,我们将约束其模为1,即\(|\omega|=1(\omega ^T \omega=1)\),于是: \[ \omega ^T x = |x|cos\theta \] 即问题转化为样本点\(x\)\(\omega\)上的投影,现在要使得这些投影点的方差最大。下面介绍一些概念,然后进行推导。

样本均值: \[ \bar{x}=\frac{1}{n}\sum ^n_i x_i\] 样本投影均值: \[ \mu=\frac{1}{n}\sum ^n_i \omega ^Tx_i\] 样本\(X\)与样本\(Y\)的协方差: \[ \begin{aligned} Cov(X,Y) &= E[(X-E(X))(Y-E(Y))] \\ &= \frac{1}{n}\sum ^n_i (x_i - \bar{x})(y_i - \bar{y}) \end{aligned}\] 样本点在\(\omega\)上投影的方差: \[ \begin{aligned} \sigma ^2 &= \frac{1}{n}\sum ^n_i (\omega^T x_i - \mu)^2\\ &= \frac{1}{n}\sum ^n_i (\omega^T x_i - \frac{1}{n}\sum ^n_i \omega ^Tx_i)^2\\ &= \frac{1}{n}\sum ^n_i(\omega^T x_i - \omega^T(\frac{1}{n}\sum ^n_i x_i))^2\\ &= \frac{1}{n}\sum ^n_i(\omega^T x_i - \omega^T\bar{x})^2\\ &= \frac{1}{n}\sum ^n_i(\omega^T(x_i - \bar{x}))^2 \qquad这里\omega^T( x_i - \bar{x})是一个数\\ &= \frac{1}{n}\sum ^n_i(\omega^T(x_i - \bar{x}))(\omega^T( x_i - \bar{x}))^T\\ &= \frac{1}{n}\sum ^n_i\omega^T(x_i - \bar{x})(x_i - \bar{x})^T\omega\\ &= \omega^T(\frac{1}{n}\sum ^n_i (x_i - \bar{x})(x_i - \bar{x})^T)\omega\\ &= \omega^T\Sigma\omega \end{aligned}\] 其中\(\Sigma\)是样本\(X\)与自身的协方差矩阵。这样一来问题就变成以下优化问题: \[ max\quad \omega^T\Sigma\omega \\ s.t.\quad \omega^T\omega=1 \] 用拉格朗日乘数法求解: \[ L(\omega,\lambda)=\omega^T\Sigma\omega-\lambda(\omega^T\omega-1)\\ \frac{\partial L(\omega,\lambda)}{\partial \omega}=2\Sigma\omega-2\lambda\omega=0\\ \Sigma\omega=\lambda\omega \]\(\lambda\)\(\Sigma\)的特征值,\(\omega\)是特征值为\(\lambda\)的特征向量。由此可以推出: \[ \sigma^2=\lambda\omega^T\omega=\lambda \]投影后的方差就是协方差矩阵的特征值,使投影后的方差最大就是协方差矩阵的特征值最大。求解协方差矩阵\(\Sigma\)的特征值和特征向量时可以用到谱分解(又称特征分解): \[ \Sigma=Q\Lambda Q^T \] 其中\(Q\)为正交矩阵,\(\Lambda\)为对角矩阵,对角线上的元素为矩阵\(\Sigma\)的特征值。\(Q\)的列向量\(q_i\)\(\Lambda\)中对角元素\(\lambda_{ii}\)对应的特征向量。

PCA算法步骤如下

输入数据集\(X=[x_1, x_2,...,x_n]其中x_i\in R^n\),需要降到\(k\)维,

  1. 去平均值(又称去中心化),即\(x_i-\bar{x}\),得到\(\bar{X}=[x_1-\bar{x},x_2-\bar{x},...,x_n-\bar{x}]\)
  2. 求解协方差矩阵\(\displaystyle \Sigma=\frac{1}{n}\bar{X}\bar{X}^T\)的特征值及对应的特征向量
  3. 选取前\(k\)大的特征值\((\lambda_1,\lambda_2,...,\lambda_k)\)及对应的特征向量\((\omega_1,\omega_2,...,\omega_k)\)
  4. 降维后的数据 \[Y=WX,W=\left[\begin{matrix} \omega ^T_1 \\ \vdots \\ \omega ^T_k \end{matrix}\right]\]

代码如下

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
from sklearn.decomposition import PCA

# 官网 https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html
# 输入数据为(n_samples, n_features)
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=1)
pca.fit(X)

print(pca.explained_variance_ratio_) # 所保留的特征的方差百分比
print(pca.fit_transform(X)) # 返回降维后的数据(n_samples, n_components)