主成分分析

  • 一、概述
    • 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维特征映射到kkk维上,这kkk维是全新的正交特征也被称为主成分,是在原有nnn维特征的基础上重新构造出来的kkk维特征。

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

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

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

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

三、相关数学知识

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

协方差:
用来衡量两个变量的总体误差,方差是协方差的一种特殊情况,即当两个变量相同。可以通俗的理解为:两个变量在变化过程中的方向,度量各个维度偏离其均值的程度,定义为:
cov⁡(X,Y)=∑i=1n=(Xi−Xˉ)(Yi−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)=n−1∑i=1n​=(Xi​−Xˉ)(Yi​−Yˉ)​​
由协方差的定义可以推出两个性质:
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. 特征值与特征向量
    如果一个向量 vvv 是矩阵AAA的特征向量,将一定可以表示成下面的形式:
    Av=λvA v=\lambda v Av=λv
    其中, λ\lambdaλ 是特征向量vvv对应的特征值,一个矩阵的一组特征向量是一组正交向量(实对称阵特征向量正交)。
  2. 特征值分解矩阵
    对于矩阵 AAA ,有一组特征向量 vvv ,将这组向量进行正交化单位化,就能得到一组正交单位向量。特 征值分解,就是将矩阵AAA分解为如下式:
    A=QΛQ−1A=Q\Lambda Q^{-1} A=QΛQ−1
    其中, QQQ 是矩阵 AAA 的特征向量组成的矩阵, Λ\LambdaΛ 则是一个对角阵,对角线上的元素就是特征值。

SVD分解矩阵

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

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

四、PCA实现步骤

4.1 特征值分解矩阵

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

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

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

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

假设有 nnn 个样本, ppp 个指标, 则可构成大小为 n×pn \times pn×p 的样本矩阵 xxx :
x=[x11x12⋯x1px21x22⋯x2p⋮⋮⋱⋮xn1xn2⋯xnp]=(x1,x2,⋯,xp)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=⎣⎡​x11​x21​⋮xn1​​x12​x22​⋮xn2​​⋯⋯⋱⋯​x1p​x2p​⋮xnp​​⎦⎤​=(x1​,x2​,⋯,xp​)

  1. 我们首先对其进行去中心:
    按列计算均值 xˉj=1n∑i=1nxij\bar x_{j}=\frac{1}{n} \sum_{i=1}^{n} x_{i j}xˉj​=n1​∑i=1n​xij​ 计算得 去中心化数据 Xij=xij−xˉjX_{i j}={x_{i j}-\bar x_{j}}Xij​=xij​−xˉj​, 原始样本矩阵经过去中心化变为:
    X=[X11X12⋯X1pX21X22⋯X2p⋮⋮⋱⋮Xn1Xn2⋯Xnp]=(X1,X2,⋯,Xp)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=⎣⎡​X11​X21​⋮Xn1​​X12​X22​⋮Xn2​​⋯⋯⋱⋯​X1p​X2p​⋮Xnp​​⎦⎤​=(X1​,X2​,⋯,Xp​)
  2. 计算处理样本的协方差矩阵
    R=[r11r12⋯r1pr21r22⋯r2p⋮⋮⋱⋮rp1rp2⋯rpp]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=⎣⎡​r11​r21​⋮rp1​​r12​r22​⋮rp2​​⋯⋯⋱⋯​r1p​r2p​⋮rpp​​⎦⎤​
    其中 rij=1n−1∑k=1n(Xki−Xiˉ)(Xkj−Xjˉ)=1n−1∑k=1nXkiXkjr_{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​=n−11​∑k=1n​(Xki​−Xi​ˉ​)(Xkj​−Xj​ˉ​)=n−11​∑k=1n​Xki​Xkj​
    (注意: 如果进行标准化处理,上面 12 两步可直接合并为一步:直接计算 xxx 矩阵的样本相关系数矩阵)
    R=∑k=1n(xki−xiˉ)(xkj−xjˉ)∑k=1n(xki−xiˉ)2∑k=1n(xkj−xjˉ)2R=\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​(xki​−xi​ˉ​)2∑k=1n​(xkj​−xj​ˉ​)2​∑k=1n​(xki​−xi​ˉ​)(xkj​−xj​ˉ​)​
  3. 计算 R\boldsymbol{R}R 的特征值和特征向量
    特征值: λ1≥λ2≥⋯≥λp≥0\lambda_{1} \geq \lambda_{2} \geq \cdots \geq \lambda_{p} \geq 0 \quadλ1​≥λ2​≥⋯≥λp​≥0 RRR是半正定矩阵, 且 tr⁡(R)=∑k=1pλk=p)\left.\operatorname{tr}(R)=\sum_{k=1}^{p} \lambda_{k}=p\right)tr(R)=∑k=1p​λk​=p)
    特征向量: a1=[a11a21⋮ap1],a2=[a12a22⋮ap2],⋯,ap=[a1pa2p⋮app]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​=⎣⎡​a11​a21​⋮ap1​​⎦⎤​,a2​=⎣⎡​a12​a22​⋮ap2​​⎦⎤​,⋯,ap​=⎣⎡​a1p​a2p​⋮app​​⎦⎤​
  4. 计算主成分贡献率以及累计贡献率
    贡献率 =λi∑k=1pλ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=1iλk∑k=1pλ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​λk​∑k=1i​λk​​(i=1,2,⋯,p)
  5. 写出主成分
    一般取累计贡献率超过 85%85 \%85% 的特征值所对应的第一、第二、 ⋯\cdots⋯ 第 m(m⩽p)m(m \leqslant p)m(m⩽p) 个主成分。
    第 iii 个主成分: Fi=a1iX1+a2iX2+⋯+apiXp(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​=a1i​X1​+a2i​X2​+⋯+api​Xp​(i=1,2,⋯,m)
  6. 根据系数分析主成分代表的意义
    对于某个主成分而言, 指标前面的系数越大, 代表该指标对于该主成分的影响越大。
  7. 利用主成分的结果进行后续的分析
    (1) 主成分得分:可用于评价类模型吗? (千万别用!!!)
    (2) 主成分可用于聚类分析(方便画图)
    (3) 主成分可用于回归分析

4.2 SVD分解协方差矩阵

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

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

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

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

五、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}_{-}n−​components=‘mle’,将自动选取主成分个数 nnn ,使得满足所要求的方差百分比
  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_: 返回所被选主成分的奇异值。
    实现降维的过程中,有两个方法,一种是用特征值分解,另一种用奇异值分解,前者限制比较多,需要矩阵是方阵,而后者可以是任意矩
    阵,而且计算量比前者少,所以说一般实现 PCAP C APCA 都是用奇异值分解的方式。
  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对奇异值分解结果进行了一个处理,因为ui∗σi∗vi=(−ui)∗σi∗(−vi)u_i*σ_i*v_i=(-u_i)*σ_i*(-v_i)ui​∗σi​∗vi​=(−ui​)∗σi​∗(−vi​),也就是uuu和vvv同时取反得到的结果是一样的,而这会导致通过PCA降维得到不一样的结果(虽然都是正确的)。

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

主成分分析(PCA)原理及其python实现相关推荐

  1. 主成分分析(PCA)原理分析Python实现

    目录 1 引言 2 PCA的意义 3 PCA的实现步骤 4 弄懂PCA要回答的问题 5 PCA原理 5.1 如何降维? 5.2 如何量化投影以后样本点之间的区分度? 5.3 求取k维坐标系 5.3.1 ...

  2. python解析原理_主成分分析法原理及其python实现

    主成分分析法原理及其python实现 前言: 这片文章主要参考了Andrew Ng的Machine Learning课程讲义,我进行了翻译,并配上了一个python演示demo加深理解. 本文主要介绍 ...

  3. 主成分分析(PCA)原理及推导

    转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/42264479 什么是PCA? 在数据挖掘或者图像处理等领域经常会用到主成分分 ...

  4. 主成分分析(PCA)原理及R语言实现及分析实例

    主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分.最近我们被客户要求撰写关于主成分分析(PCA)的研究报告,包括一些图形和统计输出.例如,使 ...

  5. 基于特征向量的主成分分析(PCA)原理解释

    引子 首先看一下如何对一维向量的进行分解,我们知道,一个 nnn 维向量 aaa 可以由 nnn 个正交向量线性 vi,i=1,2,...,nv_i,i=1,2,...,nvi​,i=1,2,..., ...

  6. 清风数学建模学习笔记——主成分分析(PCA)原理详解及案例分析

    主成分分析   本文将介绍主成分分析(PCA),主成分分析是一种降维算法,它能将多个指标转换为少数几个主成分,这些主成分是原始变量的线性组合,且彼此之间互不相关,其能反映出原始数据的大部分信息. 一般 ...

  7. 图解主成分分析PCA算法(附Python实现)

    0 写在前面 机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用."深"在详细推导算法模型背后的数学原理:"广"在分析多个机器学习模型:决策树.支持 ...

  8. pca主成分分析结果解释_主成分分析(PCA)原理精讲 | 统计学专题

    引言:当数据维度较高时,我们很难通过普通的方法做图,更不能分析样本间的关系.故我们接下来学习降维度.可视化的主成分分析(Principal Component Analysis,PCA). 1.何时使 ...

  9. 主成分分析PCA简介及其python实现

    主成分分析(principal component analysis)是一种常见的数据降维方法,其目的是在"信息"损失较小的前提下,将高维的数据转换到低维,从而减小计算量. PCA ...

  10. 主成分分析(PCA)原理详解_转载

    一.PCA简介 1. 相关背景 在许多领域的研究与应用中,往往需要对反映事物的多个变量进行大量的观测,收集大量数据以便进行分析寻找规律.多变量大样本无疑会为研究和应用提供了丰富的信息,但也在一定程度上 ...

最新文章

  1. 【Python】安利 3 个 pandas 数据探索分析神器!
  2. OpenGL渲染纹理和平面反射
  3. python中parse是什么_python中的configparse学习笔记
  4. win2008的搜索功能就是个鸡肋
  5. Visual Studio 2005中编译调试新功能
  6. html链接txt文件,怎么在TXT文件中建立超链接
  7. 判断字符串是不是application/x-www-form-urlencoded字符串(URL编码格式的字符串)
  8. C++中的继承与虚函数各种概念
  9. 挑战程序设计竞赛_我系首次参加第六届中国大学生程序设计竞赛网络预选赛
  10. Spring.Net---4、IoC/DI注入方式
  11. linux c 网络编程与信号量,linux网络编程-----线程同步--信号量
  12. php与数据库编码格式转码,php 数据库 中文转码
  13. 深度学习难?学完它,拿高薪绝对不是问题
  14. 关于未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序的解决办法
  15. 水经注万能地图下载器如何导出透明TIF标签
  16. 红米10X/Pro/Note8Pro/Note9/K30U解账户锁详细刷机教程-可登小米账号
  17. Git Error---bad signature 0x00000000 index file corrupt
  18. 不做自了汉,大家好才是真的好
  19. Markdown中图片左对齐
  20. 投影坐标系的shp数据,如何获取到它地理坐标系下的经纬度坐标

热门文章

  1. IE浏览器的调试工具
  2. 机器学习笔记 - 范数
  3. golang mysql 如何设置最大连接数和最大空闲连接数
  4. 互联网宗教信息传播规范和宗教内容审核机制|图普科技
  5. 电子电气架构——车载以太网防火墙
  6. 结构体中元素的偏移地址与首地址
  7. 一台服务器虚拟交换机,产品技术-H3C S1010V虚拟交换机-新华三集团-H3C
  8. 23种设计模式(Bright模式)
  9. IDEA如何导入jar包
  10. 计算机网络class4(时延、时延带宽积、RTT和利用率)