主成分分析(PCA)原理及示例

背景

在数据处理的应用中,一般不需要使用海量数据对象的全部特征,大量的数据特征并不能刻画数据的本质特征,反而使得数据的冗余影响到后续的数据处理,因此需要对数据进行特征提取,剔除数据的噪声与冗余。特征提取一方面能够显著降低数据维数,避免数据维数灾难,另一方面能够提取所需要数据的主要特征,抓住数据的本质特征,减少噪声与冗余对数据处理的影响。

关于数据特征提取的研究国内外已日趋成熟,常用的特征提取方法有线性判别分析法(LDA)、主成分分析(PCA)、局部保持映射法(LPP)、核主成分分析(KPCA)等都是模式分类中常用的特征提取方法。特征提取的中心思想是降低数据维数、简化数据,数据特征提取的基础是根据某种规则对数据映射,将数据由输入空间通过映射规则映射到特征空间下。这种映射一般情况下要遵守两个准则:其一是特征空间应该能最大限度的保留原始输入空间中的主要分类信息,其二是在数据降维的规则下,数据输入空间的维数应大于特征空间的维数。

主成分分析是模式分类中最常使用的特征提取算法,它是一种满足上述映射准则的数据压缩方法。作为经典的特征提取算法田之一,主成分分析能够较全面的刻画原始数据包含的内在信息,将原始数据转换为较少的综合特征来表示,其使用准则是使其在统计均方意义下的方差最优,其提取出的综合特征能够刻画原始输入数据的绝大部分的本质信息,剔除掉的维度认为是由信息重叠引起的,因此PCA可以达到去相关性的目的,可以认为是去除噪声的过程。作为常用的数据特征提取方法,主成分分析仍有不足,PCA在众多学者的深入研究下形成了许多改进算法。1

原理

假定有n个样本,每个样本共有p个变量/属性,构成一个n×p阶的数据矩阵:

$$X = \begin{pmatrix} x _ { 11 } & x _ { 12 } & \cdots & x _ { 1 p } \ x _ { 21 } & x _ { 22 } & \cdots & x _ { 2 p } \ \vdots & \vdots & \vdots & \vdots \ x _ { n 1 } & x _ { n 2 } & \cdots & x _ { n p } \end{pmatrix}$$

定义$x_1,x_2,\cdots,x_p$为原变量指标,$z_1,z_2,\cdots,z_n(m \lt p)$为新变量指标:

$$\begin{pmatrix} z _ { 1 } = l _ { 11 } x _ { 1 } + l _ { 12 } x _ { 2 } + \cdots + l _ { 1 p } x _ { p } \ z _ { 2 } = l _ { 21 } x _ { 1 } + l _ { 22 } x _ { 2 } + \cdots + l _ { 2 p } x _ { p } \ \vdots \ z _ { m } = l _ { m 1 } x _ { 1 } + l _ { m 2 } x _ { 2 } + \cdots + l _ { m p } x _ { p } \end{pmatrix} $$

上式系数$l_{ij}$确定原则:

  • $z_i$与$z_j (i \ne j; i,j=1,2,\cdots,m)$相互无关
  • $z_1$是$x1,x2,\cdots,x_p$的一切线性组合中方差最大者,$z_2$是与$z_1$不相关的$x1,x2,\cdots,x_p$的所有线性组合中方差最大者,$z_m$是与$z1,z2,\cdots,z_{m-1}$都不相关的所有线性组合中方差最大者
  • 则新变量指标$z1,z2,\cdots,z_{m}$分别称为原变量指标$x1,x2,\cdots,x_p$的第1、第2、……、第m主成分。

从以上的分析可以看出,主成分分析的实质就是确定原来变量$x_j(j=1,2,\cdots,p)$在诸主成分$z_i(i=1,2,\cdots,m)$上的载荷$l_{ij}(i=1,2,\cdots,m;j=1,2,\cdots,p)$。从数学上可以证明,载荷$l_{ij}$分别是相关矩阵的$m$个较大的特征值所对应的特征向量。

计算步骤

相关矩阵

$$R = \left[ \begin{array} { c c c c } r _ { 11 } & r _ { 12 } & \cdots & r _ { 1 p } \ r _ { 21 } & r _ { 22 } & \cdots & r _ { 2 p } \ \vdots & \vdots & \vdots & \vdots \ r _ { p 1 } & r _ { p 2 } & \cdots & r _ { p p } \end{array} \right]$$

$r_{ij}(i,j=1,2,\cdots,p)$为原变量$x_i$与$x_j$的相关系数,$r_{ij}=r_{ji}$,其计算公式为:

$$r _ { i j } = \frac { \sum _ { k = 1 } ^ { n } \left( x _ { k i } - \bar { x } _ { i } \right) \left( x _ { k j } - \bar { x } _ { j } \right) } { \sqrt { \sum _ { k = 1 } ^ { n } \left( x _ { k i } - \bar { x } _ { i } \right) ^ { 2 } \sum _ { k = 1 } ^ { n } \left( x _ { k j } - \bar { x } _ { j } \right) ^ { 2 } } }$$

特征值与特征向量

1.解特征方程$|\lambda I-R|=0$,求出特征值并使其按大小顺序排列:$\lambda_1≥\lambda2≥\cdots≥\lambda_p≥0$

2.分别求出对应于特征值$\lambda_i$的特征向量$l_i(i=1,2,\cdots,p)$,要求$||l_i||=1$。其中$l_ij$示由量$l_i$的第$j$个分量

贡献率

  • 贡献率

$$\frac { \lambda _ { i } } { \sum _ { k = 1 } ^ { p } \lambda _ { k } } \quad ( i = 1,2 , \cdots , p )$$

  • 累计贡献率

$$\frac { \sum _ { k = 1 } ^ { i } \lambda _ { k } } { \sum _ { k = 1 } ^ { p } \lambda _ { k } } \quad ( i = 1,2 , \cdots , p )$$

技巧
一般取累计贡献率达85-95%的特征值$\lambda_1,\lambda_2,…,\lambda_m$所对应的第1、第2、……、第m(m≤p)个主成分。

示例

模块介绍

我们主要使用Python的scikit-learn模块中的sklearn.decomposition.PCA类来进行PCA降维。PCA类基本不需要调参,一般来说,我们只需要指定我们需要降维到的维度,或者我们希望降维后的主成分的方差和占原始维度所有特征方差和的比例阈值就可以了。其构造函数为2

1
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)

该类的重要参数:

参数 介绍
n_components PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
copy 表示是否在运行算法时,将原始训练数据复制一份
whiten 是否白化
svd_solver 指定奇异值分解SVD的方法,由于特征分解是奇异值分解SVD的一个特例,一般的PCA库都是基于SVD实现的

该类的重要属性:

属性 类型 介绍
components_ 所保留的成分个数n
n_components_ 所保留的成分个数n
explained_variance_ 降维后的各主成分的方差值(已排序),方差值越大,则越是重要的主成分
explained_variance_ratio_ 降维后的各主成分的方差值占总方差值的比例(已排序),这个比例越大,则越是重要的主成分

该类的重要方法:

方法 介绍
fit(X[, y]) 每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤
fit_transform(X[, y]) 用X来训练PCA模型,同时返回降维后的数据
inverse_transform(X) 将降维后的数据转换成原始数据
transform(X) 将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维

使用

本例所使用数据为 尿检结果.xls

https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/20200814220628.png
尿检结果

  1. 导入数据集
1
2
3
4
5
6
7
import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

data = pd.read_excel(r'尿检结果.xls', header=0, index_col=0)
data_pca = data.iloc[:,4:].values
  1. 数据标准化
    PCA会被数据的大小所影响,所以在做之前,我们需要先对数据进行标准化。在此使用StandardScaler进行标准化, 标准化之后变为均值为0, 方差为1的数据:
1
data_pca = StandardScaler().fit_transform(data_pca)
  1. 估计新维数
    explained_variance_ratio_属性会输出排序后所有维度的方差比例,根据测试,前10项的方差比例和为0.89,因此可选择新维度为10。
1
2
3
4
5
pca = PCA()
pca.fit_transform(data_pca)
#  降维后的各主成分的方差值占总方差值的比例
print(pca.explained_variance_ratio_)
print(np.sum(pca.explained_variance_ratio_[:10]))

https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/20200814222857.png
估计新维数

  1. 开始降维
1
2
3
# 开始降维
pca = PCA(n_components=10)
result = pca.fit_transform(data_pca)
  1. 转换系数
    PCA中的新的维度是通过原始变量线性组合而来的(新维度1=原维度1×系数1+原维度2×系数2+……+原维度p×系数p),可通过PCA的pca.components_属性查看原维度的系数。3

参考


  1. 赵秀红. 基于主成分分析的特征提取的研究[D]. 西安电子科技大学. [2016] ↩︎

  2. 刘建平Pinard. 用scikit-learn学习主成分分析(PCA). 腾讯云社区. [2018-08-14] ↩︎

  3. 王茂南. 主成分分析(Principal component analysis, PCA)例子–Python. 文艺数学君. [2019-08-21] ↩︎