数据降维之主成分分析法(PCA)——基本原理与基于python sklearn库的PCA实现

目录

  • 简介
  • 算法流程
  • 基于python sklearn库的PCA例程

简介

主成分分析(Principal Component Analysis,PCA)通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量称为主成分,最终得到的主成分两两正交。

应用场景:
对于线性的拟合、分类算法,可以利用主成分分析对输入数据实现降维,去除冗余数据可以提高计算效率并提高计算精度;
对于难以进行可视化的高维数据可以利用主成分分析映射至二维进行可视化,方便进行展示。

缺点:
主成分分析法是一种无监督学习,其追求的是在降维之后能够最大化保持数据的内在信息,并未考虑不同类型数据,可能使不同类型的数据点揉杂在一起无法区分。
此外,线性不相关变量可能是非线性相关的,如x与x2 可能线性不相关但显然是非线性相关的,如果后续的拟合算法是非线性的,那么x与 x2 依然是冗余输入。

算法流程

符号约定:
记总样本个数为 n n n,每个初始样本所含特征数为 N N N,最终选择的主成分所含特征数为 K K K
记第 j j j个样本的第 i i i个特征为: x i j x_{ij} xij
N N N个初始特征为: X 1 , X 2 , . . . , X N X_1,X_2,...,X_N X1,X2,...,XN
每个初始特征为一个 n n n维向量,第 i i i个特征为 X i = [ x i 1 x i 1 . . . x i n ] X_i=\begin{bmatrix}x_{i1} &x_{i1} & ... &x_{in} \end{bmatrix} Xi=[xi1xi1...xin]
K K K个主成分即最终选择的特征为: Y 1 , Y 2 , . . . , Y K Y_1,Y_2,...,Y_K Y1,Y2,...,YK,每个主成分同样是 n n n维向量

计算流程:
第一步:计算各个特征间的协方差矩阵
C O V = [ c o v ( X 1 , X 1 ) ) c o v ( X 1 , X 2 ) ) . . . c o v ( X 1 , X N ) ) c o v ( X 2 , X 1 ) ) c o v ( X 2 , X 2 ) ) . . . c o v ( X 2 , X N ) ) . . . . . . . . . c o v ( X N , X 1 ) ) c o v ( X N , X 2 ) ) . . . c o v ( X N , X N ) ) ] N × N COV=\begin{bmatrix} cov(X_1,X_1)) &cov(X_1,X_2))&... &cov(X_1,X_N)) \\ cov(X_2,X_1)) &cov(X_2,X_2))&... &cov(X_2,X_N)) \\ ...& ...& & ...\\ cov(X_N,X_1)) &cov(X_N,X_2))&... &cov(X_N,X_N)) \end{bmatrix}_{N\times N} COV=cov(X1,X1))cov(X2,X1))...cov(XN,X1))cov(X1,X2))cov(X2,X2))...cov(XN,X2)).........cov(X1,XN))cov(X2,XN))...cov(XN,XN))N×N
其中 c o v ( X i , X j ) = 1 n − 1 ∑ p = 0 n ( x i p − X i ˉ ) ( x j p − X j ˉ ) cov(X_i,X_j)=\frac{1}{n-1} \sum ^{n}_{p=0}(x_{ip}-\bar{X_i})(x_{jp}-\bar{X_j}) cov(Xi,Xj)=n11p=0n(xipXiˉ)(xjpXjˉ)为特征 X i X_i Xi X j X_j Xj的协方差
X i ˉ = 1 n ∑ p = 0 n x i p \bar{X_i}=\frac{1}{n}\sum ^{n}_{p=0}x_{ip} Xiˉ=n1p=0nxip为特征 i i i的均值

第二步:计算特征值与特征向量
求协方差矩阵的特征值 λ λ λ与特征向量 v v v
其中特征值与特征向量均有 N N N
N N N个特征值由大到小排列,记为: λ 1 , λ 2 , . . . , λ N λ_1, λ_2,...,λ_N λ1,λ2,...,λN,并将对应的特征向量记为: v 1 , v 2 , . . . , v N v_1, v_2,...,v_N v1,v2,...,vN
由于 C O V COV COV是协方差矩阵,因此其特征向量满足:
λ 1 + λ 2 + . . . + λ N = 1 λ_1+ λ_2+...+λ_N=1 λ1+λ2+...+λN=1

第三步:对初始特征进行线性变换
对初始特征矩阵进行线性变换,得到 N N N个新特征 Y 1 , Y 2 , . . . , Y N Y_1,Y_2,...,Y_N Y1,Y2,...,YN
[ Y 1 Y 2 . . . Y N ] N × n = [ v 1 T v 2 T . . . v N T ] N × N × [ X 1 X 2 . . . X N ] N × n \begin{bmatrix}Y_1\\Y_2\\...\\Y_N\end{bmatrix}_{N\times n}=\begin{bmatrix}v_1^T\\v_2^T\\...\\v_N^T\end{bmatrix}_{N\times N}\times\begin{bmatrix}X_1\\X_2\\...\\X_N\end{bmatrix}_{N\times n} Y1Y2...YNN×n=v1Tv2T...vNTN×N×X1X2...XNN×n
我们认为协方差矩阵 C O V COV COV的第 i i i个(由大到小排列的)特征值 λ i λ_i λi即是第 i i i个新特征 Y i Y_i Yi所包含的信息量
如若 λ 2 = 0.2 λ_2=0.2 λ2=0.2,则我们认为 Y 2 Y_2 Y2包含了原特征所含所有信息量的20%

第四步:选择主成分
由于特征值 λ 1 , λ 2 , . . . , λ N λ_1, λ_2,...,λ_N λ1,λ2,...,λN是由大到小排列的,而 λ i λ_i λi即是 Y i Y_i Yi所包含的信息量的大小,因此新特征 Y 1 , Y 2 , . . . , Y N Y_1,Y_2,...,Y_N Y1,Y2,...,YN所包含的信息量也是依次递减的,因此要想使主成分保留最多的信息,只需选取前 K K K个特征作为主成分即可
即主成分为: Y 1 , Y 2 , . . . , Y K Y_1,Y_2,...,Y_K Y1,Y2,...,YK
在一些情况下, K K K的值是给定的,如希望对高维数据进行可视化的时候需要令 K = 2 K=2 K=2即只保留两个信息最多的特征作为主成分
在另一些情况下,可以设置阈值 λ c r i t λ_{crit} λcrit,选取满足 λ K > λ c r i t λ_K>λ_{crit} λK>λcrit的前 K K K个特征作为主成分,确保舍弃的信息足够少

基于python sklearn库的PCA例程

利用sklearn库中的函数实现主成分分析
所选数据为39节点电网仿真数据,包含5000个样本,每个样本包含160个特征量,即 n = 5000 , N = 160 n=5000, N=160 n=5000,N=160
特征量包括各节点电压、功率、各线路电流等,显然这些特征量存在冗余的现象
由于并不确定要选择多少个特征作为主成分,首先选取 K = 160 K=160 K=160,观察160个特征向量再确定主成分所含的特征个数

import numpy as np
from sklearn.decomposition import PCA

test_features, test_labels = read_data(ADDRESS) 
#从地址ADDRESS读取初始特征与标签,此函数为自定义函数

pca = PCA(n_components=160)
#创建PCA类,参数n_components为主成分所含特征数,令其为'mle'则自动选取特征数
#这里选择160个特征,观察每个特征所包含的信息量后手动选取主成分所含的特征
pca_feature = pca.fit_transform(test_features)
#得到线性变换后的160个特征

feature_info = np.zeros(160)
for i in range(160):
    feature_info[i] = sum(pca.explained_variance_ratio_[0:i])
#pca.explained_variance_ratio_为160个特征向量,即线性变换后的160个特征所含信息量
#sum(pca.explained_variance_ratio_[0:i])计算前i个特征所含信息量之和
#存储在feature_info中

PCA类的参数n_components为主成分包含的特征数,默认为1,也可以设定为字符串’mle’自动选取特征数
函数pca.fit_transform函数输入值为原始数据,输出为主成分,同时将会利用输入的原始数据训练模型
pca.explained_variance_ratio_为得到的 K K K个特征向量

将前 i i i个特征所含信息量之和制成图表,如下所示:
数据降维之主成分分析法(PCA)——基本原理与基于python sklearn库的PCA实现_第1张图片

特征数 信息量
1 0.102006
30 0.706626
60 0.999479
90 0.999998
120 1.000000

可以看出第一个特征包含了10%以上的信息量,而前60个特征就已经几乎包含原数据的所有信息,再增加特征几乎不会增加信息量,余下特征可以作为冗余数据,因此可以确定 K = 60 K=60 K=60
此时有两种方法可以获取主成分
一是直接取此前计算的160个新特征的前60个

pca = PCA(n_components=160)
pca_feature = pca.fit_transform(test_features)#计算160个新特征
pca_feature_60 = pca_feature[:, 0:60]#取前60个特征

二是令 K = 60 K=60 K=60重新调用函数计算

pca_60 = PCA(n_components=60)
pca_feature_60 = pca_60.fit_transform(test_features)#直接计算60个新特征

这两种方法是等价的
如果希望利用同样的模型提取新数据的主成分,则可以利用transform函数实现:

pca_feature = pca.fit_transform(test_features)#利用测试数据训练模型
pca_feature_new=pca.transform(new_data)#利用训练好的模型提取新数据的特征

你可能感兴趣的:(机器学习,数据处理)