判别分析是根据所研究的个体的观测指标来推断该个体所属类型的一种方法,常见的判别分析有三种:距离判别、贝叶斯(bayes)判别、费舍尔(Fisher)判别。判别式的作用推荐阅读下面的博客:
木水小亭:数模系列(7):Fisher判别分析(Fisher Discriminant Analysis)zhuanlan.zhihu.com1.距离判别
在计算距离时,我们最常用的欧式距离,但是在统计学中,欧式距离就不适用了,统计学中常用马氏(Mahalanobis)距离来定义“距离”这个概念,马氏距离的计算公式如下:
x,y表示两点,
表示协方差。
当需要计算点与总体的马氏距离时:
,
-表示总体的均值。
先假设有
两个总体,
总体有
个样本,
总体有
个样本,每个样本有
个特征。现有一个样本
判断属于
还是
,则分别计算
的马氏距离,越小则越靠近。
我们以matlab自带的数据集fisheriris为例来演示距离判别如何实现分类判别的。具体matlab代码如下:
load fisheriris
function [biaoji,label_s,t_rate]judge(meas,species)
m=length(species);
index=randperm(m);%打乱顺序
species1=species(index);
meas1=meas(index,:);
meas1=meas1(:,3:4);
A=[];
B=[];
C=[];
for i=1:100
if species1(i)=="setosa"
A=[A;meas1(i,:)];
plot(meas1(i,1),meas1(i,2),"r*")
hold on
elseif species1(i)=="versicolor"
B=[B;meas1(i,:)];
plot(meas1(i,1),meas1(i,2),"bx")
hold on
elseif species1(i)=="virginica"
C=[C;meas1(i,:)];
plot(meas1(i,1),meas1(i,2),"g+")
hold on
end
end
Sample=meas1(101:m,:);
label_s=species1(101:m,:);
label=["setosa","versicolor","virginica"];
biaoji=distance_d(A,B,C,Sample,label);
label_s=string(label_s);
t_sum=0;
for i=1:length(biaoji)
if biaoji(i)==label_s(i)
t_sum=t_sum+1;
end
end
t_rate=t_sum/length(biaoji);
disp("判断准确率:"+num2str(t_rate));
end
%距离判别函数
function biaoji=distance_d(A,B,C,Sample,label)
ma=mean(A);
mb=mean(B);
mc=mean(C);
ca=cov(A);
cb=cov(B);
cc=cov(C);
a=length(A);
b=length(B);
c=length(C);
S=((a-1)*ca+(b-1)*cb+(c-1)*cc)/(a+b+c-3);
n=length(Sample);
for i=1:n
d(i,1)=(Sample(i,:)-ma)*inv(S)*(Sample(i,:)-ma)';
d(i,2)=(Sample(i,:)-mb)*inv(S)*(Sample(i,:)-mb)';
d(i,3)=(Sample(i,:)-mc)*inv(S)*(Sample(i,:)-mc)';
index=d(i,:)==min(d(i,:));
biaoji(i)=label(index);
end
end
输出结果的准确率是92%
fisheriris:数据包是matlab自带的数据集,包含两个数据集,meas是样本数据,species是样本的标记。
2.Fisher判别
Fisher判别的原理与步骤参考上面那篇博客,但是要注意Fisher判别的应用场景,Fisher应用场景是用于线性二类分析。这里补充具体的matlab代码:
function biaoji=fisher(A,B,Sample,label)
%类的均值向量
m1=mean(A);
m2=mean(B);
%各类内离散度矩阵
s1=zeros(2);
s2=zeros(2);
for i=1:1:length(A)
s1=s1+(A(i,:)-m1)'*(A(i,:)-m1);
end
for i=1:1:length(B)
s2=s2+(B(i,:)-m2)'*(B(i,:)-m2);
end
%总类内离散矩阵
sw=s1+s2;
%投影方向
w=inv(sw)*(m2-m1)';
%判别函数以及阈值T
T=0.5*(m1+m2)*w;
n=length(Sample);
% x=[1:0.1:5];
% yy=-w(1)/w(2)*x;
% plot(x,yy)
for i=1:n
y=Sample(i,:)*w;
if y>T
biaoji(i)=label(2);
else
biaoji(i)=label(1);
end
end
end
function [biaoji,label_s,t_rate]=judge_F(meas,species)
species_two=species(1:100);
m=length(species_two);
index=randperm(m);%打乱顺序
species1=species_two(index);
meas1=meas(index,:);
meas1=meas1(:,3:4);
A=[];
B=[];
for i=1:80
if species1(i)=="setosa"
A=[A;meas1(i,:)];
plot(meas1(i,1),meas1(i,2),"r*")
hold on
elseif species1(i)=="versicolor"
B=[B;meas1(i,:)];
plot(meas1(i,1),meas1(i,2),"bx")
hold on
end
end
Sample=meas1(81:m,:);
label_s=species1(81:m,:);
label=["setosa","versicolor"];
biaoji=fisher(A,B,Sample,label);
label_s=string(label_s);
t_sum=0;
for i=1:length(biaoji)
if biaoji(i)==label_s(i)
t_sum=t_sum+1;
end
end
t_rate=t_sum/length(biaoji);
disp("判断准确率:"+num2str(t_rate));
end
注意这里将三个标签拿走了一个变成了一个二分类问题。