首页 > 代码库 > 关于fisher判别的一点理解
关于fisher判别的一点理解
最近一个朋友问这方面的一些问题,其实之前也就很粗略的看了下fisher,真正帮别人解答问题的时候才知道原来自己也有很多东西不懂。下面小结下自己对fisher判别的理解:
其实fisher和PCA差不多,熟悉PCA的人都知道,PCA其实就是在寻找一个子空间。这个空间怎么来的呢,先求协方差矩阵,然后求这个协方差矩阵的特征空间(特征向量对应的空间),选取最大的特征值对应的特征向量组成特征子空间(比如说k个,相当于这个子空间有k维,每一维代表一个特征,这k个特征基本上可以涵盖90%以上的信息)。那么我们把样本投影在这个子空间,原来那么多维的信息就可以用这k维的信息代替了,也就是说降维了。至于PCA为啥要用求协方差矩阵然后求特征子空间的方法,这个数学上有证明,记得在某篇文章上看过,有兴趣的可以找找,看看证明。
那么fisher空间又是怎么一回事呢,其实fisher判别和PCA是在做类似的一件事,都是在找子空间。不同的是,PCA是找一个低维的子空间,样本投影在这个空间基本不丢失信息。而fisher是寻找这样的一个空间,样本投影在这个空间上,类内距离最小,类间距离最大。那么怎么求这个空间呢,类似于PCA,求最大特征值对应的特征向量组成的空间。
假设我们给定C类样本,我们先求sw(类内离散度)和sb(类间离散度),如下所示:
那么样本投影在新的投影空间中类间离散度为:
样本投影在新的投影空间中类内离散度为:
那么只要我们最大化就可以使得样本投影在这个空间上类内离散度最小,类间离散度最大,其中,w就是我们要找的投影方向。但是问题就来了,如果sw是一个奇异矩阵,那么这个式子是求不出来的。所以就有高人想到用这个式子代替:
这里的B是一个权衡因子,权衡类间距离和类内距离谁的比重大,试验中可以根据需要调节。也就是说,只要我们可以根据梯度下降法迭代w,使得最大化,这个w就是我们所要求的最好的投影方向。在fisher中我们去w为最大特征值对应的那个特征向量,也就是说w是一个nx1的向量。当然我们也可以取w为最大几个特征值对应的那几个特征向量,但是这样我们所求的就是一个矩阵,达不到求损失(一般是具体的数)函数的目的。
如果sw是非奇异矩阵,那么我们可以用更为简单的公式求解w,如下:
好了,下面来给出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
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:
实验效果如下:
关于fisher判别的一点理解