• 关于fisher判别的一点理解


        最近一个朋友问这方面的一些问题,其实之前也就很粗略的看了下fisher,真正帮别人解答问题的时候才知道原来自己也有很多东西不懂。下面小结下自己对fisher判别的理解:

        其实fisher和PCA差不多,熟悉PCA的人都知道,PCA其实就是在寻找一个子空间。这个空间怎么来的呢,先求协方差矩阵,然后求这个协方差矩阵的特征空间(特征向量对应的空间),选取最大的特征值对应的特征向量组成特征子空间(比如说k个,相当于这个子空间有k维,每一维代表一个特征,这k个特征基本上可以涵盖90%以上的信息)。那么我们把样本投影在这个子空间,原来那么多维的信息就可以用这k维的信息代替了,也就是说降维了。至于PCA为啥要用求协方差矩阵然后求特征子空间的方法,这个数学上有证明,记得在某篇文章上看过,有兴趣的可以找找,看看证明。

        那么fisher空间又是怎么一回事呢,其实fisher判别和PCA是在做类似的一件事,都是在找子空间。不同的是,PCA是找一个低维的子空间,样本投影在这个空间基本不丢失信息。而fisher是寻找这样的一个空间,样本投影在这个空间上,类内距离最小,类间距离最大。那么怎么求这个空间呢,类似于PCA,求最大特征值对应的特征向量组成的空间。  当我们取最大几个特征值对应的特征向量组成特征空间时(这里指出,最佳投影轴的个数d<=c-1,这里c是类别数),最佳投影矩阵如下:

                                                  image

        其实在文章Eigenfaces vs Fisherfaces :recognition using class specific linear projection中给出了PCA和LDA比较直观的解释,文中对一个二维的数据进行分析,PCA和LDA都是把二维数据降到一个一维空间,那么其实PCA使得数据投影在这个一维空间总的离散度最大,我的理解是这样的,如果数据在某一维上比较离散,说明这维特征对数据的影响比较大,也就是说这维特征是主成分。而LDA呢,数据投影在这个空间,类内离散度最小,类间离散度最大,数据变得线性可分,如文中所说:

                                                         image

        假设我们给定C类样本,我们先求sw(类内离散度)和sb(类间离散度),如下所示:

                            image

        那么样本投影在新的投影空间中类间离散度为:

                                                                                           image

       样本投影在新的投影空间中类内离散度为:

                                                                                              image

        那么只要我们最大化image就可以使得样本投影在这个空间上类内离散度最小,类间离散度最大,其中,w就是我们要找的投影方向。但是问题就来了,如果sw是一个奇异矩阵,那么这个式子是求不出来的。所以就有高人想到用这个式子代替:

                                                                      image

        这里的B是一个权衡因子,权衡类间距离和类内距离谁的比重大,试验中可以根据需要调节。也就是说,只要我们可以根据梯度下降法迭代w,使得image最大化,这个w就是我们所要求的最好的投影方向。在fisher中最大特征值对应的特征向量就是最佳投影方向,如果我们取最大k个特征值对应的特征向量作为投影方向,那么最终样本就投影到了这样的一个k维子空间,在这个子空间里面类内最小,类间最大。

                          image

        另外还有一种方法来解决sw的奇异性引起的问题,比如如果我们试验中处理的数据时人脸图片,由于人脸图片之间相关性很大,所以sw很容易就是一个奇异矩阵,但是如果我们先用PCA对样本进行降维,去掉相关性,那么这样我们再用LDA就不会遇到sw奇异性的为题了,实际中这种方法也是很常用的,在用LDA的时候往往先使用PCA降维。

        好了,下面来给出fisher的一个简单的matlab代码:

        main.m

       1: clear; clc;
       2: %定义两类样本的空间范围 
       3: x1min=2;x1max=6; 
       4: y1min=-4,y1max=0; 
       5: x2min=6,x2max=10; 
       6: y2min=2,y2max=6; 
       7: %产生两类2D空间的样本 
       8: c1=createSwatch(x1min,x1max,y1min,y1max,100); 
       9: c2=createSwatch(x2min,x2max,y2min,y2max,80); 
      10: %获取最佳投影方向 
      11: w=fisher_w(c1,c2); 
      12: %计算将样本投影到最佳方向上以后的新坐标 
      13: cm1=c1(1,:)*w(1)+c1(2,:)*w(2); 
      14: cm2=c2(1,:)*w(1)+c2(2,:)*w(2); 
      15: cc1=[w(1)*cm1;w(2)*cm1]; 
      16: cc2=[w(1)*cm2;w(2)*cm2]; 
      17: %打开图形窗口 
      18: figure; 
      19: %绘制多图 
      20: hold on; 
      21: %绘制第一类的样本 
      22: plot(c1(1,:),c1(2,:),'rp'); 
      23: %绘制第二类的样本 
      24: plot(c2(1,:),c2(2,:),'bp'); 
      25: %绘制第一类样本投影到最佳方向上的点 
      26: plot(cc1(1,:),cc1(2,:),'r+'); 
      27: %绘制第二类样本投影到最佳方向上的点 
      28: plot(cc2(1,:),cc2(2,:),'b+'); 
      29: w=10*w; 
      30: %画出最佳方向 
      31: line([-w(1),w(1)],[-w(2),w(2)],'color','k'); 
      32: axis([-10,10,-10,10]); 
      33: grid on; 
      34: hold off; 

    fisher_w.m

       1: function w = fisher_w(c1,c2) 
       2: %利用Fisher准则函数确定最佳投影方向 
       3: %c1和c2分别为两类样本的样本矩阵
       4: %得到样本矩阵的尺寸信息 
       5: %样本矩阵的行数代表样本的维数 
       6: %样本矩阵的列数代表样本的个数 
       7:     size1=size(c1); 
       8:     size2=size(c2); 
       9:     %计算两类样本的均值向量 
      10:     m1=sum(c1,2)/size1(2); 
      11:     m2=sum(c2,2)/size2(2); 
      12:     %样本向量减去均值向量 
      13:     c1=c1-m1(:,ones(1,size1(2))); 
      14:     c2=c2-m2(:,ones(1,size2(2))); 
      15:     %计算各类的类内离散度矩阵 
      16:     S1=c1*c1.'; 
      17:     S2=c2*c2.'; 
      18:     %计算总类内离散度矩阵 
      19:     Sw=S1+S2; 
      20:     %计算最佳投影方向向量 
      21:     w=Sw^-1*(m1-m2); 
      22:     %将向量长度变成1 
      23:     w=w/sqrt(sum(w.^2)); 
      24: end
    createSwatch.m
       1: function swatch=createSwatch(xmin,xmax,ymin,ymax,num,varargin) 
       2:  
       3: xlen = abs(xmax - xmin);
       4: ylen = abs(ymax - ymin);
       5:  
       6: if numel(varargin)>0 && isa(varargin{1},'function_handle') 
       7:     f = varargin{1}; 
       8: else
       9:     f = @rand;
      10: end 
      11: swatch=[xlen*f(1,num)+min(xmax,xmin);ylen*f(1,num)+min(ymax,ymin)]; 
      12:  
      13: end
      14:  

    实验效果如下:

                                                                   image

  • 相关阅读:
    iOS核心动画高级技巧之核心动画(三)
    iOS核心动画高级技巧之图层变换和专用图层(二)
    iOS核心动画高级技巧之CALayer(一)
    Swift高级语法学习总结
    Swift基础语法学习总结
    Swift语法总结补充(一)
    【思图佳预约(一)】在做预约挂号小程序时,text标签出现一截多余的空白?
    【随笔】清除浮动float的几种办法
    ----原生js实现飞机大战小游戏<第二篇>----@半城言沙
    ----原生js实现飞机大战小游戏<第一篇>----@半城言沙
  • 原文地址:https://www.cnblogs.com/txg198955/p/4106682.html
Copyright © 2020-2023  润新知