PCA的原理及MATLAB实现

相关文章

PCA的原理及MATLAB实现

UFLDL教程:Exercise:PCA in 2D & PCA and Whitening

python-A comparison of various Robust PCA implementations

----------------------------

本文参考:
http://blog.csdn.net/gwh111/article/details/11742735
http://www.mathworks.com/matlabcentral/newsreader/view_thread/326056
https://www.zhihu.com/question/37094362
http://blog.csdn.net/zhaoxinfan/article/details/9138165
http://blog.csdn.net/stdcoutzyx/article/details/37568225
http://blog.csdn.net/ice110956/article/details/14250745
http://blog.csdn.net/xl890727/article/details/16898315
http://www.cnblogs.com/tornadomeet/archive/2012/09/06/2673104.html
http://blog.csdn.net/llp1992/article/details/45065609
http://www.cnblogs.com/tornadomeet/archive/2012/12/30/2839615.html
http://blog.csdn.net/ice110956/article/details/20936351?utm_source=tuicool&utm_medium=referral

关于PCA原理可以直接参考下面的文章
深入理解PCA

PCA是经常用来减少数据集的维数,同时保留数据集中对方差贡献最大的特征来达到简化数据集的目的。
PCA的原理就是将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。通过一个转换坐标,也可以理解成把一组坐标转换到另外一组坐标系下,但是在新的坐标系下,表示原来的原本不需要那么多的变量,只需要原来样本的最大的一个线性无关组的特征值对应的空间的坐标即可。
PCA算法核心思想就是将 n 维特征映射到 k 维上(k < n),这 k 维是全新的正交特征。我们将这 k 维成为主元,是重新构造出来的 k 维特征,而不是简单地从 n 维特征中取出其余 n-k 维特征。

PCA实现的步骤
(1)把原始数据中每个样本用一个向量表示,然后把所有样本组合起来构成一个矩阵。为了避免样本的单位的影响,样本集需要标准化(一般都是去均值化)。
(2)求该矩阵的协方差矩阵。
(3)求步骤2中得到的协方差矩阵的特征值和特征向量。
(4)将求出的特征向量按照特征值的大小进行组合形成一个映射矩阵,并根据指定的PCA保留的特征个数取出映射矩阵的前n行或者前n列作为最终的映射矩阵。
(5)用步骤4的映射矩阵对原始数据进行映射,达到数据降维的目的。

PCA理论的matlab实现

function [Y,V,E,D] = newpca(X)
%其中X为输入数据,X的每一列是一个输入样本。返回值Y是对X进行PCA分析后的投影矩阵。
%V是与X有关的协方差矩阵特征向量的白化矩阵,E是对应的特征向量(列)构成的矩阵,
%D是对应的特征值构成的对角矩阵(特征值处于对角线上)。
%返回值中的白化矩阵,特征向量和特征值都是按照对应特征值大小进行排序后了的。
% do PCA on image patches
%
% INPUT variables:
% X                  matrix with image patches as columns
%
% OUTPUT variables:
% Y                  the project matrix of the input data X without whiting
% V                  whitening matrix
% E                  principal component transformation (orthogonal)
% D                  variances of the principal components%去除直流成分
X = X-ones(size(X,1),1)*mean(X);% Calculate the eigenvalues and eigenvectors of the new covariance matrix.
covarianceMatrix = X*X'/size(X,2); %求出其协方差矩阵
%E是特征向量构成,它的每一列是特征向量,D是特征值构成的对角矩阵
%这些特征值和特征向量都没有经过排序
[E, D] = eig(covarianceMatrix); % Sort the eigenvalues  and recompute matrices
% 因为sort函数是升序排列,而需要的是降序排列,所以先取负号,diag(a)是取出a的对角元素构成
% 一个列向量,这里的dummy是降序排列后的向量,order是其排列顺序
[dummy,order] = sort(diag(-D));
E = E(:,order);%将特征向量按照特征值大小进行降序排列,每一列是一个特征向量
Y = E'*X;
d = diag(D); %d是一个列向量
%dsqrtinv是列向量,特征值开根号后取倒,仍然是与特征值有关的列向量
%其实就是求开根号后的逆矩阵
dsqrtinv = real(d.^(-0.5)); 
Dsqrtinv = diag(dsqrtinv(order));%是一个对角矩阵,矩阵中的元素时按降序排列好了的特征值(经过取根号倒后)
D = diag(d(order));%D是一个对角矩阵,其对角元素由特征值从大到小构成
V = Dsqrtinv*E';%特征值矩阵乘以特征向量矩阵

示例:二维数据的实现过程

function [lowData,reconMat] = PCA(data,K)
[row , col] = size(data);
meanValue = mean(data);
%varData = var(data,1,1);
normData = data - repmat(meanValue,[row,1]);
covMat = cov(normData(:,1),normData(:,2));%求取协方差矩阵
[eigVect,eigVal] = eig(covMat);%求取特征值和特征向量
[sortMat, sortIX] = sort(eigVal,'descend');
[B,IX] = sort(sortMat(1,:),'descend');
len = min(K,length(IX));
eigVect(:,IX(1:1:len));
lowData = normData * eigVect(:,IX(1:1:len));
reconMat = (lowData * eigVect(:,IX(1:1:len))') + repmat(meanValue,[row,1]); % 将降维后的数据转换到新空间
end

下面给出PCA的Matlab实现部分:Matlab自带的函数
Matlab中已经包含了实现了的PCA算法,可以通过princomp函数调用。其形式为:
[COEFF,SCORE, latent]=princomp(X);
X:为要输入的n维原始数据。带入这个matlab自带函数,将会生成新的n维加工后的数据(即SCORE)。此数据与之前的n维原始数据一一对应。
COEFF主成分分量,即变换空间中的那些基向量,是系数矩阵。通过COEFF可以知道x是怎样转换成SCORE的。
在n行p列的数据集X上做主成分分析。返回主成分系数。X的每行表示一个样本的观测值,每一列表示特征变量。COEFF是一个p行p列的矩阵,是X矩阵所对应的协方差阵V的所有特征向量组成的矩阵,即变换矩阵或称投影矩阵,COEFF每列对应一个特征值的特征向量,列的排列顺序是按特征值的大小递减排序。
SCORE为主成分,即X的低维表示。生成的n维加工后的数据存在SCORE里。它是对原始数据进行的分析,进而在新的坐标系下获得的数据。他将这n维数据按贡献率由大到小排列。(即在改变坐标系的情况下,又对n维数据排序)
latent为一个包含样本协方差矩阵的本征值的向量。是一维列向量,每一个数据是对应SCORE里相应维的贡献率,因为数据有n维所以列向量有n个数据。由大到小排列(因为SCORE也是按贡献率由大到小排列)。
princomp这个matlab自带的函数,在降维之前就将每一个样本减去了一个所有样本的平均值。princomp这里使用一行表示一个样本,每行包括这个样本的所有的特征值。

其实我们要的是由函数[COEFF,SCORE, latent] = princomp(X)它所产生的pc和latent。由latent可以算出降维后的空间所能表示原空间的程度,只要这个累积的值大于95%就行了
cumsum(latent)./sum(latent)

举例说明:

load hald; %载入matlab内部数据
[COEFF,SCORE,latent,tsquare] = princomp(ingredients); %调用pca分析函数
% 下面我们具体说明COEFF,SCORE,latent

%下面为计算ingredients所对应的协方差矩阵(也就是cov_ingredients矩阵)的特征值和特征向量,下面的矩阵V为特征向量,D为特征值(对比上面的latent)组成的对角线矩阵
[V,D] = eig(cov_ingredients)V =0.5062    0.5673    0.6460   -0.06780.4933   -0.5440    0.0200   -0.67850.5156    0.4036   -0.7553    0.02900.4844   -0.4684    0.1085    0.7309D =0.2372         0         0         00   12.4054         0         00         0   67.4964         00         0         0  517.7969

%说明1:对比一下矩阵V和矩阵COEFF,现在很容易明白为什么COEFF是按列递减顺序排列的了!(V中第三列与COEFF中倒数第三列差个负号,学过线性代数的人都知道这没问题)

%下面再验证一下说明2
diag(cov(SCORE))ans =517.796967.496412.40540.2372
%说明2:以上结果显示latent确实表示SCORE矩阵每列的方差,517.7969表示第一列方差[COEFF,SCORE,latent,tsquare] = princomp(ingredients);
% 上面这个函数,COEFF矩阵是返回的转换矩阵,也就是把样本转换到新的空间中的准换矩阵,这个准换矩阵式比较大的。
% SCORE是原来的样本矩阵在新的坐标系中的表示,也就是原来的样本乘上转换矩阵,但是,还不是直接乘,要减去一个样本的均值。将原来的数据转换到新的样本空间中的算法是这样实现的:
x0 = bsxfun(@minus,ingredients,mean(ingredients,1));
NewSCORE1 = x0 * COEFF;NewSCORE1 =36.8218   -6.8709   -4.5909    0.396729.6073    4.6109   -2.2476   -0.3958-12.9818   -4.2049    0.9022   -1.1261
   23.7147   -6.6341    1.8547   -0.3786-0.5532   -4.4617   -6.0874    0.1424
  -10.8125   -3.6466    0.9130   -0.1350
  -32.5882    8.9798   -1.6063    0.0818
   22.6064   10.7259    3.2365    0.3243-9.2626    8.9854   -0.0169   -0.5437
   -3.2840  -14.1573    7.0465    0.3405
    9.2200   12.3861    3.4283    0.4352-25.5849   -2.7817   -0.3867    0.4468
  -26.9032   -2.9310   -2.4455    0.4116

NewSCORE2 = ingredients * COEFF;NewSCORE2 =25.9105   -7.0189  -35.8545   48.526618.6960    4.4628  -33.5112   47.7341-23.8931   -4.3530  -30.3613   47.0039
   12.8034   -6.7821  -29.4088   47.7514-11.4645   -4.6098  -37.3510   48.2723
  -21.7238   -3.7946  -30.3506   47.9950
  -43.4995    8.8318  -32.8699   48.2117
   11.6951   10.5779  -28.0270   48.4543-20.1739    8.8373  -31.2805   47.5862
  -14.1953  -14.3053  -24.2171   48.4705
   -1.6913   12.2380  -27.8352   48.5651
  -36.4962   -2.9297  -31.6503   48.5768
  -37.8145   -3.0790  -33.7091   48.5416

%对比NewSCORE1和NewSCORE2 与 SCORE,可以看成 SCORE与NewSCORE1是一样。
% 下面我们就来确定最后的转换矩阵
cumsum(latent)./sum(latent)
ans =0.86600.97890.99961.0000SelectNum = cumsum(latent)./sum(latent)index = find(SelectNum >= 0.95);ForwardNum = index(1);
%选择由latent可以算出降维后的空间所能表示原空间的程度,只要这个累积的值大于95%的数目ForwardNum,就选择前ForwardNum个主成分作为变换矩阵。
%做主成分变换矩阵,也就是降维矩阵
tranMatrix = COEFF(:,1:ForwardNum)tranMatrix =-0.0678   -0.6460
   -0.6785   -0.0200
    0.0290    0.75530.7309   -0.1085

% Newingredients = x0 * tranMatrix
Newingredients =36.8218   -6.870929.6073    4.6109-12.9818   -4.2049
   23.7147   -6.6341-0.5532   -4.4617
  -10.8125   -3.6466
  -32.5882    8.9798
   22.6064   10.7259-9.2626    8.9854
   -3.2840  -14.1573
    9.2200   12.3861-25.5849   -2.7817
  -26.9032   -2.9310
  % 这样Newingredients就是ingredients经过PCA降维的最终的结果。

测试样本降维
如果你需要对测试样本降维,一般情况下,使用matlab自带的方式,肯定需要对测试样本减去一个训练样本均值,因为你在给训练样本降维的时候减去了均值,所以测试样本也要减去均值,然后乘以coeff这个矩阵,就获得了测试样本降维后的数据。使用训练样本得到的转换矩阵,保证训练样本和测试样本转换到相同的样本空间中。比如说你的测试样本是1*1000000,那么乘上一个1000000*29的降维矩阵,就获得了1*29的降维后的测试样本的降维数据。

princomp(x)使用的行表示一个样本,每行的所有的列数据都是这个样本的特征值。降维以后比如是30*29,那么每一行就是降维以后的数据。每个样本有29个特征值。

%X为训练集,Xtest为测试集
[COEFF,SCORE, latent] = princomp(X);SelectNum = cumsum(latent)./sum(latent)index = find(SelectNum >= 0.95);ForwardNum = index(1);
%选择由latent可以算出降维后的空间所能表示原空间的程度,只要这个累积的值大于95%的数目ForwardNum,就选择前ForwardNum个主成分作为变换矩阵。
%做主成分变换矩阵
NewtrainScores = SCORE(:,1:ForwardNum);
**NewtrainScores就是X经过PCA降维后的数据**%
tranMatrix = COEFF(:,1:ForwardNum)
[row , col] = size(Xtest);
meanValue = mean(X);
normXtest = Xtest - repmat(meanValue,[row,1]);
% 第二种方法
%normXtest = bsxfun(@minus,Xtest,meanValue); % center the test data
NewtestScores = normXtest*tranMatrix;
%**NewtestScores 就是Xtest经过PCA降维后的数据。**

备注说明:
对测试样本进行降维的时候,一定要减去训练样本的均值,使用训练样本得到的转换矩阵,保证训练样本和测试样本转换到相同的样本空间中,这样才有意义。
很多人就选择还是使用princomp这个函数处理测试样本,那么这样测试样本被映射到一个新的空间中,和原来的训练样本完全不是在一个空间,一点意义都没有,还是要使用测试样本减去训练样本的均值,然后乘上训练样本降维的时候获得降维矩阵,转换到相同的空间中

project the test data on the reduced set of the principal 
components. Note that princomp centers data before computing the principal components. You need to center the test data as well. It is best to do that using the means obtained from the training data. Something like this would 
do:mu = mean(Xtrain);
[coefs,scores,variances] = princomp(Xtrain,'econ');
% do your thing to select the components
Xtest = bsxfun(@minus,Xtest,mu); % center the test data
testScores = Xtest*coefs(:,1:d);

具体详情大家可以参考
http://blog.csdn.net/gwh111/article/details/11742735
http://www.mathworks.com/matlabcentral/newsreader/view_thread/326056

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明&#xff1a;Java生鲜电商平台中&#xff0c;我们将进一步理解微服务架构的核心要点和实现原理&#xff0c;为读者的实践提供微服务的设计模式&#xff0c;以期让微服务在读者正在工作的项目中起到积极的作用。…

iOS中下载小文件

在iOS中通过网络下载小文件比如小型图片等资源&#xff0c;一般在子线程中将数据完全下载完毕&#xff0c;然后在调用block将下载的数据整个部分返回&#xff0c;或者采用同步返回下载数据。 一般采用以下两种方式&#xff1a; &#xff08;1&#xff09;使用GCD将下载操作放…

iOS下载大文件原理解析一

iOS中下载大型文件&#xff0c;需要考虑到占用内存的大小与下载速度&#xff08;使用多线程&#xff09;&#xff0c;因此本文首先介绍一个原理性下载文件的DEMO。 在下载大型文件中&#xff0c;需要知道下载的进度因此需要使用代理模式&#xff0c;不断的回调下载进度。 - (…

recv原理、高阶版黏包解决方案、基于UDP的socket通信

recv原理、高阶版黏包解决方案、基于UDP的socket通信 recv原理 源码解释&#xff1a; Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据&#xff0c; For the optional flags argument, see the Unix manual. 对于这些设置的参数&#xff0c;可…

iOS中下载大型文件的原理解析二

在iOS中下载大型文件&#xff0c;需要使用NSURLConnection 的代理方法&#xff1a; (void)touchesBegan:(NSSet)touches withEvent:(UIEvent *)event { NSURL *url [NSURL URLWithString:”http://d.3987.com/fengj_141112/007.jpg“]; NSURLRequest *request [NSURLReque…

ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试。 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的IIS上面进行调试的呢&#xff0c;接下来我们来简单介绍下&#xff1a; 一、安装IIS所需的Host扩…

iOS下载大型文件原理解析三

在下载大型文件过程中是可以取消下载的 - (IBAction)download:(UIButton *)sender { // 状态取反 sender.selected !sender.isSelected; // 断点续传 // 断点下载if (sender.selected) { // 继续&#xff08;开始&#xff09;下载// 1.URLNSURL *url [NSURL URLWithStrin…

HTML文件上传与下载

文件下载 传统的文件下载有两种方法&#xff1a; 使用<a/>标签&#xff0c;href属性直接连接到服务器的文件路径window.location.href"url"这两种方法效果一样。但有个很大的问题&#xff0c;如果下载出现异常&#xff08;连接路径失效、文件不存在、网络问题等…

NSURLSession的应用

iOS7以后发布了NSURLSession用来替换NSURLConnection&#xff0c;NSURLSession使用方式有以下两种&#xff1a; 1.block方式 &#xff08;1&#xff09;创建的步骤 获取单例会话对象 创建URL对象 隐含创建request 创建NSURLSessionDataTask // 1.获取会话对象 NSURLSess…

ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)...

在正式进入主题之前我们来看下几个概念&#xff1a; 一、依赖倒置 依赖倒置是编程五大原则之一&#xff0c;即&#xff1a; 1、上层模块不应该依赖于下层模块&#xff0c;它们共同依赖于一个抽象。 2、抽象不能依赖于具体&#xff0c;具体依赖于抽象。 其中上层就是指使用者&am…

iOS中XML解析

iOS中XML解析分为两种实现方式&#xff1a;SAX与DOM SAX方式&#xff1a;主要是事件驱动的解析方式&#xff0c;是逐行读取XML数据&#xff0c;不断回调代理&#xff0c;告诉代理当前解析的元素开始或者结束。 DOM解析方式&#xff1a;是讲整个XML数据全部读入内存&#xff0…

苹果电脑基本设置+Linux 命令+Android 实战集锦

本文微信公众号「AndroidTraveler」首发。 背景 大多数应届毕业生在大学期间使用的比较多的是 windows 电脑&#xff0c;因此初入职场如果拿到一台苹果电脑&#xff0c;可能一时间不能够很快的上手。基于此&#xff0c;这边出了系列视频&#xff0c;通过实际的演示让没使用过苹…

iOS中POST请求

iOS中POST请求的发送需要使用NSMutableURLRequest可以设置URL request的头字段&#xff0c;比如超时时间&#xff0c;请求类型&#xff1a;GET POST等一些关键头字段&#xff1a; - (IBAction)login { // 1.用户名 NSString *usernameText self.username.text; if (userna…

发送JSON数据给服务器

需要将JSON格式的数据传送给服务器&#xff0c;注意需要设置&#xff1a; [request setValue:”application/json” forHTTPHeaderField:”Content-Type”]; Content-Type类型为&#xff1a;application/json // 1.URL NSURL *url [NSURL URLWithString:"http://localh…

Mac中AndroidStudio没有找到Plugins的问题

我们在windows中都可以正常找到plugins 但是在Mac上AndroidStudio里 setting打开却没有plugins 正准备在Mac上搞一下flutter呢 我感觉智商受到了侮辱&#xff01; 这里其实是mac版本给我开了个玩笑 你可以按快捷键&#xff0c;你就可以找到 快捷键 command ‘,’ 没错就是comm…

进程和操作系统概述

进程和操作系统概述 进程的基础 程序和进程&#xff1a; 程序是一对静态的代码文件 进程是一个正在运行着的程序&#xff0c;抽象概念 进程由操作系统操控调用交于CPU运行 操作系统 1.管理控制协调计算机硬件和软件的关系 2.操作系统的作用&#xff1f; ​ 第一个作用&#xff…

iOS手势操作简介(一)

iOS中能够响应手势操作的类必须要继承自UIResponder&#xff0c;才能够处理手势响应操作。 默认继承了UIResponder的类有&#xff1a;UIApplication UIViewController UIView都继承自UIResponder. UIView是UIResponder的子类&#xff0c;可以实现下列4个方法处理不同的触摸事…

iOS开发中手势处理简介(二)

iOS中手势操作事件的产生于传递 发生触摸事件后&#xff0c;系统会将该事件加入到一个由UIApplication管理的事件队列中 UIApplication会从事件队列中取出最前面的事件&#xff0c;并将事件分发下去以便处理&#xff0c;通常&#xff0c;先发送事件给应用程序的主窗口&#x…

对前端Jenkins自动化部署的研究

1. 安装 安装 Nginx 1.1去官网下直接下载&#xff0c;解压缩 start nginx就可以使了&#xff0c;常用命令&#xff1a; start nginx # 启动 nginx -s reload # 修改配置后重新加载生效 nginx -s reopen # 重新打开日志文件 nginx -t # 配置文件检测是否正确 1.2 安装Jenkins…

python超神之路:Python3 列表list合并的4种方法

Python3 列表list合并的4种方法 方法1: 直接使用""号合并列表 aList [1,2,3] bList [www, pythontab.com] cList aList bList dList bList aList print(cList) print(dList) # 结果&#xff1a; [1, 2, 3, www, pythontab.com] [www, pythontab.com, 1, 2, 3] …