关于PCA
PCA是常见的降维技术。
对于使用PCA来进行降维的数据,需要进行预处理,是指能够实现均值为0,以及方差接近。如何来确定到底哪个维度是"主成分"?就要某个axis的方差。
为什么要减去均值?目的就是要获取矩阵为0,以及方差相同。为什么均值会为0?
mean = (a + b + c)/3
val = (a - m + b - m + c - m)/3 = (a + b + c)/ 3 - m/3 = 0 => 均值为0
注意,这里均值是指某个特征的,比如某个数据样本有两个特征,那么a,b,c是指其中一个特征的样本值;所以在计算均值的时候需要指定axis = 0,即在纵向上计算均值。
通过上图,我们可以看到,很明显B线的方差最大;然后数据将会做旋转(rotation),然后数据将会在这个轴上面做投影;然后我们再找第二个维度,这个维度需要正交并且垂直于第一个维度(二维世界里面正交和垂直是一个概念),这里线段C,同样的数据还会沿着C轴做旋转,然后做映射。
我理解其实旋转只是一种便于理解的方式,其实就可以理解为将空间中的数据的特征(每个特征都一个维度)要乘以一个数字,将其映射为某个新的维度,之前有N个维度,将会从其中选出一些可以很好覆盖数据的新的维度,将原来的特征做映射,映射到一个新的特征空间中:K维空间(K < N);那么怎么映射,于是就有了旋转这个概念,其实本质就是所有样本的指定特征都乘以一个数(不同的数),这些树也是一个矩阵,以一个用于旋转的矩阵;按照K个维度坐旋转。
现在问题就是如何来获得这个新的特征空间呢?想要求出特征空间就要求出这个旋转矩阵;这个旋转矩阵就可以通过特征值和特征向量来搞掂;求得是什么特征值和特征向量?协方差,至于为什么要用协方差,还记得上面我们提到的:要找到方差最大的角度,其实就是求解上图中两个特征的最大差距,这个可以用协方差来表示。
另外我们简单讲一下特征值和特征向量:Av=λv,描述的是这样数据关系:一个矩阵A左乘矩阵v,等价于一个标量λ*矩阵v。所谓标量值就是一个数(多个数就可以组成一个矩阵就是矢量),但是注意这里λ其实是多个数,但是每一个数都是代表一个独立的解,根据这个独立解可以获得一个特征向量,所以特征值和特征向量是一一对应的关系;特征值他们之间的关系并不能组成矩阵(具体可以参见《线性代数》特征值和特征向量章节)。对于特征值和特征向量一般应用的场景是A已知,求λ和v,前者就是特征值,后者就是特征向量。
在PCA算法中,协方差就是那个矩阵A,根据矩阵A可以求出λ和v;λ大小可以方便的判断坐标轴的方差大小,根据λ的大小我们可以推测出对应的特征向量的(旋转角度)数据的方差排序;很多场景下排名靠前的特征向量可以包揽大部分的方差,后面的特征向量(旋转角度)所占用的份额非常小,基本可以忽略不计。
这里牵涉到一个问题,怎么计算这个份额,还是使用特征值:
注意:上面采用特征值来评估特征向量的排序,这里还是使用特征向量来计算份额,我们其实可以这么来理解特征值,其实他就是特征向量的一个缩影(特征向量的计算和特征值密切相关)。再回到份额,我们可以根据上面的公式来计算份额。那么这里牵涉到了一个问题,就是如何来获取主成分的数量?根据份额;比如我们打算保留98%的份额,那么就逐个添加特征值(此时的特征值已经是按照从大到小排列),直到份额达到了比例。
from numpy import mean
from numpy import linalg
from numpy import argsort
from numpy import cov # 哪里看出来是降维呢?降维的依据又是什么呢?注意,eigValInd最后只是取值前topNfeat个成分
def PCA(dataMat, topNfeat=99999):
# 计算方差,然后用原始数据集-均值,减去均值目的就是要计算方差,为下一步求解协方差矩阵做准备
# 求解完协方差之后,就可以利用协方差值来求特征值以及特征矩阵
meanValue = mean(dataMat, axis = 0)
print("meanValue: ", meanValue)
# 源数据减去均值,整个特征的特征均值为0
meansRemoved = dataMat - meanValue
print("meansRemoved: ", meansRemoved)
covMat = cov(meansRemoved, rowvar=0)
print("covMat: ", covMat)
eigVals, eigVects = linalg.eig(mat(covMat))
print("eigVals: \n", eigVals)
print("eigVects: \n", eigVects)
# 对特征值进行排序,并基于此来获取特征向量,之所以通过-1来取倒序,是因为要按照特征权重从大到小获取
eigValInd = argsort(eigVals)
print("eigValInd: ", eigValInd)
eigValInd = eigValInd[:-(topNfeat+1):-1]
print("eigValInd sorted: ", eigValInd)
regeigVects = eigVects[:, eigValInd]
print("regeigVects: ", regeigVects)
# 获取降维之后的数据,以及逆运算推出原始数据
lowDDataMat = meansRemoved * regeigVects
reconMat = (lowDDataMat * regeigVects.T) + meanValue return lowDDataMat, reconMat
上面的一段代码中第28,29行其实并不是很懂,为什么分别计算lowDDataMat和reconMat?从是应用来看其实最终降维后,参与运算的数据是reconMat。
下面就是最后一个问题:如何对于降维后数据进行还原?降维的本质其实就是将非核心特征设置值为0;我们在算法一般会把把0值添加回去,而是直接采用xHat * Uk(xHat是旋转以后降维数据,Uk是特征向量空间的前K个向量)
参考:
解释特征矩阵和特征向量
http://mini.eastday.com/bdmip/180328092726628.html#
关于主成分分析
《机器学习实战》 Peter
关于PCA的更多相关文章
- 用scikit-learn学习主成分分析(PCA)
在主成分分析(PCA)原理总结中,我们对主成分分析(以下简称PCA)的原理做了总结,下面我们就总结下如何使用scikit-learn工具来进行PCA降维. 1. scikit-learn PCA类介绍 ...
- 主成分分析(PCA)原理总结
主成分分析(Principal components analysis,以下简称PCA)是最重要的降维方法之一.在数据压缩消除冗余和数据噪音消除等领域都有广泛的应用.一般我们提到降维最容易想到的算法就 ...
- 机器学习基础与实践(三)----数据降维之PCA
写在前面:本来这篇应该是上周四更新,但是上周四写了一篇深度学习的反向传播法的过程,就推迟更新了.本来想参考PRML来写,但是发现里面涉及到比较多的数学知识,写出来可能不好理解,我决定还是用最通俗的方法 ...
- 数据降维技术(1)—PCA的数据原理
PCA(Principal Component Analysis)是一种常用的数据分析方法.PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降 ...
- 深度学习笔记——PCA原理与数学推倒详解
PCA目的:这里举个例子,如果假设我有m个点,{x(1),...,x(m)},那么我要将它们存在我的内存中,或者要对着m个点进行一次机器学习,但是这m个点的维度太大了,如果要进行机器学习的话参数太多, ...
- PCA、ZCA白化
白化是一种重要的预处理过程,其目的就是降低输入数据的冗余性,使得经过白化处理的输入数据具有如下性质:(i)特征之间相关性较低:(ii)所有特征具有相同的方差. 白化又分为PCA白化和ZCA白化,在数据 ...
- PCA 协方差矩阵特征向量的计算
人脸识别中矩阵的维数n>>样本个数m. 计算矩阵A的主成分,根据PCA的原理,就是计算A的协方差矩阵A'A的特征值和特征向量,但是A'A有可能比较大,所以根据A'A的大小,可以计算AA'或 ...
- 【统计学习】主成分分析PCA(Princple Component Analysis)从原理到实现
[引言]--PCA降维的作用 面对海量的.多维(可能有成百上千维)的数据,我们应该如何高效去除某些维度间相关的信息,保留对我们"有用"的信息,这是个问题. PCA给出了我们一种解决 ...
- 主成分分析 (PCA) 与其高维度下python实现(简单人脸识别)
Introduction 主成分分析(Principal Components Analysis)是一种对特征进行降维的方法.由于观测指标间存在相关性,将导致信息的重叠与低效,我们倾向于用少量的.尽可 ...
- PCA与LDA的区别与联系
由于涉及内容较多,这里转载别人的博客: http://blog.csdn.net/sunmenggmail/article/details/8071502 其实主要在于:PCA与LDA的变换矩阵不同, ...
随机推荐
- 如何在一台计算机上配置多个jdk【转】
分析问题 为了多快好省的解决当前的问题,我的想法是在windows中同时安装jdk1.6和jdk1.8,在中间进行切换,而不需要多次进行重复的安装和卸载,这样简单方便. 解决思路 第一步:在安装之前, ...
- python之三级目录
#python之三级目录低配版 menu = { '北京':{ '朝阳':{ '国贸':{ 'CICC':{ }, 'HP':{ }, '渣打银行':{ }, 'CCTV':{ }, }, '望京': ...
- 基于Verilog的带FIFO输出缓冲的串口接收接口封装
一.模块框图及基本思路 rx_module:串口接收的核心模块,详细介绍请见“基于Verilog的串口接收实验” rx2fifo_module:rx_module与rx_fifo之间的控制模块,其功能 ...
- abp框架下,donet core配置swagger
abp已经自带了swagger,但是我们的文档注释swagger并没有做处理,需要我们自己手动处理一下 1.对Application层配置xml输出,一般勾上xml,默认的地址就可以啦! 2.修改St ...
- Vue-cli里面引用stylus遇到的问题总结
1.stylus的调用 在vue-cli中用到stylus样式处理器的时候一定要引用两个对应的报stylus stylus-loader 命令:cnpm install stylus stylus- ...
- python阅读目录
一.python基础--列表.元祖.字典.集合 二.1231 三.12121
- 如何使用idea给系统平台添加子应用和应用的模块
1.添加模块smartcity-portal,由于模块是在smartcity-framework工程下的,所以按照图片所示添加 2.smartcity-portal模块添加完成后,由于portal-d ...
- String对象常量池特性对synchronized对象的影响
一 .什么是String的常量池特性 对于字符串对象有两种创建方法,如下: 直接赋值法: String str1="直接赋值创建字符串"; 创建对象法: String str2=n ...
- hibrnate缓存
缓存: 是计算机领域的概念,它介于应用程序和永久性数据存储源之间. 缓存: 一般人的理解是在内存中的一块空间,可以将二级缓存配置到硬盘.用白话来说,就是一个存储数据的容器.我们关注的是,哪些数据需要被 ...
- Java中对Array数组的常用操作
目录: 声明数组: 初始化数组: 查看数组长度: 遍历数组: int数组转成string数组: 从array中创建arraylist: 数组中是否包含某一个值: 将数组转成set集合: 将数组转成li ...