zoukankan      html  css  js  c++  java
  • [降维] PCA 主成分分析

    其实早该整理一下PCA了,怎奈一直没有时间,可能是自己对时间没有把握好吧,下面进入正题。

     


    降维的概念

    所谓降维,就是降低数据的维数。在机器学习中尤其常见,之前做过对一幅图片提取小波特征,对于一幅大小为800*600的图片,如果每个点提取五个尺度、八个方向的特征,那么每一个像素点提取40个特征,那么一副图片的话就是40*800*600=19200000个特征。也就是我们用一个19200000的向量描述一幅图片。如果有m幅图片,那么特征为m*19200000的大小。显然这个维数太大了,所以需要降维。

    形式化的描述:假设数据矩阵为Xm,n(这个矩阵可能是feature矩阵,也可能是其他矩阵)。m代表数据的大小,n代表维数,通常n非常大。降维的目的是我们希望找到一个矩阵Y=XP,使得Y满足以下两个条件:

    (a) Y的维度小于X的维度(这样就起到了降维的目的)。

    (b) Y的各个维度之间的差异越大越好(差异越大,表示包含的信息越多,对描述数据越有效);

    条件(a)比较容易满足,我们只需要Pn,t(t<m),那么得到的Y就是Ym,t显然起到了降维的目的。因此我们的重点是找到P满足(b)。

    为此,我们首先给出差异性度量的准则-方差和协方差。

    方差和协方差

    对于数据矩阵Xm,n,它的第 j 维数据的差异性可以用方差来表示:

                

    对于数据Xm,n,我们希望的是它的所有的维与维之间的差异性越大越好,维p与维q之间的差异性可以用协方差表示:

    这样,数据Xm,n的各个维度的差异性可以用协方差矩阵C表示

    显然,协方差矩阵是一个实对阵矩阵。通过上面的式子计算协方差矩阵还是比较麻烦的,我们直接在矩阵上操作,对矩阵X进行中心化

    那么协方差矩阵可以通过下式得到

    可见协方差矩阵计算起来还是挺简单的。

     

    有了协方差矩阵的概念以后,我们继续前面的讨论:前面提到,我们需要一个这样的Y=XP(中心化的),它的各个维度之间的差异越大越好,也就是Y的协方差矩阵D的不同维度之间的协方差越小越好,形式化的表述为

    到了这一步就比较明了了。还记得我们需要一个什么样的D吗,这个D最好是一个对角阵,使得不在对角线上的元素均为0。问题转化为实对称矩阵的对角化问题。根据矩阵论的知识我们知道,一个是对称矩阵必存在一个正交矩阵P使得PTAP为对角阵。

    原则上说讲到这里就算讲完了,但是这个定力还有一个限制,A是线性无关的(或者说A有n个不同的特征值),此时把A的特征值从大到小排序,每一个特征值对应一个特征向量,我们把这些特征向量从左到右排起来就得到了P。如果我们取前 t 个特征值,那么P的大小为n*t,通过Y=XP,我们得到的 Y 就是一个m*t的矩阵(X是m*n的矩阵),从而起到了降维的作用。当然,如果P的大小为n*n,那么没有起到降维的目的,但是将X映射到了一个新的空间。

    从几何的角度来讲,其实线性变换就是空间映射,我们没有改变数据在空间中的位置,但是用了不同的基来表示他,关于基感觉这篇博客讲的很到位:

    http://blog.codinglabs.org/articles/pca-tutorial.html

     

    给出简单的matlab代码

    m=10;
    n=100;
    t=50;
    
    X=100*rand([m,n]);%% original data
    
    X=X-repmat(mean(X),m,1);%Centralization
    
    C=(X'*X)/m;
    
    [E,D]=eig(C);
    
    [dummy,order] = sort(diag(-D));
    E = E(:,order);%将特征向量按照特征值大小进行降序排列,每一列是一个特征向量
    D =D(:,order);
    
    Y=X*E(:,1:t); %Y

    原创文章,转载请注明出处,谢谢!

  • 相关阅读:
    1025WHERE执行顺序以及MySQL查询优化器
    1025基础REDIS
    1025关于explain的补充1
    1021mysql 全外连接
    python开发进程:进程开启方式&多进程
    python开发面向对象进阶:反射&内置函数
    python开发socket套接字:粘包问题&udp套接字&socketserver
    python开发面向对象基础:封装
    python开发模块基础:异常处理&hashlib&logging&configparser
    python开发面向对象基础:接口类&抽象类&多态&钻石继承
  • 原文地址:https://www.cnblogs.com/taokongcn/p/4147616.html
Copyright © 2011-2022 走看看