目录

  • 一、PCA简介
  • 二、举个例子
  • 三、计算过程(公式)
    • 3.0 题干假设
    • 3.1 标准化
    • 3.2 计算协方差矩阵
    • 3.3 计算特征值和特征值向量
    • 3.3 多重共线性检验(可跳过)
    • 3.4 适合性检验(可跳过)
    • 3.5 计算主成分贡献率及累计贡献率
    • 3.6 选取和表示主成分
    • 3.7 系数的简单分析
  • 四、案例分析(python)
    • 4.1 一步一步PCA
    • 4.2 sklearn的PCA
    • 4.3 其他实现代码(长期更新)
      • 4.3.1 numpy实现和sklearn实现
  • 五、补充总结
  • 六、参考链接

最近在文献调研,发现PCA基本都有用到,回忆起了机器学习和数学建模,总之还是要好好学学捏。

一、PCA简介

定义:主成分分析(Principal Component Analysis, PCA)是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。

换一种说法:PCA去除噪声和不重要的特征,将多个指标转换为少数几个主成分,这些主成分是原始变量的线性组合,且彼此之间互不相关,其能反映出原始数据的大部分信息,而且可以提升数据处理的速度。

为什么会出现PCA呢?因为每个变量都在不同程度上反映了所研究问题的某些信息,并且指标之间彼此有一定的相关性,因而所得的统计数据反映的信息在一定程度上有重叠。在用统计方法研究多变量问题时,变量太多会增加计算量和分析问题的复杂性

核心思想降维,这个过程中可能会损失精度,但是能获取更高更关键的因素。


二、举个例子

例子1:评选三好学生,每个学生都有很多特征,比如学习成绩、社会实践、思想道德、体育成绩等。在评比中,有一些特征属于“ 无用特征 ”,比如身高、体重、头发长短等,这些特征在评比中是不会考虑的;而有一些特征属于“ 冗余特征 ”,比如各科成绩、总成绩、GPA,实际上这些有一个即可。

例子2:见下图。原本黑色坐标系中需要记录每个点的横纵坐标(xi, yi),也就是 2 个纬度的数据。

但如果转换坐标系,如绿色坐标系所示,让每个点都位于同一条轴上,这样每个点坐标为(xi’, 0),此时仅用x’坐标表示即可,即 1 个维度。


在这个过程中,原先需要保存的 2 维数据变成了 1 维数据,叫做数据降维 / 数据提炼。而PCA的任务形象理解也就是坐标系的转换

PCA其实目的就是寻找这个转换后的坐标系,使数据能尽可能分布在一个或几个坐标轴上,同时尽可能保留原先数据分布的主要信息,使原先高维度的信息,在转换后能用低维度的信息来保存。而新坐标系的坐标轴,称为主成分(Principal components, PC),这也就是PCA的名称来源。


三、计算过程(公式)

3.0 题干假设

首先假设有 n 个样本,p 个特征,xijx_{ij}xij​ 表示第i个样本的第 j 个特征,这些样本构成的 n × p 特征矩阵 X 为:
X=[x11x12⋯x1px21x22⋯x2p⋮⋮⋱⋮xn1xn2⋯xnp]=[x1,x2,⋯,xp]X=\begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1p} \\ x_{21} & x_{22} & \cdots & x_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{np} \\ \end{bmatrix} = [x_1,x_2,\cdots,x_p]X=⎣⎡​x11​x21​⋮xn1​​x12​x22​⋮xn2​​⋯⋯⋱⋯​x1p​x2p​⋮xnp​​⎦⎤​=[x1​,x2​,⋯,xp​]

我们的目的是找到一个转换矩阵,将 p 个特征转化为 m 个特征(m < p),从而实现特征降维。即找到一组新的特征 / 变量z1z_1z1​, z2z_2z2​, …, zmz_mzm​(m ≤ p),满足以下式子:
{z1=l11x1+l12x2+⋯+l1pxpz2=l21x1+l22x2+⋯+l2pxp⋮zm=lm1x1+lm2x2+⋯+lmpxp\begin{cases} \begin{aligned} z_1&=l_{11}x_1+l_{12}x_2+\dots+l_{1p}x_p \\ z_2&=l_{21}x_1+l_{22}x_2+\dots+l_{2p}x_p \\ \vdots \\ z_m&=l_{m1}x_1+l_{m2}x_2+\dots+l_{mp}x_p \end{aligned} \end{cases}⎩⎨⎧​z1​z2​⋮zm​​=l11​x1​+l12​x2​+⋯+l1p​xp​=l21​x1​+l22​x2​+⋯+l2p​xp​=lm1​x1​+lm2​x2​+⋯+lmp​xp​​​

3.1 标准化

有的博客写的是去中心化而不是标准化,在计算过程中也仅体现出步骤的不同,实际两种方法都可以用的,大家也可以看看这篇博客看看这几种“化”的区别:数据归一化、标准化和去中心化。本篇只研究标准化,第四部分的参考链接中介绍了标准化和去中心化的步骤,写得很详细,欢迎大家学习~

标准化过程如下:

  1. 计算每个特征(共p个特征)的均值 xj‾\overline{x_j}xj​​ 和标准差 SjS_jSj​,公式如下:
    xj‾=1n∑i=1nxij\overline{x_j}=\frac{1}{n}\sum_{i=1}^nx_{ij}xj​​=n1​i=1∑n​xij​
    Sj=∑i=1n(xij−xj‾)2n−1S_j=\sqrt{\frac{\sum_{i=1}^n(x_{ij}-\overline{x_j})^2}{n-1}}Sj​=n−1∑i=1n​(xij​−xj​​)2​​

  2. 将每个样本的每个特征进行标准化处理,得到标准化特征矩阵XstandX_{stand}Xstand​:
    Xij=xij−xj‾SjX_{ij}=\frac{x_{ij}-\overline{x_j}}{S_j}Xij​=Sj​xij​−xj​​​
    Xstand=[X11X12⋯X1pX21X22⋯X2p⋮⋮⋱⋮Xn1Xn2⋯Xnp]=[X1,X2,⋯,Xp]X_{stand}=\begin{bmatrix} X_{11} & X_{12} & \cdots & X_{1p} \\ X_{21} & X_{22} & \cdots & X_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ X_{n1} & X_{n2} & \cdots & X_{np} \\ \end{bmatrix} = [X_1,X_2,\cdots,X_p]Xstand​=⎣⎡​X11​X21​⋮Xn1​​X12​X22​⋮Xn2​​⋯⋯⋱⋯​X1p​X2p​⋮Xnp​​⎦⎤​=[X1​,X2​,⋯,Xp​]

3.2 计算协方差矩阵

协方差矩阵是汇总了所有可能配对的变量间相关性的一个表。

协方差矩阵 R 为:
R=[r11r12⋯r1pr21r22⋯r2p⋮⋮⋱⋮rp1rp2⋯rpp]R=\begin{bmatrix} r_{11} & r_{12} & \cdots & r_{1p} \\ r_{21} & r_{22} & \cdots & r_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ r_{p1} & r_{p2} & \cdots & r_{pp} \\ \end{bmatrix}R=⎣⎡​r11​r21​⋮rp1​​r12​r22​⋮rp2​​⋯⋯⋱⋯​r1p​r2p​⋮rpp​​⎦⎤​

rij=1n−1∑k=1n(Xki−Xi‾)(Xkj−Xj‾)=1n−1∑k=1nXkiXkj\begin{aligned} r_{ij}&=\frac{1}{n-1}\sum_{k=1}^n(X_{ki}-\overline{X_i})(X_{kj}-\overline{X_j})\\ &=\frac{1}{n-1}\sum_{k=1}^nX_{ki}X_{kj} \end{aligned}rij​​=n−11​k=1∑n​(Xki​−Xi​​)(Xkj​−Xj​​)=n−11​k=1∑n​Xki​Xkj​​

3.3 计算特征值和特征值向量

计算矩阵R的特征值,并按照大小顺序排列,计算对应的特征向量,并进行标准化,使其长度为1。R是半正定矩阵,且tr(R)=∑k=1pλk=ptr(R) = \sum_{k=1}^p\lambda_k = ptr(R)=∑k=1p​λk​=p。

特征值:λ1≥λ2≥⋯≥λp≥0\lambda_1\ge\lambda_2\ge \dots \ge \lambda_p\ge0λ1​≥λ2​≥⋯≥λp​≥0

特征向量:L1=[l11,l12,…,l1p]T…Lp=[lp1,lp2,…,lpp]TL_1=[l_{11},l_{12},\dots ,l_{1p}]^T \dots L_p=[l_{p1},l_{p2},\dots ,l_{pp}]^TL1​=[l11​,l12​,…,l1p​]T…Lp​=[lp1​,lp2​,…,lpp​]T

3.3 多重共线性检验(可跳过)

若存在明显的多重共线性,则重新根据研究问题选取初始分析变量。

多重共线性的影响、判定及消除的方法

由于这里是【计算过程】而不是【研究过程】,此处不推翻3.0部分的假设,着重探讨PCA的计算流程即可,故3.3和3.4部分可跳过,真正的研究过程再考虑特征矩阵如何取。

3.4 适合性检验(可跳过)

一组数据是否适用于主成分分析,必须做适合性检验。可以用球形检验和KMO统计量检验。

1. 球形检验(Bartlett)
球形检验的假设:
H0:相关系数矩阵为单位阵(即变量不相关)
H1:相关系数矩阵不是单位阵(即变量间有相关关系)

2. KMO(Kaiser-Meyer-Olkin)统计量
KMO统计量比较样本相关系数与样本偏相关系数,它用于检验样本是否适于作主成分分析。KMO的值在0-1之间,该值越大,则样本数据越适合作主成分分析和因子分析。一般要求该值大于0.5,方可作主成分分析或者相关分析。Kaiser在1974年给出了经验原则:

KMO值的范围 适合性情况
0.9以上 适合性很好
0.8~0.9 适合性良好
0.7~0.8 适合性中等
0.6~0.7 适合性一般
0.5~0.6 适合性不好
0.5以下 不能接受的

3.5 计算主成分贡献率及累计贡献率

第 i 个主成分的贡献率为:
λi∑k=1pλk\frac{\lambda_i}{\sum_{k=1}^p\lambda_k}∑k=1p​λk​λi​​

前 i 个主成分的累计贡献率为:
∑j=1iλj∑k=1pλk\frac{\sum_{j=1}^i\lambda_j}{\sum_{k=1}^p\lambda_k}∑k=1p​λk​∑j=1i​λj​​

3.6 选取和表示主成分

一般取累计贡献率超过80%的特征值所对应的第一、第二、…、第m(m ≤ p)个主成分。Fi表示第i个主成分:
Fi=li1X1+li2X2+⋯+lipXp,(i=1,2,…,p)F_i=l_{i1}X_1+l_{i2}X_2+\dots+l_{ip}X_p,(i=1,2,\dots,p)Fi​=li1​X1​+li2​X2​+⋯+lip​Xp​,(i=1,2,…,p)

3.7 系数的简单分析

对于某个主成分而言,指标前面的系数越大(即 lijl_{ij}lij​),代表该指标对于该主成分的影响越大。


四、案例分析(python)

参考了这个链接:主成分分析(PCA)及其可视化——python。其中提供了两种方法,分别对应3.1为标准化去中心化的步骤,每一步都有注释和代码,很详细!

还有这个写的太好了qaq,英文的球球大家一定要看:Principal Component Analysis in 3 Simple Steps

4.1 一步一步PCA

1. 数据集
是从这部分的第一个链接里随便扣出来的部分数据,如果大家感兴趣可以玩玩。

链接:https://pan.baidu.com/s/108JPN6LGg7GJfxCiJaItZA
提取码:3w5u

2. 安装库

pip install pandas
pip install numpy
pip install seaborn
pip install matplotlib
pip install sklearn
pip install factor_analyzer

3. 读取数据集

import pandas as pd
import numpy as np
import seaborn as sns
# 读取数据集
df = pd.read_csv(r"D:\vscpro\PyThon\data.csv",sep=',',header=None).reset_index(drop=True)
df.columns = ['a', 'b', 'c']
df.dropna(how="all", inplace=True)
df.tail()

4. 适合性检验(Bartlett && KMO)

from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
from factor_analyzer.factor_analyzer import calculate_kmodf_check = df
# Bartlett 球状检验
chi_square_value, p_value = calculate_bartlett_sphericity(df_check)
print("Bartlett=", chi_square_value, p_value)# KMO检验(>0.5为好,越靠近1越好)
kmo_all, kmo_model = calculate_kmo(df_check)
print("KMO=", kmo_all)

5. 标准化

# 标准化
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
X = df.iloc[:, 0:3].values
Y = df.iloc[:, 2].values
X_std = StandardScaler().fit_transform(X)df = preprocessing.scale(df)
print(df)

6. 法一:计算系数相关矩阵并特征求解
金融领域常使用相关矩阵代替协方差矩阵。

# 系数相关性矩阵
covX = np.around(np.corrcoef(df.T), decimals = 3)
# 系数相关矩阵特征求解
featValue, featVec=  np.linalg.eig(covX.T)
print(featValue, featVec)

7. 法二:计算协方差矩阵并特征求解

# 协方差矩阵
# ①写法:
# mean_vec = np.mean(X_std, axis=0)
# covX = (X_std - mean_vec).T.dot((X_std - mean_vec)) / (X_std.shape[0]-1)
# ②写法:
covX = np.cov(X_std.T)
# print(covX)# 协方差矩阵特征求解
cov_mat = np.cov(X_std.T)
eig_vals, eig_vecs = np.linalg.eig(cov_mat)# 基于相关矩阵的标准化数据的特征分解
cor_mat1 = np.corrcoef(X_std.T)
eig_vals, eig_vecs = np.linalg.eig(cor_mat1)# 基于相关矩阵的原始数据的特征分解
cor_mat2 = np.corrcoef(X.T)
eig_vals, eig_vecs = np.linalg.eig(cor_mat2)
print(eig_vals, eig_vecs)

8. 计算贡献率

# 特征值排序输出
featValue = sorted(featValue)[::-1]# 贡献度
gx = featValue / np.sum(featValue)#累计贡献度
lg = np.cumsum(gx)
print(featValue, gx, lg)

9. 选取主成分

# 选取主成分,一般要超过80%或85%
k = [i for i in range(len(lg)) if lg[i] < 0.85]
k = list(k)
print(k)


10. 表示主成分

# 主成分对应的特征向量矩阵
selectVec = np.matrix(featVec.T[k]).T
selectVe = selectVec*(-1)
print(selectVec)# 表示主成分
finalData = np.dot(X_std, selectVec)
print(finalData)

11. 绘制图像

import matplotlib.pyplot as plt
# 绘制散点图和折线图
plt.scatter(range(1, df.shape[1] + 1), featValue)
plt.plot(range(1, df.shape[1] + 1), featValue)plt.title("Plot")
plt.xlabel("Factors")
plt.ylabel("Eigenvalue")plt.grid()
plt.show()

4.2 sklearn的PCA

这个数据集是经典鸢尾花~

from sklearn.decomposition import PCA as sklearnPCA
sklearn_pca = sklearnPCA(n_components=2)
Y_sklearn = sklearn_pca.fit_transform(X_std)# draw
with plt.style.context('seaborn-whitegrid'):plt.figure(figsize=(6, 4))for lab, col in zip(('Iris-setosa', 'Iris-versicolor', 'Iris-virginica'),('blue', 'red', 'green')):plt.scatter(Y_sklearn[y==lab, 0],Y_sklearn[y==lab, 1],label=lab,c=col)plt.xlabel('Principal Component 1')plt.ylabel('Principal Component 2')plt.legend(loc='lower center')plt.tight_layout()plt.show()

4.3 其他实现代码(长期更新)

这部分用来堆堆其他大佬们写的代码,方便后面学习和使用。

4.3.1 numpy实现和sklearn实现

来自主成分分析(PCA)原理详解

(1)PCA的Python实现

##Python实现PCA
import numpy as np
def pca(X,k):#k is the components you want#mean of each featuren_samples, n_features = X.shapemean=np.array([np.mean(X[:,i]) for i in range(n_features)])#normalizationnorm_X=X-mean#scatter matrixscatter_matrix=np.dot(np.transpose(norm_X),norm_X)#Calculate the eigenvectors and eigenvalueseig_val, eig_vec = np.linalg.eig(scatter_matrix)eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)]# sort eig_vec based on eig_val from highest to lowesteig_pairs.sort(reverse=True)# select the top k eig_vecfeature=np.array([ele[1] for ele in eig_pairs[:k]])#get new datadata = np.dot(norm_X,np.transpose(feature))return dataX = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])print(pca(X,1))

(2)sklearn的PCA

##用sklearn的PCA
from sklearn.decomposition import PCA
import numpy as np
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.transform(X))

五、补充总结

PCA的数学思想:

  • 根据p个特征的线性组合,得到一个新的特征z,使得该特征的方差最大,该特征即为主成分。
  • 再次寻找p个特征的线性组合,得到新的特征,该特征与之前得到的主成分线性无关,且方差最大。

其余要点:

  • 如果每个主成分的贡献率都相差不多,则不建议使用PCA。因为它一定程度上舍弃了部分信息,来提高整体的计算效率。
  • 对于降维形成的主成分,我们经常无法找到其在实际情况中所对应的特征,即主成分的解释其含义一般带有模糊性,不像原始变量的含义那么清楚确切,这也是PCA的缺陷所在。
  • PCA不可用于评价类模型。可用于聚类、回归,如回归分析解决多重共线性。

六、参考链接

  1. 如何理解主成分分析法 (PCA)
  2. 清风数学建模学习笔记——主成分分析(PCA)原理详解及案例分析
  3. PCA的数学原理
  4. 【数据处理方法】主成分分析(PCA)原理分析
  5. 协方差矩阵和矩阵相关系数的理解

主成分分析法(PCA)的理解(附python代码案例)相关推荐

  1. 教程 | 理解和实现自然语言处理终极指南(附Python代码)

     教程 | 理解和实现自然语言处理终极指南(附Python代码) 时间 2017-02-16 14:41:39 机器之心 原文  http://www.jiqizhixin.com/article ...

  2. 主成分分析(PCA)方法步骤以及代码详解

    主成分分析(PCA)方法步骤以及代码详解 前言 上一节我们了解到在构建神经网络模型,除了掌握如何搭建神经网络架构,了解参数具体含义,规避风险等方法.第一步是要对采用数据集的详细了解,无需接触任何神经网 ...

  3. python重点知识归纳_一文了解机器学习知识点及其算法(附python代码)

    一文了解机器学习知识点及其算法(附python代码) 来源:数据城堡 时间:2016-09-09 14:05:50 作者: 机器学习发展到现在,已经形成较为完善的知识体系,同时大量的数据科学家的研究成 ...

  4. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码) 译注:文内提供的代码和运行结果有一定差异,可以从这里下载完整代码对照参考.另外,我自己跟着教程做的时候,发现我的库无法解析字符串类型的特征,所以只 ...

  5. python随机森林变量重要性_推荐 :一文读懂随机森林的解释和实现(附python代码)...

    原标题:推荐 :一文读懂随机森林的解释和实现(附python代码) 作者:WilliamKoehrsen:翻译:和中华:校对:李润嘉 本文约6000字,建议阅读15分钟. 本文从单棵决策树讲起,然后逐 ...

  6. 利用OpenSearch API检索和下载数据 附Python代码实例

    利用OpenSearch API检索和下载数据 附Python代码实例 在数据下载过程中,我们常常会需要下载非常多的数据文件,这时我们可以利用wget等软件或者编写数据下载脚本来实现数据下载的批处理. ...

  7. 机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)

    机器学习系列(12)_XGBoost参数调优完全指南(附Python代码) 原文链接:http://blog.csdn.net/han_xiaoyang/article/details/5266539 ...

  8. 数据降维之主成分分析法PCA

    主成分分析法PCA 参考链接:https://www.bilibili.com/video/BV1E5411E71z 主成分分析(Principal Component Analysis,PCA), ...

  9. sklearn 主成分分析法 PCA和IPCA

    主成分分析法 (PCA) 是一种常用的数据分析手段.对于一组不同维度 之间可能存在线性相关关系的数据,PCA 能够把这组数据通过正交变换变 成各个维度之间线性无关的数据.经过 PCA 处理的数据中的各 ...

最新文章

  1. IE6左右边框断线现象
  2. Linux显示某文件中有关某字符串的信息
  3. am.java_6.3.1 从am说起
  4. boost::describe模块实现==重载的测试程序
  5. EM算法【图像迭代】
  6. 晶晶赴约会(信息学奥赛一本通-T1049)
  7. 【AI视野·今日CV 计算机视觉论文速览 第191期】Wed, 5 May 2021
  8. express中的错误处理
  9. 双时隙的工作原理_提高频点利用 海能达双时隙功能效率高
  10. 【博客搬家】【转】matlab 6.5和7.0中simulink模型的兼容问题
  11. Cannot resolve plugin org.apache.tomcat.maven:tomcat7-maven-plugin:<unknown>
  12. java拼音搜索排序算法_神级程序员Java Script300行代码搞定汉字转拼音
  13. 判断手机横屏竖屏,切换时刷新一次页面
  14. 【附源码】计算机毕业设计java音乐鉴赏网站前端开发设计与实现
  15. 【Axure高保真原型】拖拉拽元件库
  16. CSS(层叠样式表(Cascading Style Sheets))历史
  17. 有一个很好的PS滤镜,可以做出非常漂亮的抽丝效果,我一定要保存下来
  18. 【笔记】Polygon mesh processing读书笔记(5)
  19. CISCO PACKET TRACER 实验:以太网连接Internet
  20. 第十三周 任务二

热门文章

  1. Android蓝牙相关—蓝牙打印
  2. windows 下同步时间的几种方法
  3. 买飞机票前必须知道的那些事!
  4. Google Protobufs(1) - maven工程使用protoc插件编译proto文件
  5. 域名系统DNS知识点
  6. html给隐藏域赋值,selenium webDriver给隐藏域赋值 input hidden set value
  7. python字节单位换算
  8. linux-deepin-GPU-CudaFFT从入门到使用三天
  9. javascript取随机数_JS随机数生成的三种方法 js随机数生成器
  10. 移动魔百盒cm211-1-zg(2+8)晶晨S905L3B芯片+最新WIFI芯片UWE5621DS,全网最完美固件