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

目录

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

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

; 一、PCA简介

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

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

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

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

二、举个例子

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

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

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

主成分分析法(PCA)的理解(附python代码案例)
在这个过程中,原先需要保存的 2 维数据变成了 1 维数据,叫做数据降维 / 数据提炼。而PCA的任务形象理解也就是 坐标系的转换

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

; 三、计算过程(公式)

3.0 题干假设

首先假设有 n 个样本,p 个特征,x i j x_{ij}x ij ​ 表示第i个样本的第 j 个特征,这些样本构成的 n × p 特征矩阵 X 为:
X = [ x 11 x 12 ⋯ x 1 p x 21 x 22 ⋯ x 2 p ⋮ ⋮ ⋱ ⋮ x n 1 x n 2 ⋯ x n p ] = [ x 1 , x 2 , ⋯ , x p ] 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 =⎣⎡​x 11 ​x 21 ​⋮x n 1 ​​x 12 ​x 22 ​⋮x n 2 ​​⋯⋯⋱⋯​x 1 p ​x 2 p ​⋮x n p ​​⎦⎤​=[x 1 ​,x 2 ​,⋯,x p ​]

我们的目的是找到一个转换矩阵,将 p 个特征转化为 m 个特征(m < p),从而实现特征降维。即找到一组新的特征 / 变量z 1 z_1 z 1 ​, z 2 z_2 z 2 ​, …, z m z_m z m ​(m ≤ p),满足以下式子:
{ z 1 = l 11 x 1 + l 12 x 2 + ⋯ + l 1 p x p z 2 = l 21 x 1 + l 22 x 2 + ⋯ + l 2 p x p ⋮ z m = l m 1 x 1 + l m 2 x 2 + ⋯ + l m p x p \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}⎩⎨⎧​z 1 ​z 2 ​⋮z m ​​=l 11 ​x 1 ​+l 12 ​x 2 ​+⋯+l 1 p ​x p ​=l 21 ​x 1 ​+l 22 ​x 2 ​+⋯+l 2 p ​x p ​=l m 1 ​x 1 ​+l m 2 ​x 2 ​+⋯+l m p ​x p ​​​

3.1 标准化

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

标准化过程如下:

  1. 计算每个特征(共p个特征)的均值 x j ‾ \overline{x_j}x j ​​ 和标准差 S j S_j S j ​,公式如下:
    x j ‾ = 1 n ∑ i = 1 n x i j \overline{x_j}=\frac{1}{n}\sum_{i=1}^nx_{ij}x j ​​=n 1 ​i =1 ∑n ​x ij ​
    S j = ∑ i = 1 n ( x i j − x j ‾ ) 2 n − 1 S_j=\sqrt{\frac{\sum_{i=1}^n(x_{ij}-\overline{x_j})^2}{n-1}}S j ​=n −1 ∑i =1 n ​(x ij ​−x j ​​)2 ​​
  2. 将每个样本的每个特征进行标准化处理,得到标准化特征矩阵X s t a n d X_{stand}X s t an d ​:
    X i j = x i j − x j ‾ S j X_{ij}=\frac{x_{ij}-\overline{x_j}}{S_j}X ij ​=S j ​x ij ​−x j ​​​
    X s t a n d = [ X 11 X 12 ⋯ X 1 p X 21 X 22 ⋯ X 2 p ⋮ ⋮ ⋱ ⋮ X n 1 X n 2 ⋯ X n p ] = [ X 1 , X 2 , ⋯ , X p ] 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]X s t an d ​=⎣⎡​X 11 ​X 21 ​⋮X n 1 ​​X 12 ​X 22 ​⋮X n 2 ​​⋯⋯⋱⋯​X 1 p ​X 2 p ​⋮X n p ​​⎦⎤​=[X 1 ​,X 2 ​,⋯,X p ​]

3.2 计算协方差矩阵

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

协方差矩阵 R 为:
R = [ r 11 r 12 ⋯ r 1 p r 21 r 22 ⋯ r 2 p ⋮ ⋮ ⋱ ⋮ r p 1 r p 2 ⋯ r p p ] 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 =⎣⎡​r 11 ​r 21 ​⋮r p 1 ​​r 12 ​r 22 ​⋮r p 2 ​​⋯⋯⋱⋯​r 1 p ​r 2 p ​⋮r pp ​​⎦⎤​

r i j = 1 n − 1 ∑ k = 1 n ( X k i − X i ‾ ) ( X k j − X j ‾ ) = 1 n − 1 ∑ k = 1 n X k i X k j \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}r ij ​​=n −1 1 ​k =1 ∑n ​(X ki ​−X i ​​)(X kj ​−X j ​​)=n −1 1 ​k =1 ∑n ​X ki ​X kj ​​

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

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

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

特征向量:L 1 = [ l 11 , l 12 , … , l 1 p ] T … L p = [ l p 1 , l p 2 , … , l p p ] T L_1=[l_{11},l_{12},\dots ,l_{1p}]^T \dots L_p=[l_{p1},l_{p2},\dots ,l_{pp}]^T L 1 ​=[l 11 ​,l 12 ​,…,l 1 p ​]T …L p ​=[l p 1 ​,l p 2 ​,…,l pp ​]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 = 1 p λ k \frac{\lambda_i}{\sum_{k=1}^p\lambda_k}∑k =1 p ​λk ​λi ​​

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

3.6 选取和表示主成分

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

3.7 系数的简单分析

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

四、案例分析(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()

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

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

from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
from factor_analyzer.factor_analyzer import calculate_kmo

df_check = df

chi_square_value, p_value = calculate_bartlett_sphericity(df_check)
print("Bartlett=", chi_square_value, p_value)

kmo_all, kmo_model = calculate_kmo(df_check)
print("KMO=", kmo_all)

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

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)

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

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


covX = np.around(np.corrcoef(df.T), decimals = 3)

featValue, featVec=  np.linalg.eig(covX.T)
print(featValue, featVec)

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

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


covX = np.cov(X_std.T)

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)

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

8. 计算贡献率


featValue = sorted(featValue)[::-1]

gx = featValue / np.sum(featValue)

lg = np.cumsum(gx)
print(featValue, gx, lg)

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

9. 选取主成分


k = [i for i in range(len(lg)) if lg[i] < 0.85]
k = list(k)
print(k)

主成分分析法(PCA)的理解(附python代码案例)
10. 表示主成分

selectVec = np.matrix(featVec.T[k]).T
selectVe = selectVec*(-1)
print(selectVec)

finalData = np.dot(X_std, selectVec)
print(finalData)

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

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()

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

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)

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()

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

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

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

4.3.1 numpy实现和sklearn实现

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

(1)PCA的Python实现


import numpy as np
def pca(X,k):

  n_samples, n_features = X.shape
  mean=np.array([np.mean(X[:,i]) for i in range(n_features)])

  norm_X=X-mean

  scatter_matrix=np.dot(np.transpose(norm_X),norm_X)

  eig_val, eig_vec = np.linalg.eig(scatter_matrix)
  eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)]

  eig_pairs.sort(reverse=True)

  feature=np.array([ele[1] for ele in eig_pairs[:k]])

  data = np.dot(norm_X,np.transpose(feature))
  return data

X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])

print(pca(X,1))

(2)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. 协方差矩阵和矩阵相关系数的理解

Original: https://blog.csdn.net/qq_45722196/article/details/127584340
Author: Mayer_myx
Title: 主成分分析法(PCA)的理解(附python代码案例)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/729471/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [CG从零开始] 3. 安装 pyassimp 库加载模型文件

    assimp 是一个开源的模型加载库,支持非常多的格式,还有许多语言的 binding,这里我们选用 assimp 的 python 的 binding 来加载模型文件。不过社区主…

    Python 2023年10月20日
    029
  • PyTorch人脸识别+Flask连接数据库

    PyTorch人脸识别+Flask连接数据库 文章目录 PyTorch人脸识别+Flask连接数据库 前言 一、flask是什么? 二、实验过程 * 1.连接数据库并查询需要的数据…

    Python 2023年8月12日
    0102
  • 学习Pytest框架(一)

    1、单元测试:对最小单位(函数、方法)进行测试 2、单元测试框架主要做: a、测试发现 b、测试执行 c、测试判断 d、测试报告 3、可以进行失败用例的重试和跳过用例 4、可以进行…

    Python 2023年9月10日
    029
  • Python学习笔记(十)

    对应第十五章折线图部分 import matplotlib.pyplot as plt squares= [1,4,9,16,25] fig,ax = plt.subplots()…

    Python 2023年9月5日
    048
  • 数据挖掘01-相关性分析及可视化【Pearson, Spearman, Kendall】

    数据挖掘01-相关性分析及可视化【Pearson, Spearman, Kendall】 * – 简介 – 一、什么是相关性分析 – 二、常见的…

    Python 2023年8月2日
    080
  • Single electron atomic structure

    def playscene1(): title = Text(‘单电子原子结构’, font=’STZhongsong’) ext({1:’1913年,丹麦物理学家 Bohr 提出…

    Python 2023年6月12日
    069
  • 多语言通信基础 01 rpc

    什么是rpc RPC(Remote Procedure Call) 远程过程调用,简单理解就是一个节点请求另一个节点提供服务。 对应rpc的是本地过程调用,函数调用是最常见测本地过…

    Python 2023年8月4日
    058
  • AR人体姿态识别,实现无边界的人机交互

    近年来,AR不断发展,作为一种增强现实技术,给用户带来了虚拟和现实世界的融合体验。但用户已经不满足于单纯地将某件虚拟物品放在现实场景中来感受AR技术,更想用身体姿势来触发某个指令,…

    Python 2023年10月17日
    039
  • 总算给女盆友讲明白了,如何使用stream流的filter()操作

    一、引言 在上一篇文章中《这么简单,还不会使用java8 stream流的map()方法吗?》分享了使用stream的map()方法,不知道小伙伴还有印象吗,先来回顾下要点,map…

    Python 2023年10月13日
    050
  • Helm Values.yaml

    1. values.yaml 上面的内置对象中有一个对象就是 Values,该对象提供对传入 chart 的值的访问,Values 对象的值有4个来源: chart 包中的 val…

    Python 2023年8月6日
    074
  • python pytest基本使用_PYTEST入门

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。 Pytest是我首选的Python测试库。它使简单的测试非常容易编写,它拥有许多高级的…

    Python 2023年9月13日
    058
  • pandas自动创建文件夹_pandas快速入门

    pandas有两类数据对象:dataframe和series。Series是一个带标签的一维数组,通常索引在左,值在右。dataframe是一个带标签的二维数组,可以理解成seri…

    Python 2023年8月9日
    042
  • NLP学习笔记——情感分析一 (简介)

    目录 一、什么是情感分析 二、研究现状及存在问题 1、研究现状 (1). 传统情感分类方法 (2). 短文本情感分类方法 (3). 基于深度学习的方法 2、存在问题 (1). 文化…

    Python 2023年9月7日
    055
  • VGG模型-文献阅读笔记

    论文简介 该论文提出深度神经网络的深度对于大规模图像识别模型的表现有显著提升。模型使用3*3的小型卷积过滤器和较小的卷积层步幅,并且其神经网络层数达到了16-19层。基于这些发现在…

    Python 2023年10月25日
    035
  • [pandas基础]Pandas DataFrame进阶操作

    DataFrame常用属性及方法 首先创建一个DataFrame对象 import pandas as pd import numpy as np data = {‘Name’:p…

    Python 2023年8月8日
    043
  • (python)利用pip解决scrapy模块的安装问题

    pip是python社区提供给我们的一个很方便的python包管理工具(它本身也是一个包),基本上我们需要第三方模块都可以通过他一行代码解决。但现实很骨感,问题总是会出现,尤其是经…

    Python 2023年10月3日
    048
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球