赞
踩
定义: PCA(Principal Component Analysis)是一种常用的数据分析方法。PCA通过线性变换将原始数据进行线性变换、映射到低维空间中,使得各维度线性无关的表示,可用于提取数据的主要特征分量。
作用:数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量数据信息。
应用:回归分析、聚类分析
向量即有大小和方向的量,例如向量(a,b),其包含的定义为: 以x轴和y轴上正方向长度为1的向量为标准,向量(a,b)可以表示为, 不难证明所有二维向量都可以表示为这样的线性组合,此处(1,0)和(0,1)叫做二维空间中的一组基。
准确的描述变量:确定一组基,给出在基所在的各个直线上的投影值。注意基是线性无关的,但不一定是正交的,但在实际应用中会选择正交基,正交基有很多较好的性质。
下面以几个例子展示基变换的矩阵表示。
例一:将(1,2)变换为新基上的坐标,即用(1,2)与第一个基作内积运算作为第一个新坐标的分量,用(1,2)与第二个基作内积运算作为第二个新坐标的分量。利用矩阵的形式可表示为:
例二:对于m个二维向量变换为这些基下的坐标,只要将二维向量按列排成一个两行m列矩阵,然后用“基矩阵”乘以这个矩阵,利用矩阵表示:
例三:对于M个N维向量,想将其变换为由R个N维向量表示的新空间中,那么首先将R个基按行组成矩阵A,然后将向量按列组成矩阵B,那么两矩阵的乘积AB就是变换结果,其中AB的第m列为A中第m列变换后的矩阵C。
注:其中a表示基,b表示原始数据记录。 这里R可以小于N,R决定了变换后数据的维数,即将一N维数据变换到更低维度的空间中去,变换后的维度取决于基的数量。
根据上面的分析,选择不同的基可以对同一组数据给出不同的表示,如果基的数量少于向量本身的维数,可以达到降维的效果
目标:如何选择最优基
(1)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值,这样做的目的是将数据处理成以0中心的数据,便于后续数据离散化;
(2)对于一般的二维降为一维,数据在某一个方向(基)上投影后的值尽可能的离散化,得出最优基。 投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述。
方差
一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值:
在(1)中已对数据的各个字段进行了0均值化,方差表示为每个元素的平方和除以元素个数:
结论:对于二维降为一维的最优基,就是使得所有数据变换为这个基上的坐标变换后“方差值最大”。
(3)对于高维数据,首先找到一个方向使得投影后方差最大,完成第一个投影方向的选择,再按要求选择第N个投影方向的选择,但是某些方向存在重合,为了投影后的投影值尽可能表示更多的原始数据,因此他们之间不存在线性相关性(相关性意味着投影值之间不是完全独立,存在重复表示的信息)。数学上利用协方差表示其相关性。
协方差
以两个字段为例,两个字段的协方差表示其相关性,在(1)中已对数据的各个字段进行了0均值化后每个字段的均值为0,则有:
注:当协方差等于0时,表示这两个字段完全独立,这就是降维的优化目标,为了让 协方差为0,在选择第二个基的时候在第一个基的正交方向上选择。
结论: 将一组N维向量降为M维(K大于0,小于N),其目标是选择M个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,而字段的方差则尽可能大(在正交的约束下,取最大的M个方差)。
上面的分析给出了选择最优基的实现目标:字段方差最大化,字段间协方差为0。我们可以用协方差矩阵将两者同一表示。
协方差矩阵
对于一个矩阵X:
用X乘以X的转置并乘以系数1/m(字段数据个数):
这个矩阵C对角线上的元素是字段的方差,其他位置元素是两字段间的协方差。
结论: 设我们有m个n维数据记录,将其按列排成n乘m的矩阵X,设,则C是一个对称矩阵,其对角线分别个各个字段的方差,而第i行j列和j行i列元素相同,表示i和j两个字段的协方差。
得到协方差矩阵后,为了达到优化目标,需要对协方差矩阵对角化: 即除对角线外的其它元素化为0(协方差为0), 并且在对角线上将元素按大小从上到下排列(方差最大)。
协方差矩阵对角化
设原始数据矩阵X对应的协方差矩阵为C,而P是一组基按行组成的矩阵,设Y=PX,则Y为X对P做基变换后的数据。设Y的协方差矩阵为D,D与C的关系如下:
结论: 优化目标变成了寻找一个矩阵P,满足是一个对角矩阵,并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件。
协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:
1)实对称矩阵不同特征值对应的特征向量必然正交。
2)设特征向量λ重数为r,则必然存在r个线性无关的特征向量对应于λ,因此可以将这r个特征向量单位正交化。
由上面两条可知,一个n行n列的实对称矩阵一定可以找到n个单位正交特征向量,设这n个特征向量e1,e2,⋯,en,我们将其按列组成矩阵E=(e1 e2 ⋯ en)则对协方差矩阵C有如下结论:
其中Λ为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。
结论:就是变换所需要的矩阵,按照特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵X,就得到了我们需要的降维后的数据矩阵Y。
(1)将原始数据按列组成n行m列矩阵X
(2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值。
(3)求出协方差矩阵
(4)求出协方差矩阵的特征值及对应的特征向量
(5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P
(6)Y=PX即为降维到k维后的数据
1)将矩阵的每行进行0均值化
2)求协方差矩阵
3)求出协方差矩阵的特征值和特征向量,并对特征向量进行标准化
特征值:
特征向量:
其中对应的特征向量分别是一个通解,c1和c2可取任意实数
标准化特征向量:
4)根据3)的标准化特征向量得出矩阵P
5) 用P的第一行乘以数据矩阵,就得到了降维后的数据
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver=’auto’, tol=0.0, iterated_power=’auto’, random_state=None)
参数说明
n_components:
意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
类型:int 或者 string,缺省时默认为None,所有成分被保留。
赋值为int,比如n_components=1,将把原始数据降到一个维度。
赋值为string,比如n_components=‘mle’,将自动选取特征个数n,使得满足所要求的方差百分比。
copy:
类型:bool,True或者False,缺省时默认为True。
意义:表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
whiten:
类型:bool,缺省时默认为False
意义:白化,使得每个特征具有相同的方差。
svd_solver :string
即指定奇异值分解SVD的方法,由于特征分解是奇异值分解SVD的一个特例,一般的PCA库都是基于SVD实现的。有4个可以选择的值:{‘auto’, ‘full’, ‘arpack’, ‘randomized’}。randomized一般适用于数据量大,数据维度多同时主成分数目比例又较低的PCA降维,它使用了一些加快SVD的随机算法。 full则是传统意义上的SVD,使用了scipy库对应的实现。arpack和randomized的适用场景类似,区别是randomized使用的是scikit-learn自己的SVD实现,而arpack直接使用了scipy库的sparse SVD实现。默认是auto,即PCA类会自己去在前面讲到的三种算法里面去权衡,选择一个合适的SVD算法来降维。一般来说,使用默认值就够了。
PCA对象的常用属性
components_ :返回具有最大方差的成分。
explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
n_components_:返回所保留的成分个数n。
mean_:返回根据训练集估计特征经验平均
noise_variance_:返回模型噪声方差
PCA对象的常用方法
fit(X,y=None)
fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。fit(X),表示用数据X来训练PCA模型。
函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。
fit_transform(X)
用X来训练PCA模型,同时返回降维后的数据。
newX=pca.fit_transform(X),newX就是降维后的数据。
inverse_transform()
将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)
transform(X)
将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。
1)随机生成随机数据并可视化
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from sklearn.datasets.samples_generator import make_blobs
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本3个特征,共4个簇
X, y = make_blobs(n_samples=10000, n_features=3, centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]], cluster_std=[0.2, 0.1, 0.2, 0.2],
random_state =9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o')
2)只对数据进行投影,观测投影后三维数据的方差分布(此时并未降维)
from sklearn.decomposition import PCA
pca = PCA(n_components=3)
pca.fit(X)
print("方差百分比:",pca.explained_variance_ratio_)
print("方差:",pca.explained_variance_)
"""
方差百分比: [0.98318212 0.00850037 0.00831751]
方差: [3.78521638 0.03272613 0.03202212]
"""
由此可以看出三个特征维度方差比例大约为98.3%、0.85%、0.83%,投影后第一个特征占了数据主要成分。
3)将数据从三维降到二维
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)
print("方差百分比:",pca.explained_variance_ratio_)
print("方差:",pca.explained_variance_)
"""
方差百分比: [0.98318212 0.00850037]
方差: [3.78521638 0.03272613]
"""
投影后选择的肯定是前两个特征,抛弃第三特征,此时我们可以看看转化后数据的分布:
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o')
plt.show()
可见降维后的数据依然可以看到三维图中四簇
4)指定降维后主成分方差和比例
from sklearn.decomposition import PCA
pca = PCA(n_components=0.95)
pca.fit(X)
print("方差百分比:",pca.explained_variance_ratio_)
print("方差:",pca.explained_variance_)
"""
方差百分比: [0.98318212]
方差: [3.78521638]
"""
可见第一个主成分占投影方差比例就达到了98%,只选第一个就达到了阀值。
5)使用mle算法自己选择降维的效果
from sklearn.decomposition import PCA
pca = PCA(n_components="mle",svd_solver='full')
pca.fit(X)
print("方差百分比:",pca.explained_variance_ratio_)
print("方差:",pca.explained_variance_)
"""
方差百分比: [0.98318212]
方差: [3.78521638]
"""
可见由于我们的数据的第一个投影特征的方差占比高达98.3%,MLE算法只保留了我们的第一个特征。
http://blog.codinglabs.org/articles/pca-tutorial.html
https://www.cnblogs.com/pinard/p/6243025.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。