Fisher線性判別算法原理及實現 MATLAB
一、Fisher判別器原理
二、代碼實現
clc;
close all;
clear;
%% 生成數據
rng(2020); %指定一個種子
mu1 = [0 3];
sigma1 = [0.5 0; 0 0.5];
data1 = mvnrnd(mu1,sigma1,300); %生成一個300*2的矩陣,每一列的數據分別以0,3為均值,標準差都為0.5rng(2021); %指定一個種子
mu2 = [6 7];
sigma2 = [0.5 0; 0 0.5];
data2 = mvnrnd(mu2,sigma2,300); %生成一個300*2的矩陣,每一列的數據分別以6,7為均值,標準差都為0.5% rng(2022); %指定一個種子
% mu3 = [5 -5];
% sigma3 = [0.5 0;
% 0 0.5];
% data3 = mvnrnd(mu3,sigma3,300); %生成一個300*2的矩陣,每一列的數據分別以5,-5為均值,標準差都為0.5%%
figure(1),plot(data1(:,1),data1(:,2),'r+');hold on;
plot(data2(:,1),data2(:,2),'b*');hold on;
% figure(3),plot(data3(:,1),data3(:,2),'m^');hold on;%%
mu_1=mean(data1,1); %求data1數據集的均值 mean是求每一列的均值
mu_2=mean(data2,1); %求data2數據集的均值 mean是求每一列的均值
tmp=data1-repmat(mu_1,[size(data1,1),1]); %size(data1,1)返回data1第一維的大小 repmat將mu_1矩陣當成一個數,然后按后面的向量排列
S1=tmp'*tmp; %計算出S1 下面的操作是一樣的
tmp=data2-repmat(mu_2,[size(data2,1),1]);
S2=tmp'*tmp;
Sw=S1+S2;
w_star=Sw\(mu_1-mu_2)'; %這邊直接用結論 注意這里的mu_1 mu_2是行向量,而PPT上的為列向量,所以多了個轉置,實際上是一樣的%% Plot w_star
Data=[data1;data2]; %將兩個數據集合并成一個數據集
[xmin,ymin]=min(Data,[],1); %返回每一列的最小值
[xmax,ymax]=max(Data,[],1); %返回每一列的最大值
X=xmin:0.1:xmax; %采樣
k=w_star(2)/(w_star(1)+eps);%求出判別函數的斜率
plot(X,k*X-4,'k--'); %畫出判別函數,-4只是上下平移,并不會影響到判別函數的方向,這里只是為了不讓它穿過樣本%%
w_star=-w_star; %反向
y1=data1*w_star; %計算data1中每一個樣本的投影
y2=data2*w_star; %計算data2中每一個樣本的投影
figure(2),plot(y1,zeros(length(y1)),'r+');hold on;
plot(y2,zeros(length(y2)),'b*');hold on; %橫坐標是它們的投影,縱坐標取零是便于在一維中比較,可以發現兩類樣本分開了%% Sw-1Sb特征值分解
Sb=(mu_1-mu_2)'*(mu_1-mu_2); %注意這里的mu_1 mu_2是行向量,而PPT上的為列向量,所以多了個轉置,實際上是一樣的
Tmp=Sw\Sb; % Jf矩陣
[V,D]=eig(Tmp); %V儲存特征向量,D儲存特征值,D是個對角陣,特征值儲存在對角線上
D=diag(D); %提取出特征值行向量
[~,ind]=max(D);%最大特征值的序號
v=V(:,ind); %提取出與最大特征值對應的特征向量
k1=v(2)/(v(1)+eps);
figure(3),plot(data1(:,1),data1(:,2),'r+');hold on;
plot(data2(:,1),data2(:,2),'b*');hold on;
plot(X,k*X-4,'k--');hold on;
plot(X,k1*X-6,'m--'); %可以發現與第一種方法得到的結果是一樣的%% G(x)=w'x+w0
mu_y1=mean(y1); %計算data1數據投影的平均值
mu_y2=mean(y2); %計算data2數據投影的平均值
d=(mu_y1+mu_y2)/2; %d就是閾值
w0=-d;
figure(4),plot(data1(:,1),data1(:,2),'r+');hold on;
plot(data2(:,1),data2(:,2),'b*');hold on;
plot(X,k*X-4,'k--');hold on;
Y=(-w_star(1)*X-w0)/(w_star(2));%令G(x)=0解出y即可 注意x向量的第一個元素是橫坐標,第二個元素是縱坐標
plot(X,Y,'m-');
axis equal;
三、實驗結果
Figure 1:
Figure 2:
Figure 3:
Figure 4: