主成分分析(PCA)原理及其python实现

article/2025/9/11 9:02:11

主成分分析

  • 一、概述
    • 1.1 问题提出
    • 1.2 降维的作用
  • 二、主成分分析(PCA)主要思想
  • 三、相关数学知识
  • 四、PCA实现步骤
    • 4.1 特征值分解矩阵
    • 4.2 SVD分解协方差矩阵
  • 五、python程序实现
    • 5.1 利用数学公式实现
    • 5.2 使用sklearn实现

一、概述

1.1 问题提出

在实际问题研究中,多变量问题是经常会遇到的。变量太多,无疑会增加分析问题的难度与复杂性,而且在许多实际问题中,多个变量之间是具有一定的相关关系的。因此,人们会很自然地想到,能否在相关分析的基础上, 用较少的新变量代替原来较多的旧变量,而且使这些较少的新变量尽可能多地保留原来变量所反映的信息?事实上,这种想法是可以实现的,主成分分析方法就是综合处理这种问题的一种强有力的工具。主成分分析是把原来多个变量划为少数几个综合指标的一种统计分析方法。从数学角度来看,这是一种降维处理技术。

1.2 降维的作用

降维是将高维度的数据(指标太多)保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的。在实际的生产和应用中,降维在一定的信息损失范围内,可以为我们节省大量的时间和成本。降维也成为应用非常广泛的数据预处理方法。
降维具有如下一些优点:

  1. 使得数据集更易使用;
  2. 降低算法的计算开销;
  3. 去除噪声;
  4. 使得结果容易理解。

降维的算法有很多,比如奇异值分解(SVD)、主成分分析(PCA)、因子分析(FA)、独立成分分析(ICA)。

二、主成分分析(PCA)主要思想

链接: 主成分分析(PCA)原理详解
链接:主成分数学原理

PCA的主要思想是将n维特征映射到 k k k维上,这 k k k维是全新的正交特征也被称为主成分,是在原有 n n n维特征的基础上重新构造出来的 k k k维特征。

PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到 n n n个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面 k k k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面 k k k个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。

思考:我们如何得到这些包含最大差异性的主成分方向呢?

答案:事实上,通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值特征向量,选择特征值最大(即方差最大)的k个特征所对应的特征向量组成的矩阵。这样就可以将数据矩阵转换到新的空间当中,实现数据特征的降维。

由于得到协方差矩阵的特征值特征向量有两种方法:特征值分解协方差矩阵、奇异值分解协方差矩阵,所以PCA算法有两种实现方法:基于特征值分解协方差矩阵实现PCA算法基于SVD分解协方差矩阵实现PCA算法

三、相关数学知识

方差:
最先提到的一个概念,也是旋转坐标轴的依据。之所以使用方差作为旋转条件是因为:最大方差给出了数据的最重要的信息。
var ⁡ ( X ) = ∑ i = 1 n ( X i − X ˉ ) 2 n − 1 \operatorname{var}(X)=\frac{\sum_{i=1}^{n}\left(X_{i}-\bar{X}\right)^2}{n-1} var(X)=n1i=1n(XiXˉ)2 s 2 = ∑ i = 1 n ( X i − X ˉ ) 2 n − 1 s^2=\frac{\sum_{i=1}^{n}\left(X_{i}-\bar{X}\right)^2}{n-1} s2=n1i=1n(XiXˉ)2
由方差可推出标准差: s = ∑ i = 1 n ( X i − X ˉ ) 2 n − 1 s=\sqrt {\frac{\sum_{i=1}^{n}\left(X_{i}-\bar{X}\right)^2}{n-1}} s=n1i=1n(XiXˉ)2

协方差:
用来衡量两个变量的总体误差,方差是协方差的一种特殊情况,即当两个变量相同。可以通俗的理解为:两个变量在变化过程中的方向,度量各个维度偏离其均值的程度,定义为:
cov ⁡ ( X , Y ) = ∑ i = 1 n = ( X i − X ˉ ) ( Y i − Y ˉ ) n − 1 \begin{array}{} \operatorname{cov}(X,Y)=\frac{\sum_{i=1}^{n}=(X_{i}-\bar{X})(Y_{i}-\bar{Y})}{n-1} \end{array} cov(X,Y)=n1i=1n=(XiXˉ)(YiYˉ)
由协方差的定义可以推出两个性质:
cov ⁡ ( X , X ) = var ⁡ ( X ) cov ⁡ ( X , Y ) = cov ⁡ ( Y , X ) \begin{array}{} \operatorname{cov}(X, X)=\operatorname{var}(X) \\ \operatorname{cov}(X, Y)=\operatorname{cov}(Y, X) \end{array} cov(X,X)=var(X)cov(X,Y)=cov(Y,X)
协方差矩阵:
协方差只能处理二维问题(即两个特征X、Y),维数多了自然需要计算多个协方差矩阵,以三维数据为例,协方差矩阵表示为:
C ( X , Y , Z ) = ( cov ⁡ ( x , x ) cov ⁡ ( x , y ) cov ⁡ ( x , z ) cov ⁡ ( y , x ) cov ⁡ ( y , y ) cov ⁡ ( y , z ) cov ⁡ ( z , x ) cov ⁡ ( z , y ) cov ⁡ ( z , z ) ) C(X,Y,Z)=\left(\begin{array}{} \operatorname{cov}(x, x) & \operatorname{cov}(x, y) & \operatorname{cov}(x, z) \\ \operatorname{cov}(y, x) & \operatorname{cov}(y, y) & \operatorname{cov}(y, z) \\ \operatorname{cov}(z, x) & \operatorname{cov}(z, y) & \operatorname{cov}(z, z) \end{array}\right) C(X,Y,Z)= cov(x,x)cov(y,x)cov(z,x)cov(x,y)cov(y,y)cov(z,y)cov(x,z)cov(y,z)cov(z,z)
可见,协方差矩阵是一个对称的矩阵,且对角线是各维度上的方差。正是由于协方差矩阵为对称矩阵所以矩阵分解后特征值所对应的特征向量 一定无线性关系,且相互之间一定正交,即内积为零。

方差和协方差的除数是n-1,这是为了得到方差和协方差的无偏估计。

特征值与特征向量

  1. 特征值与特征向量
    如果一个向量 v v v 是矩阵 A A A的特征向量,将一定可以表示成下面的形式:
    A v = λ v A v=\lambda v Av=λv
    其中, λ \lambda λ 是特征向量 v v v对应的特征值,一个矩阵的一组特征向量是一组正交向量(实对称阵特征向量正交)。
  2. 特征值分解矩阵
    对于矩阵 A A A ,有一组特征向量 v v v ,将这组向量进行正交化单位化,就能得到一组正交单位向量。特 征值分解,就是将矩阵 A A A分解为如下式:
    A = Q Λ Q − 1 A=Q\Lambda Q^{-1} A=QΛQ1
    其中, Q Q Q 是矩阵 A A A 的特征向量组成的矩阵, Λ \Lambda Λ 则是一个对角阵,对角线上的元素就是特征值。

SVD分解矩阵

奇异值分解是一个能适用于任意矩阵的一种分解的方法,对于任意矩阵 A A A总是存在一个奇异值分解:
A = U Λ V T A=U \Lambda V^{T} A=UΛVT
假设 A A A 是一个 m ∗ n m * n mn 的矩阵,那么得到的 U U U 是一个 m ∗ m m * m mm 的方阵,U里面的正交向量被称为左奇异向 转置矩阵,是一个 n ∗ n n * n nn 的矩阵,它里面的正交向量被称为右奇异值向量。而且一般来讲,我们会将SVD分解矩阵A的步骤:

  1. A A T A A^{T} AAT 的特征值和特征向量,用单位化的特征向量构成 U U U
  2. A T A A^{T} A ATA 的特征值和特征向量,用单位化的特征向量构成 V \mathrm{V} V
  3. A A T A A^{T} AAT 或者 A T A A^{T} A ATA 的特征值求平方根,然后构成 Λ \Lambda Λ

四、PCA实现步骤

4.1 特征值分解矩阵

输入:数据集 X = { x 1 , x 2 , x 3 , … , x n } X=\left\{x_{1}, x_{2}, x_{3}, \ldots, x_{n}\right\} X={x1,x2,x3,,xn} ,需要降到 k k k 维。

  1. 去平均值(即去中心化),即每一位特征减去各自的平均值。
  2. 计算协方差矩阵 1 n X X T \frac{1}{n} XX^T n1XXT (这里除或不除样本数量n或n-1,其实对求出的特征向量没有影响)
  3. 用特征值分解方法求协方差矩阵 1 n X X T \frac{1}{n}XX^{T} n1XXT 的特征值与特征向量。
  4. 对特征值从大到小排序,选择其中最大的 k k k 个。然后将其对应的 k k k 个特征向量分别作为行向量组 成特征向量矩阵 P P P
  5. 将数据转换到 k k k 个特征向量构建的新空间中,即 Y = P X Y=PX Y=PX

为什么数据要减去均值?
把数据中心化,减少过度拟合的可能性。
为什么选取前k个最大的特征值?
k维特征是将n维样本点转换为k维后,每一维上的样本方差都很大。特征值越大,说明矩阵在对应的特征向量上的方差越大,样本点越离散,越容易区分,信息量也就越多。因此,特征值最大的对应的特征向量方向上所包含的信息量就越多,如果某几个特征值很小,那么就说明在该方向的信息量非常少,我们就可以删除小特征值对应方向的数据,只保留大特征值方向对应的数据,这样做以后数据量减小,但有用的信息量都保留下来了。
在n维中选多少个k最合适?
研究表明,所选的主轴总长度占所有主轴长度之和的大约 85 % 85 \% 85% 即可如下图公式。
∑ i = 1 k λ i ∑ i = 1 n λ i \frac{\sum_{i=1}^{k} \lambda_{i}}{\sum_{i=1}^{n} \lambda_{i}} i=1nλii=1kλi n n n 为样本数, k k k 为我们选的维数。

计算过程
此处参考数学建模清风老师课件

假设有 n n n 个样本, p p p 个指标, 则可构成大小为 n × p n \times p n×p 的样本矩阵 x x 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=\left[\begin{array}{cccc} x_{11} & x_{12} & \cdots & x_{1 p} \\ x_{21} & x_{22} & \cdots & x_{2 p} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n 1} & x_{n 2} & \cdots & x_{n p} \end{array}\right]=\left(x_{1}, x_{2}, \cdots, x_{p}\right) x= x11x21xn1x12x22xn2x1px2pxnp =(x1,x2,,xp)

  1. 我们首先对其进行去中心:
    按列计算均值 x ˉ j = 1 n ∑ i = 1 n x i j \bar x_{j}=\frac{1}{n} \sum_{i=1}^{n} x_{i j} xˉj=n1i=1nxij 计算得 去中心化数据 X i j = x i j − x ˉ j X_{i j}={x_{i j}-\bar x_{j}} Xij=xijxˉj, 原始样本矩阵经过去中心化变为:
    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=\left[\begin{array}{} X_{11} & X_{12} & \cdots & X_{1 p} \\ X_{21} & X_{22} & \cdots & X_{2 p} \\ \vdots & \vdots & \ddots & \vdots \\ X_{n 1} & X_{n 2} & \cdots & X_{n p} \end{array}\right]=\left(X_{1}, X_{2}, \cdots, X_{p}\right) X= X11X21Xn1X12X22Xn2X1pX2pXnp =(X1,X2,,Xp)
  2. 计算处理样本的协方差矩阵
    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=\left[\begin{array}{} r_{11} & r_{12} & \cdots & r_{1 p} \\ r_{21} & r_{22} & \cdots & r_{2 p} \\ \vdots & \vdots & \ddots & \vdots \\ r_{p 1} & r_{p 2} & \cdots & r_{p p} \end{array}\right] R= r11r21rp1r12r22rp2r1pr2prpp
    其中 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 r_{i j}=\frac{1}{n-1} \sum_{k=1}^{n}\left(X_{k i}-\bar{X_{i}}\right)\left(X_{k j}-\bar{X_{j}}\right)=\frac{1}{n-1} \sum_{k=1}^{n} X_{k i} X_{k j} rij=n11k=1n(XkiXiˉ)(XkjXjˉ)=n11k=1nXkiXkj
    (注意: 如果进行标准化处理,上面 12 两步可直接合并为一步:直接计算 x x x 矩阵的样本相关系数矩阵)
    R = ∑ k = 1 n ( x k i − x i ˉ ) ( x k j − x j ˉ ) ∑ k = 1 n ( x k i − x i ˉ ) 2 ∑ k = 1 n ( x k j − x j ˉ ) 2 R=\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}}} R=k=1n(xkixiˉ)2k=1n(xkjxjˉ)2 k=1n(xkixiˉ)(xkjxjˉ)
  3. 计算 R \boldsymbol{R} R 的特征值和特征向量
    特征值: λ 1 ≥ λ 2 ≥ ⋯ ≥ λ p ≥ 0 \lambda_{1} \geq \lambda_{2} \geq \cdots \geq \lambda_{p} \geq 0 \quad λ1λ2λp0 R R R是半正定矩阵, 且 tr ⁡ ( R ) = ∑ k = 1 p λ k = p ) \left.\operatorname{tr}(R)=\sum_{k=1}^{p} \lambda_{k}=p\right) tr(R)=k=1pλk=p)
    特征向量: a 1 = [ a 11 a 21 ⋮ a p 1 ] , a 2 = [ a 12 a 22 ⋮ a p 2 ] , ⋯ , a p = [ a 1 p a 2 p ⋮ a p p ] a_{1}=\left[\begin{array}{c}a_{11} \\ a_{21} \\ \vdots \\ a_{p 1}\end{array}\right], a_{2}=\left[\begin{array}{c}a_{12} \\ a_{22} \\ \vdots \\ a_{p 2}\end{array}\right], \cdots, a_{p}=\left[\begin{array}{c}a_{1 p} \\ a_{2 p} \\ \vdots \\ a_{p p}\end{array}\right] a1= a11a21ap1 ,a2= a12a22ap2 ,,ap= a1pa2papp
  4. 计算主成分贡献率以及累计贡献率
    贡献率 = λ i ∑ k = 1 p λ k ( i = 1 , 2 , ⋯ , p ) =\frac{\lambda_{i}}{\sum_{k=1}^{p} \lambda_{k}}(i=1,2, \cdots, p) \quad =k=1pλkλi(i=1,2,,p) 累计贡献率 = ∑ k = 1 i λ k ∑ k = 1 p λ k ( i = 1 , 2 , ⋯ , p ) =\frac{\sum_{k=1}^{i} \lambda_{\mathrm{k}}}{\sum_{k=1}^{p} \lambda_{k}}(i=1,2, \cdots, p) =k=1pλkk=1iλk(i=1,2,,p)
  5. 写出主成分
    一般取累计贡献率超过 85 % 85 \% 85% 的特征值所对应的第一、第二、 ⋯ \cdots m ( m ⩽ p ) m(m \leqslant p) m(mp) 个主成分。
    i i i 个主成分: F i = a 1 i X 1 + a 2 i X 2 + ⋯ + a p i X p ( i = 1 , 2 , ⋯ , m ) F_{i}=a_{1 i} X_{1}+a_{2 i} X_{2}+\cdots+a_{p i} X_{p} \quad(i=1,2, \cdots, m) Fi=a1iX1+a2iX2++apiXp(i=1,2,,m)
  6. 根据系数分析主成分代表的意义
    对于某个主成分而言, 指标前面的系数越大, 代表该指标对于该主成分的影响越大。
  7. 利用主成分的结果进行后续的分析
    (1) 主成分得分:可用于评价类模型吗? (千万别用!!!)
    (2) 主成分可用于聚类分析(方便画图)
    (3) 主成分可用于回归分析

4.2 SVD分解协方差矩阵

输入: 数据集 X = { x 1 , x 2 , x 3 , … , x n } X=\left\{x_{1}, x_{2}, x_{3}, \ldots, x_{n}\right\} X={x1,x2,x3,,xn} ,需要降到 k k k维。

  1. 去平均值,即每一位特征減去各自的平均值。
  2. 计算协方差矩阵。
  3. 通过SVD计算协方差矩阵的特征值与特征向量。
  4. 对特征值从大到小排序,选择其中最大的k个。然后将其对应的k个特征向量分别作为列向量組 成特征向量矩阵。
  5. 将数据转换到 k \mathrm{k} k 个特征向量构建的新空间中。

在PCA降维中,我们需要找到样本协方差矩阵 X X T X X^{T} XXT 的最大 k \mathrm{k} k 个特征向量,然后用这最大的 k \mathrm{k} k 个特 征向量组成的矩阵来做低维投影降维。可以看出,在这个过程中需要先求出协方差矩阵 X X T X X^{T} XXT, 当样本数多、样本特征数也多的时候,这个计算还是很大的。当我们用到SVD分解协方差矩阵的时候,SVD有两个好处:

  1. 有一些SVD的实现算法可以先不求出协方差矩阵 X X T X X^{T} XXT 也能求出我们的右奇异矩阵 V \mathrm{V} V 。也就是说,我们的PCA算法可以不用做特征分解而是通过SVD来完成,这个方法在样本量很大的时候很有效。实际上,scikit-learn的PCA算法的背后真正的实现就是用的SVD,而不是特征值分解。
  2. 注意到PCA仅仅使用了我们SVD的左奇异矩阵,没有使用到右奇异值矩阵,那么右奇异值矩阵有 什么用呢?
    假设我们的样本是 m ∗ n \mathrm{m} * \mathrm{n} mn 的矩阵X,如果我们通过SVD找到了矩阵 X T X X^{T} X XTX 最大的 k \mathrm{k} k 个特征向量组成的 k ∗ n \mathrm{k}^{*} \mathrm{n} kn 的矩阵 V T V^{T} VT,则我们可以做如下处理:
    X m ∗ k ′ = X m ∗ n V n ∗ k T X_{m * k}^{\prime}=X_{m * n} V_{n * k}^{T} Xmk=XmnVnkT
    可以得到一个 m ∗ k m * k mk 的矩阵 X ′ X^{\prime} X, , 文个矩阵和我们原来 m ∗ n m * n mn 的矩阵 X X X 相比,列数从 n n n 減到了 k k k ,可见对列数

五、python程序实现

5.1 利用数学公式实现

  1. 部分数据
32.502345269453031,31.70700584656992
53.426804033275019,68.77759598163891
61.530358025636438,62.562382297945803
47.475639634786098,71.546632233567777
59.813207869512318,87.230925133687393
55.142188413943821,78.211518270799232
52.211796692214001,79.64197304980874
39.299566694317065,59.171489321869508
48.10504169176825,75.331242297063056
52.550014442733818,71.300879886850353
45.419730144973755,55.165677145959123
54.351634881228918,82.478846757497919
44.164049496773352,62.008923245725825
58.16847071685779,75.392870425994957
56.727208057096611,81.43619215887864
48.955888566093719,60.723602440673965
44.687196231480904,82.892503731453715
60.297326851333466,97.379896862166078
45.618643772955828,48.847153317355072
38.816817537445637,56.877213186268506
66.189816606752601,83.878564664602763
65.41605174513407,118.59121730252249
47.48120860786787,57.251819462268969
41.57564261748702,51.391744079832307
51.84518690563943,75.380651665312357
59.370822011089523,74.765564032151374
57.31000343834809,95.455052922574737
63.615561251453308,95.229366017555307
  1. 第一种实现方式(去中心化)
import numpy as np
import matplotlib.pyplot as pltdata = np.genfromtxt("data.csv", delimiter=',')
x_data = data[:, 0]
y_data = data[:, 1]plt.scatter(x_data, y_data)# 数据中心化
def zeroMean(dataMat):# 按列求平均,及几个特征的平均meanval = np.mean(dataMat, axis=0)newData = dataMat - meanvalreturn newData, meanvalnewData, meanval = zeroMean(data)
print(newData)
# 协方差矩阵生成,n个变量,生成n*n矩阵
covMat = np.cov(newData, rowvar=False)
# 计算特征值、特征向量
eigvals, eigvects = np.linalg.eig(covMat)
print("特征值:\n",eigvals,"\n特征向量:\n",eigvects)
# 对特征值从大到小排序 np.argsort(a)从小到大排序 -a为从大到小排序
eigvalindice = np.argsort(-eigvals)
# 最大的1个特征值的下标
n_eigvalindice = eigvalindice[:1]    # 返回[1]# 最大的特征值对应的特征向量   n_eigVect[1]
n_eigVect = eigvects[:, n_eigvalindice]
print("最大特征值对应特征向量:\n",n_eigVect)
# 低维特征空间的数据
# np.dot()函数主要有两个功能,向量点积和矩阵乘法
lowDDataMat = np.dot(newData, n_eigVect)
print(lowDDataMat,lowDDataMat.shape)
# 利用低纬度数据来重构数据
reconMat = np.dot(lowDDataMat, n_eigVect.T) +meanval # (100,2)x_data = np.array(reconMat)[:, 0]
y_data = np.array(reconMat)[:, 1]
plt.scatter(x_data, y_data, c='b')plt.savefig("PCA降维.png")
plt.show()

结果显示:
在这里插入图片描述

  1. 第二种实现方式(标准化)
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing# 导入数据集
data = np.genfromtxt("data_1.csv", delimiter=',')
data = data[1:, :]
print(data)
# 标准化
new_data = preprocessing.scale(data)# 求相关系数矩阵   相关系数为行变量
covX = np.around(np.corrcoef(new_data.T), decimals=3)# 求解特征值、特征变量
featValue, featVec = np.linalg.eig(covX)
print("特征值:\n",featValue,"\n特征向量:\n",featVec)
# 降序排列
# featValue = sorted(featValue, reverse=True)
# [::-1] 顺序相反操作
featValue = sorted(featValue)[::-1]
print("特征值降序排列:\n",featValue)
# 绘制散点图与折线图
plt.scatter(range(1, data.shape[1] + 1), featValue)
plt.plot(range(1, data.shape[1] + 1), featValue)
plt.title("Scree Plot")
plt.xlabel("Factors")
plt.ylabel("Eigenvalue")
plt.savefig("Factors")plt.grid()
plt.show()
# 求特征值的贡献度
gx = featValue / np.sum(featValue)
print("特征值的贡献度:\n",gx)
# 累计贡献度
lg = np.cumsum(gx)
print("累计贡献度\n",lg)
plt.scatter(range(1, data.shape[1] + 1), lg)
plt.plot(range(1, data.shape[1] + 1), lg)
plt.axhline(y=0.85, c='r', xmin=0.1, xmax=0.9)
plt.text(1,0.86,"水平线")
plt.savefig("累计贡献度")
# 选出主成分对应下标
k = [i for i in range(len(lg)) if lg[i] < 0.85]
print("主成分对应下标\n",k)
# 选出主成分对应的特征向量
Vec = featVec.T[k].T
print("主成分对应的特征向量\n",Vec)
# 降维新数据
finalData = np.dot(new_data, Vec)
print("低维数据:\n",finalData)
plt.figure(figsize=(14, 14))ax = sns.heatmap(Vec, annot=True, cmap="BuPu")
# 设置y轴字体大小
ax.yaxis.set_tick_params(labelsize=15)
plt.title("Factor Analysis", fontsize="xx-large")# 设置y轴标签
plt.ylabel("Sepal Width", fontsize="xx-large")
# 保存图片
plt.savefig("factorAnalysis", dpi=500)
# 显示图片
plt.show()

特征值:
在这里插入图片描述
累计贡献度:
在这里插入图片描述
特征向量:
在这里插入图片描述

5.2 使用sklearn实现

一、参数说明 (Parameters)

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)
  1. n_components: int, float, None or str
    意义 :代表返回的主成分的个数,也就是你想把数据降到几维
    n_components = 2 =2 =2 代表返回前 2 个主成分
    0 < 0< 0< n_components <1代表满足最低的主成分方差男计贡献率
    n_components = 0.98 =0.98 =0.98 ,指返回满足主成分方差男计贡献率达到 98 % 98 \% 98% 的主成分
    n_components=None,返回所有主成分
    n − \mathrm{n}_{-} ncomponents=‘mle’,将自动选取主成分个数 n n n ,使得满足所要求的方差百分比
  2. copy: bool类型, False/True 默认是True
    意义:在运行的过程中,是否将原数据复制。由于你在运行的过程中,是在降维,数据会变动。
    这copy主要影响的是,调用显示降维后的数据的方法不同。
    copy=True时,直接 fit_transform (X),就能够显示出降维后的数据。
    copy=False时,需要 fit (X).transform (X) ,才能够显示出降维后的数据。
    (fit_transform()方法后面会讲到!)
  3. whiten: bool类型,False/True 默认是False
    意义:白化。白化是一种重要的预处理过程,其目的就是降低输入数据的冗余性,使得经过白化处理的输入数据具有如下性质:(i)特征之间相关性较低;(ii)所有特征具有相同的方差。
  4. svd_solver: str类型,str {‘auto’, ‘full’, ‘arpack’, ‘randomized’}
    意义:定奇异值分解 SVD 的方法。
    svd_solver=auto:PCA 类自动选择下述三种算法权衡。
    svd_solver= ‘full’:传统意义上的 SVD,使用了 scipy 库对应的实现。
    svd_solver=‘arpack’:直接使用 scipy 库的 sparse SVD 实现,和 randomized 的适用场景类似。
    svd_solver=‘randomized’:适用于数据量大,数据维度多同时主成分数目比例又较低的 PCA 降维。

二、属性 (Attributes)

  1. components_: 返回最大方差的主成分。
  2. explained_variance_: 它代表降维后的各主成分的方差值。方差值越大,则说明越是重要的主成分。
  3. explained_variance_ratio_: 它代表降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。(主成分方差贡献率)
  4. singular_values_: 返回所被选主成分的奇异值。
    实现降维的过程中,有两个方法,一种是用特征值分解,另一种用奇异值分解,前者限制比较多,需要矩阵是方阵,而后者可以是任意矩
    阵,而且计算量比前者少,所以说一般实现 P C A P C A PCA 都是用奇异值分解的方式。
  5. mean_: 每个特征的经验平均值,由训练集估计。
  6. n_features_: 训练数据中的特征数。
  7. n_samples_: 训练数据中的样本数量。
  8. noise_variance_: 噪声协方差

三、方法 (Methods)

  1. fit(self, X,Y=None) 模型训练,由于PCA是无监督学习,所以Y=None,没有标签
  2. fit_transform(self, X , Y = X, Y= X,Y= None):将模型与X进行训练,并对X进行降维处理,返回的是降维后的数据。
  3. get_covariance(self) 获得协方差数据
  4. get_params(self,deep = = = True) 返回模型的参数
  5. get_precision(self) 计算数据精度矩阵 ( 用生成模型)
  6. inverse_transform(self, X) 将降维后的数据转换成原始数据,但可能不会完全一样
  7. score(self, X, Y= None) 计算所有样本的log似然平均值
  8. transform(X) 将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。
# 用sklearn的PCA
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
data = np.genfromtxt("data.csv",delimiter=",")
plt.scatter(data[:,0],data[:,1],c="b")
plt.show()
# pca = PCA(n_components=2,whiten=True)   whiten=True标准化
pca=PCA(n_components=1)
pca.fit(data)
main_var = pca.explained_variance_  # 特征值
print(main_var)
pca_data = pca.transform(data)
print(pca_data)

sklearn降维部分结果显示:

[-44.02694787][ -1.49722533][ -3.35564513][ -1.73205523][ 17.84406034][  7.68710859][  7.6311404 ][-16.4703207 ][  1.92574891][  0.35289859][-17.26071108][ 11.13030667][-11.73358623][  6.54975245][ 11.27989566][-10.70315359][  7.11092921][ 27.10646295][-22.80011879]

sklearn中的PCA是通过svd_flip函数实现的,sklearn对奇异值分解结果进行了一个处理,因为 u i ∗ σ i ∗ v i = ( − u i ) ∗ σ i ∗ ( − v i ) u_i*σ_i*v_i=(-u_i)*σ_i*(-v_i) uiσivi=(ui)σi(vi),也就是 u u u v v v同时取反得到的结果是一样的,而这会导致通过PCA降维得到不一样的结果(虽然都是正确的)。

本文为学习过程记录,难免出现错误,欢迎指正。


http://chatgpt.dhexx.cn/article/lTAQlSZZ.shtml

相关文章

核酸扫码登记体验有感(如何提高OCR的文字正确识别率)

近几年&#xff0c;新冠疫情持续反复&#xff0c;核酸检测已成为了我们日常生活的一部分&#xff0c;甚至有人开玩笑说朋友邻居见面问候语从“吃了吗你&#xff1f;”变成了“今儿核酸了&#xff1f;”。核酸检测全员常态化&#xff0c;需要大量的志愿者协助医生进行身份证扫描…

ORB-SLAM2 特征点法SLAM 单目 双目 rgbd相机SLAM 单应/本质矩阵恢复运动 小图大图地图优化

ORB-SLAM2 ORB特征点法SLAM 支持单目、双目、rgbd相机 安装测试 本文github链接 orbslam2 imu ORB-SLAM是一个基于特征点的实时单目SLAM系统&#xff0c;在大规模的、小规模的、室内室外的环境都可以运行。 该系统对剧烈运动也很鲁棒&#xff0c;支持宽基线的闭环检测和重…

opencv4算法库学习笔记(5万多字超长干货——纪念奋战的自己)

整理于2020年初三个月的日夜积累。。。 参考链接 opencv安装 安装脚本链接&#xff1a;https://github.com/milq/milq/blob/master/scripts/bash/install-opencv.sh 源码编译安装参考&#xff1a;https://blog.csdn.net/liuli2008212/article/details/128169266?spm1001.2…

【数字图像处理课程设计】期中、期末综合考试题目整理总结(共四个图像处理算法应用题)

目录 一、下面两幅图像中有几处不同&#xff0c;编程把它们找出来、并在图中突出显示&#xff08;关键步骤不能调用内置函数&#xff09;。 1.算法原理 2.解题步骤 3.程序代码 4.处理结果 二、下图含有干扰条纹&#xff08;moir pattern&#xff09;、并且低灰度区域的细…

MATLAB各个产品概述----哪些产品需要安装?哪些产品不需要安装?阅完了然

MATLAB产品概述 文章目录 1 MATLAB2 Simulink3 5G Toolbox&#xff08;5G工具箱&#xff09;4 Aerospace Blockset&#xff08;航空区块集&#xff09;5 Aerospace Toolbox&#xff08;航空航天工具箱&#xff09;6 Antenna Toolbox&#xff08;天线工具箱&#xff09;7 Audio…

Latex相关符号

函数、符号及特殊字符 声调 语法效果语法效果语法效果\bar{x}\acute{\eta}\check{\alpha}\grave{\eta}\breve{a}\ddot{y}\dot{x}\hat{\alpha}\tilde{\iota} 函数 语法效果语法效果语法效果\sin\theta\cos\theta\tan\theta\arcsin\frac{L}{r}\arccos\frac{T}{r}\arctan\frac{L…

一文读懂人脸识别技术

2019-08-27 17:06:26 本文内容涵盖人脸识别发展历程、市场研究、核心技术、商业应用以及产业落地、个人看法等干货研究。注意&#xff0c;本文干货满满&#xff0c;约有2万7千字&#xff0c;强烈建议大家先收藏后学习&#xff01; 01 发展史 1. 人脸识别的理解 人脸识别(Fa…

综述 | 基于特征的视觉同步定位和建图

点击上方“计算机视觉工坊”&#xff0c;选择“星标” 干货第一时间送达 Feature‑based visual simultaneous localization and mapping: a survey Rana Azzam1 Tarek Taha2 Shoudong Huang3 Yahya Zweiri4 接收日期&#xff1a;2019 年 10 月 30 日/接受时间&#xff1a;…

ORB_SLAM2 源码解析 单目初始化器Initializer(三)

目录 一、地图点初始化 二、重新记录特征点的匹配关系 1、构建旋转直方图 1.1、在半径窗口内搜索当前帧F2中所有的候选匹配特征点GetFeaturesInArea 1.2、表示一个图像像素相当于多少个图像网格列和行 1.4、遍历圆形区域内的所有网格&#xff0c;寻找满足条件的候选特征点&…

Zotero文献管理软件使用指南——入门篇

一、安装与注册 zotero下载地址 二、文献导入 2.1 方法一&#xff1a;Zoreto Connector插件 2.1.1 下载插件 还是刚刚那个网址&#xff0c;点击红色方框下载插件。 下载完成之后浏览器上方会有如下图所示的小图标 2.1.2 导入举例 以知网为例 找到你想看的…

【EndNote】功能强大的文献管理软件

EndNote X9是一款功能强大的文献管理软件,使用这款EndNote X9破解版可以让你直接将其安装到Windows操作系统上使用,如果您正需要这款免费版工具,马上下载EndNote X9使用吧。 基本简介 EndNote 是一款主流文献管理软件&#xff0c;有数以百万计的研究人员、学生和图书管理员使用…

文献管理软件Zotero配置及使用

文献管理软件-Zotero常用插件安装及配置使用 一、Zotero安装与同步盘配置 1、下载Zotero并安装2、配置Zotero &#xff08;1&#xff09;配置同步盘&#xff08;以onedrive为例&#xff09;——如果不配置同步盘&#xff0c;这一步可以跳过&#xff08;2&#xff09;配置输出文…

文献管理软件//Zotero导入文献的五种方式(九)

Zotero导入文献的五种方式 一、利用zotero插件自动获取pdf文件二、利用DOI获取pdf文件三、从剪贴板导入pdf文件3.1 导入单篇文献3.2 导入多篇文献 四、利用endnote格式导入文献五、通过已下载的PDF文件导入文献 一、利用zotero插件自动获取pdf文件 首先&#xff0c;可以通过以…

文献管理软件Mendeley基本使用教程

一、文献管理软件 文献管理软件是学者或者作者用于记录、组织、调阅引用文献的计算机程序&#xff0c;其便利之处在于&#xff1a; 1.直接联网不同数据库进行文献检索&#xff0c;提高效率&#xff1b; 2.方便快捷管理文献信息&#xff0c;包括文摘、全文、笔记记录、以及其…

文献管理软件Zotero常用插件安装及配置使用

文献管理软件-Zotero常用插件安装及配置使用 一、Zotero安装与同步盘配置1、下载Zotero并安装2、配置Zotero&#xff08;1&#xff09;配置同步盘&#xff08;以onedrive为例&#xff09;——如果不配置同步盘&#xff0c;这一步可以跳过&#xff08;2&#xff09;配置输出文献…

文献管理软件zotero|电脑和平板文献管理实现同步

高效管理文献——实现PC和ipad同步 作为一个科研打工人&#xff0c;读论文是我们每个人基本天天都要做的事&#xff0c;但论文越来越多如何实现论文高效管理&#xff1f;利用文献管理软件zotero&#xff0c;能实现高效管理文献。 之前也用过&#xff0c;mendeley软件也用过&a…

科研必备文献管理软件EndNote

什么是ENDNOTE&#xff1f; Endnote是一款被广泛使用的文献管理软件&#xff0c;其是SCI&#xff08;Thomson Scientific 公司&#xff09;的官方软件&#xff0c;支持国际期刊的参考文献格式有3776 种【也可以自定义期刊引用格式】。 软件非常方便科研狗进行文献整理&#xf…

四款主流文献管理软件,总有一款适合你

本文作者&#xff1a;生信不是人学的 看文献是每个科研人都必须做的事情 但随着阅读量的增加&#xff0c;面对几十甚至上百篇文献&#xff0c;单纯靠自己的记忆来整理文献是一件不太可能的事情。 因此需要一款合适的软件来帮助我们进行文献管理&#xff0c;提高科研效率。 接下…

如何让vim编辑器永久显示行号

在Linux环境下的编辑器有vi、vim、gedit等等。进入这些编辑器之后&#xff0c;为了方便我们需要编辑器显示出当前的行号&#xff0c;可偏偏编辑器默认是不会显示行号的。我们有二种办法可以解决&#xff1a; 第一种是&#xff0c;手动显示&#xff1a;在vim命令行模式下输入 …

【LINUX-vim命令】设置vim显示行号

【vim命令】设置vim显示行号 linux环境下&#xff0c;使用vim查看或编辑文件&#xff0c;vim打开的文件默认是不显示行号的&#xff0c;问题&#xff1a;怎么才能让vim打开的文件显示行号呢&#xff1f; 1. 临时显示行号 set number2. 永久显示行号 # 打开 /etc/vimrc文件 vi…