PCA(主成分分析)

在处理数据时有可能会造成维数灾难:在给定精度下,准确地对某些变量的函数进行估计,所需样本量会随着样本维数的增加而呈指数形式增长。
降维的意义:克服维数灾难,获取本质特征,节省存储空间,去除无用噪声,实现数据可视化
在这里插入图片描述

主成分分析(PCA(Principal Component Analysis))

  • 基本概念:构造原变量的一系列线性组合形成几个综合指标,以去除数据的相关性,并使低维数据最大程度保持原始高维数据的方差信息。
  • 一般步骤:
  1. 去除平均值,又称为样本中心化(每个样本元素减去自己特征的平均值)
  2. 计算协方差矩阵
  3. 计算协方差矩阵的特征值和特征向量将特征值从大到小排序
  4. 保留最上面的N个特征向量
  5. 将数据转换到上述N个特征向量构建的新空间中
  • 性质
    1.保留方差是最大的
    2.最终的重构误差(从变换后回到原始情况)是最小的

  • 算法描述:
    在这里插入图片描述
    假定数据样本进行了中心化,再假定投影变换后得到的新坐标系为 { w 1 , w 2 , . . . , w d } \{w_1,w_2,...,w_d\} {w1,w2,...,wd},其中 w i w_i wi是标准正交基向量, ∣ ∣ w i ∣ ∣ 2 = 1 , w i w j T = 0 ( i 不 等 于 j ) ||w_i||_2=1,w_iw_j^T=0(i不等于j) wi2=1,wiwjT=0(ij)若丢弃新坐标系中的部分坐标,即将维度降低到 d ′ &lt; d d&#x27;&lt;d d<d,则样本点 x i x_i xi在低维坐标系中的投影是 z i = ( z i 1 ; z i 2 ; . . . ; z i d ′ ) , z_i = (z_{i1};z_{i2};...;z_{id&#x27;}), zi=(zi1;zi2;...;zid), 其中 z i j = w i ⋅ x i z_{ij} = w_i\cdot x_i zij=wixi是在低维坐标系下第j维的坐标.若基于 z i z_i zi来重构 x i x_i xi,则会得到 y ^ = ∑ j = 1 d ′ z i j x j \hat y=\sum_{j=1}^{d&#x27;}z_{ij}x_j y^=j=1dzijxj.

了解PCA之前我们先复习一下概率论中方差,协方差,协方差矩阵的概念。

  • 方差

方差衡量数据的波动程度
均值:
X ‾ = 1 n ∑ i = 1 n x i \overline X=\frac{1}{n}\sum_{i=1}^nx_i X=n1i=1nxi
方差:
s 2 = 1 n − 1 ∑ i = 1 n ( x i − X ‾ ) 2 s^2=\sqrt{\frac{1}{n-1}\sum_{i=1}^n(x_i-\overline X)^2} s2=n11i=1n(xiX)2
标准差: s = s 2 s=\sqrt{s^2} s=s2

  • 协方差

方差描述的是其本身数据的情况,如果我们想知道,某2种数据之间的关系,比如,年龄和身高。假设这里有样本集合f(x,y)=(xi,…,yi),x表示年龄,y表示身高,那么2者之间的关联程度可以这么定义:
c o v ( X , Y ) = c o v ( Y , X ) = 1 n − 1 ∑ i = 1 n ( X 1 − X ‾ ) ( Y i − Y ‾ ) cov(X,Y)=cov(Y,X)=\frac{1}{n-1}\sum_{i=1}^n(X_1-\overline X)(Y_i-\overline Y) cov(X,Y)=cov(Y,X)=n11i=1n(X1X)(YiY)

  • 若X和Y相互独立,则 c o v ( X , Y ) = 0 cov(X,Y)=0 cov(X,Y)=0

  • c o v ( X , X ) = D ( X ) , D ( X ) 方 表 示 方 差 cov(X,X)=D(X),D(X)方表示方差 cov(X,X)=D(X)D(X)

  • c o v ( X , Y ) &gt; 0 , 则 表 示 X , Y 正 相 关 cov(X,Y)&gt;0,则表示X,Y正相关 cov(X,Y)>0X,Y相反则负相关。

  • 协方差矩阵

上述协方差描述的是二维,即两个变量之间的关系,如果是三维或者多维的情况则引入协方差矩阵来描述他们的关系。
设有n维随机变量 ( X 1 , X 2 , . . . , X n ) (X_1,X_2,...,X_n) (X1,X2,...,Xn)
σ i , j = c o v ( X i , X j ) = E ( X i − E ( X i ) ) E ( X j − E ( X j ) ) \sigma_{i,j}=cov(X_i,X_j)=E(X_i-E(X_i))E(X_j-E(X_j)) σi,j=cov(Xi,Xj)=E(XiE(Xi))E(XjE(Xj))
则协方差矩阵:
Σ = [ σ 11 σ 1 , 2 . . . σ 1 , n σ 21 σ 22 . . . σ 2 n . . . . . . . . . . . . σ n 1 σ n , 2 . . . σ n , n ] \Sigma=\begin{bmatrix} \sigma_{11} &amp; \sigma_{1,2} &amp;...&amp;\sigma_{1,n}\\ \sigma_{21} &amp; \sigma_{22}&amp;...&amp; \sigma_{2n}\\ ...&amp;...&amp;...&amp;...\\\sigma_{n1}&amp; \sigma_{n,2} &amp;...&amp;\sigma_{n,n}\\ \end{bmatrix}\quad Σ=σ11σ21...σn1σ1,2σ22...σn,2............σ1,nσ2n...σn,n
由协方差的性质可知,协方差矩阵 Σ \Sigma Σ对称矩阵

那么PCA和协方差矩阵有什么关系呢。

PCA的就是将高维空间的数据映射到低维空间,降低维度之间的相关性,并且使自身维度的方差尽可能的大。那么哪种数据方式可以同时表达维度之间的相关性以及维度本身的方差呢?就是上面提到的协方差矩阵。由上面协方差矩阵的概念可知,协方差矩阵对角线上是自身的方差,其他元素是两两维度之间的协方差(即相关性)。
PCA的目的之一:降低维度之间的相关性,也就说减小协方差矩阵非对角线上的值。如何减小呢?可以使协方差矩阵变成对角矩阵。对角化后的矩阵,其对角线上是协方差矩阵的特征值。特征值和特征向量可以参照线性代数中的概念。
即:假设有n*n的矩阵 A A A,并且有 A α = λ α , α 是 特 征 向 量 。 λ 称 为 特 征 值 。 A\alpha=\lambda \alpha,\alpha是特征向量。\lambda称为特征值。 Aα=λα,αλA若有n个线性无关的特征向量,则 A A A可对角化。若矩阵A可对角化,则有 P − 1 A P = [ λ 1 . . . λ 2 . . . . . . . . . . . . . . . . . . λ n ] P 表 示 有 A 的 的 特 征 向 量 施 密 特 正 交 化 后 组 成 的 正 交 矩 阵 。 P^{-1}AP=\begin{bmatrix} \lambda_1 &amp; &amp;...&amp;\\ &amp; \lambda_2&amp;...&amp; \\ ...&amp;...&amp;...&amp;...\\&amp; &amp;...&amp;\lambda_n\\ \end{bmatrix}\quad\\P表示有A的的特征向量施密特正交化后组成的正交矩阵。 P1AP=λ1...λ2..................λnPA
注:实对称矩阵( A T = A A^T=A AT=A)必可矩阵对角化。

A α A\alpha Aα矩阵相乘的含义就是,矩阵A对向量 α \alpha α进行一系列的变换(旋转或者拉伸),其效果等于一个常数 λ \lambda λ乘以向量 α \alpha α
通常我们求特征值和特征向量是想知道,矩阵能使哪些向量(当然是特征向量)只发生拉伸,其拉伸程度如何(特征值的大小)。这个真正的意义在于,是为了让我们看清矩阵能在特征向量方向产生最大的变化效果。
再回到刚才的协方差矩阵对角化之后,得到了协方差矩阵的特征值;那么我们就能得到协方差矩阵在特征值对应的特征向量的方向上有最大的变化效果。当然这里的特征值会有多个,我们只需要取最大的几个,特征值越大,表示其在特征向量上的变化越大。我们将这几个特征值对应的特征向量的方向作为新的维度,于是就达到了降维的目的。
即我们求协方差矩阵的特征值和特征向量得到 Σ = P − 1 Λ P , Λ 表 示 有 特 征 值 组 成 的 对 角 矩 阵 。 \Sigma=P^{-1}\Lambda P, \Lambda表示有特征值组成的对角矩阵。 Σ=P1ΛPΛ

代码实现:

import numpy as np
#读取文件
def loadDataSet(fileName, delim='\t'):
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    datArr = [map(float,line) for line in stringArr]
    return mat(datArr)

def pca(dataMat, topNfeat=n):
    meanVals = np.mean(dataMat, axis=0)   #(axis=0)按列求均值
    meanRemoved = dataMat - meanVals   #减去均值,即:每个元素减去自己特征的平均值
    covMat = np.cov(meanRemoved, rowvar=0)   #计算协方差矩阵,rowvar为0,一行为一个样本,不为0一列为一个样本
    
#求特征值和特征向量,特征向量是按列放的,即一列代表一个特征向量 。eigVals以行向量形式存放特征值。
#eigVects存放特征向量,每一列代表一个特征向量。
    eigVals,eigVects = np.linalg.eig(mat(covMat))
    eigValInd = np.argsort(eigVals)            #对特征值从小到大排序 ,函数argsort()返回从小到大排序的index
    eigValInd = eigValInd[:-(topNfeat+1):-1]  #列表逆序以后,从头到位取前topNfeat个特征值index,
#即最大的n个特征值的index (python里面,list[a:b:c]代表从下标a开始到b,
#步长为c。list[::-1]可以看作是列表逆序)
    redEigVects = eigVects[:,eigValInd]       
#最大的n个特征值对应的特征向量  
    lowDDataMat = meanRemoved * redEigVects
#低维特征空间的数据 
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
#把数据转换到新空间
    return lowDDataMat, reconMat
#返回结果

使用sklearn中的PCA:

  • 参数说明:
    n_components:
    意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
    类型:int 或者 string,缺省时默认为None,所有成分被保留。
    copy:
    类型:bool,True或者False,默认为True。意义:表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
    whiten:
    类型:bool,默认为False
    意义:白化,使得每个特征具有相同的方差。就是对降维后的数据的每个特征进行归一化,一般不需要白化。
  • .PCA对象的属性
    components_ :返回具有最大方差的成分。
    explained_variance_:所保留的n个成分各自的方差
    explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
    n_components_:返回所保留的成分个数n。
    noise variance:噪声方差大小
    mean_:特征均值
  • PCA对象的方法
    fit(X,y=None)
    fit()是scikit-learn中通用的方法。因为PCA是无监督学习算法,此处y等于None。
    fit(X),表示用数据X来训练PCA模型。
    fit_transform(X)
    用X来训练PCA模型,同时返回降维后的数据。
    inverse_transform()
    将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)
    transform(X)
    将数据X转换成降维后的数据。
  • 使用
    通常来说使用PCA降维以后需要保留95%以上的方差,因此sklearn中的PCA有三种种使用方式:
    第一种:手动设置维度int类型,即降维后的维度,查看保留的方差百分比(explained_variance_ratio_)来调整合适的n_components,此时n_components大于1。
    第二种:手动设置保留的方差百分比int类型,系统会自动选择维度,此时n_components范围在(0,1],例如0.95。
    第三种:还可以将参数设置为string类型"mle", 此时PCA类会用MLE最大似然算法根据特征的方差分布情况自己去选择一定数量的主成分特征来降维。
    通常使用pandas读取数据的时候得到的dataframe可能需要处理一下,变成array格式。
import numpy as np
import pandas as pd

df =pd.read_excel('data')
#这三种方法都可以
matrix1 = df.values
matrix2 = df.as_matrix()
matrix3 = np.array(df)

from sklearn.decomposition import PCA
pca1 = PCA(n_components=30)
pca2 = PCA(n_components=0.3)
pca3= PCA(n_components="mle")
matrix_pca = pca.fit_transform(matrix)
print (explained_variance_ratio_) #查看保留的维度各自的方差比例
variance_pca = pca.explained_variance_ratio_.sum()
#查看保留的总方差
print (variance_pca)

PCA的数学推导(了解)

矩阵知识可知: z = W X \bm{z=WX} z=WX
假设X代表所有属性构成的向量 X n × 1 \bm X_{n\times 1} Xn×1,我们可以乘上 W d × n \bm W_{d\times n} Wd×n,则上上式可得 z d × 1 z_{\bm d\times 1} zd×1,若d<n,则得到的新向量z的维度就小于 X \bm X X的维度,就达到了降维的效果。
那么问题就准变成了怎样找 W W W矩阵?我们拆开来看:
W = [ w 1 T w 2 T . . . w d T ] W=\begin{bmatrix} w_1^T \\ w_2^T\\ ...\\w_d^T\\ \end{bmatrix}\quad W=w1Tw2T...wdT

已知 z 1 \bm z_1 z1是特征 x 1 \bm x_1 x1投影在正交向量 w 1 \bm w_1 w1方向上的结果,即 z 1 = w 1 ⋅ x 1 , ∣ ∣ w 1 ∣ ∣ 2 = 1 , 即 w 1 是 正 交 向 量 。 \bm{z_1=w_1\cdot x_1}, \quad||w_1||_2=1,即w_1是正交向量。 z1=w1x1,w12=1,w1(向量点乘的含义:结果是一个向量在另一个向量方向上投影的长度,是一个标量)。
正交向量 w w w具有特征 ∣ ∣ w ∣ ∣ 2 = 1 , w T ⋅ w = 1 ||w||_2=1,w^T\cdot w=1 w2=1,wTw=1
在这里插入图片描述在这里插入图片描述
在整个样本空间中,要使样本点投影在特征向量上极可能的分开,则需要最大化投影点的方差:
V a r ( z 1 ) = ∑ z 1 ( z 1 − z ‾ 1 ) , ∣ ∣ w 1 ∣ ∣ 2 = 1 , z ‾ 1 表 示 该 特 征 的 均 值 Var(z_1)=\sum_{z_1}(z_1-\overline z_1),\quad||w_1||_2=1, \overline z_1表示该特征的均值 Var(z1)=z1(z1z1),w12=1,z1
由线性代数的知识可得:
Var ⁡ ( z 1 ) = ∑ z 1 ( z 1 − z 1 ‾ ) 2 = ∑ x ( w 1 ⋅ x − w 1 ⋅ x ‾ ) 2 = ∑ ( w 1 ⋅ ( x − x ‾ ) ) 2 = ∑ ( w 1 ) T ( x − x ‾ ) ( x − x ‾ ) T w 1 = ( w 1 ) T ∑ ( x − x ‾ ) ( x − x ‾ ) T w 1 \begin{array}{l}{\operatorname{Var}\left(z_{1}\right)=\sum_{z_{1}}\left(z_{1}-\overline{z_{1}}\right)^{2}} \\ {=\sum_{x}\left(w_{1} \cdot x-w_{1} \cdot \overline{x}\right)^{2}} \\ {=\sum\left(w_{1} \cdot(x-\overline{x})\right)^{2}} \\ {=\sum\left(w_{1}\right)^{T}(x-\overline{x})(x-\overline{x})^{T} w_{1}} \\ {=\left(w_{1}\right)^{T} \sum(x-\overline{x})(x-\overline{x})^{T} w_1}\end{array} Var(z1)=z1(z1z1)2=x(w1xw1x)2=(w1(xx))2=(w1)T(xx)(xx)Tw1=(w1)T(xx)(xx)Tw1
可看出其中 ∑ ( x − x ‾ ) ( x − x ‾ ) T = C o v ( x ) = S \sum(x-\overline{x})(x-\overline{x})^{T}=Cov(x)=S (xx)(xx)T=Cov(x)=S是协方差,(S是半正定矩阵,所有特征值非负。)
所以即找到 w 1 w_1 w1使得 V a r ( z 1 ) = w 1 T S w 1 , s t : ∣ ∣ w 1 ∣ ∣ 2 = 1 Var(z_1)=w_1^TSw_1,\quad st:\quad||w_1||_2=1 Var(z1)=w1TSw1,st:w12=1最大。
由拉格朗日乘子法令:
g ( w 1 ) = w 1 T S w 1 + λ ∣ ∣ w 1 ∣ ∣ 2 g(w_1)=w_1^TSw_1+\lambda||w_1||_2 g(w1)=w1TSw1+λw12
分别对 w 1 , λ w_1,\lambda w1,λ求偏导可得: S w 1 = λ w 1 , Sw_1=\lambda w_1, Sw1=λw1,所以 w 1 就 是 协 方 差 矩 阵 S w_1就是协方差矩阵S w1S的特征向量。且 w 1 w_1 w1是正交向量。

同理我们将特征 x 2 x_2 x2投影到 w 2 w_2 w2上得到 z 2 z_2 z2,且 w 1 ∗ w 2 = 0 , 即 两 向 量 垂 直 w_1\ast w_2=0,即两向量垂直 w1w2=0,:
V a r ( z 2 ) = ∑ z 2 ( z 2 − z ‾ 2 ) , ∣ ∣ w 2 ∣ ∣ 2 = 1 , w 1 ⋅ w 2 = 0 , z ‾ 2 表 示 该 特 征 的 均 值 Var(z_2)=\sum_{z_2}(z_2-\overline z_2),\quad||w_2||_2=1,w_1 \cdot w_2=0, \overline z_2表示该特征的均值 Var(z2)=z2(z2z2),w22=1,w1w2=0,z2
按相同的方法得到 S 对 应 的 特 征 向 量 w 2 , . . . , w d S对应的特征向量\bm{w_2,...,w_d} Sw2,...,wd。需注意不要忘记条件 w i w_i wi是正交向量,得到的矩阵 W \bm W W是正交矩阵,有性质 ∣ ∣ w i ∣ ∣ 2 = 1 , w i w j T = 0 ||w_i||_2=1,w_iw_j^T=0 wi2=1,wiwjT=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值