理论部分:
评述:贝叶斯方法唯一严重的缺点是:计算条件密度函数的困难。而多元高斯模型可以为许多真实的密度提供一个充分的近似,但在另外的很多问题中密度形式却与高斯形式相差很远。
二分类器实现部分:
数据:数据集有3000个样本,每个样本是三维的,其中两个位是特征(如光泽和尾长),一位是标签(类别,+1表示鱼类1,-1表示鱼类2)。选择前面2500个样本作为训练数据,后面500个样本作为测试数据。这里要求使用贝叶斯理论来鉴别这些测试数据。
打开数据集
代码实现:
load data1;
right=0;
x=zeros(2,1);
%假设它们都符合二元高斯分布
u1=zeros(2,1);%值为1的类的均值
v1=zeros(2,2);%值为1的类的协方差
u2=zeros(2,1);%值为2的类的均值
v2=zeros(2,2);%值为2的类的协方差
sum1=0;
sum2=0;
pior1=0; %先验概率
posterior1=0; %后验概率
likehood1=0; %似然
pior2=0; %先验概率
posterior2=0; %后验概率
likehood2=0; %似然
for i=1:1:2500%求先验
if(data(3,i)==1)
sum1=sum1+1;
else
sum2=sum2+1;
end
end
pior1=sum1/(sum1+sum2); %先验概率
pior2=sum2/(sum1+sum2); %先验概率
for m=2501:1:3000 %测试循环
for i=1:1:2500%求均值
if(data(3,i)==1)
u1(1,1)=u1(1,1)+data(1,i);
u1(2,1)=u1(2,1)+data(2,i);
else
u2(1,1)=u2(1,1)+data(1,i);
u2(2,1)=u2(2,1)+data(2,i);
end
end
u1=u1/2500;
u2=u2/2500;
for i=1:1:2500%求协方差
if(data(3,i)==1)
x(1,1)=data(1,i);
x(2,1)=data(2,i);
v1=v1+(x-u1)*(x-u1)';
else
x(1,1)=data(1,i);
x(2,1)=data(2,i);
v2=v2+(x-u2)*(x-u2)';
end
end
v1=v1/2500;
v2=v2/2500;
%求似然
x(1,1)=data(1,m);
x(2,1)=data(2,m);
likehood1=1/(det(v1)^0.5)*exp(-0.5*(x-u1)'*(v1^-1)*(x-u1));%相同的项不乘了
likehood2=1/(det(v2)^0.5)*exp(-0.5*(x-u2)'*(v2^-1)*(x-u2));
%求后验
posterior1=pior1*likehood1; %后验
posterior2=pior2*likehood2; %后验
%这里直接使用了判别函数g(x)= p(w1|x)-p(w2|x)=p(x|w1)p(w1)-p(x|w2)p(w2)
if(((posterior1>posterior2)&&(data(3,m)==1))||((posterior1<posterior2)&&(data(3,m)==-1)))
right=right+1;
end
end
arr=right/500
测试得到的正确率为:88.6%
代码实现二:
1. 贝叶斯分类器(bayesian_Classify.m)
function predict = bayesian_Classify(newInput, dataSet, labels)
%newInput:测试数据(是一个列向量)
%dataSet: 训练样本集(其中,一列代表一个样本)
%labels: 训练样本的标签(类别)
class=unique(labels); %类别,unique(去除重复的元素)
[d,n]= size(dataSet); %d:表示训练样本的维数,n:表示样本的个数
%第一步:二元高斯模型参数的估计(使用训练样本来进行估计,可以使用最大似然估计)
%假设它们都符合二元高斯分布
u1=zeros(2,1);%值为1的类的均值
v1=zeros(2,2);%值为1的类的协方差
u2=zeros(2,1);%值为2的类的均值
v2=zeros(2,2);%值为2的类的协方差
%求均值
for i=1:1:n
if(labels(i)==1)
u1(1,1)=u1(1,1)+dataSet(1,i);
u1(2,1)=u1(2,1)+dataSet(2,i);
else
u2(1,1)=u2(1,1)+dataSet(1,i);
u2(2,1)=u2(2,1)+dataSet(2,i);
end
end
u1=u1/n;
u2=u2/n;
%求协方差
x=zeros(2,1);
for i=1:1:n%求协方差
if(labels(i)==1)
x(1,1)=dataSet(1,i);
x(2,1)=dataSet(2,i);
v1=v1+(x-u1)*(x-u1)';
else
x(1,1)=dataSet(1,i);
x(2,1)=dataSet(2,i);
v2=v2+(x-u2)*(x-u2)';
end
end
v1=v1/n;
v2=v2/n;
%第二步:求先验
pior1=0; %先验概率
pior2=0; %先验概率
sum1=0;
sum2=0;
for i=1:1:n
if(labels(i)==1)
sum1=sum1+1;
else
sum2=sum2+1;
end
end
pior1=sum1/(sum1+sum2); %先验概率
pior2=sum2/(sum1+sum2); %先验概率
%第三步:求似然
likehood1=0; %似然
likehood2=0; %似然
x= newInput; %测试数据
%注意到:相同的项没有乘
likehood1=1/(det(v1)^0.5)*exp(-0.5*(x-u1)'*(v1^-1)*(x-u1));
likehood2=1/(det(v2)^0.5)*exp(-0.5*(x-u2)'*(v2^-1)*(x-u2));
%第四步:求后验
posterior1=0; %后验概率
posterior2=0; %后验概率
posterior1=pior1*likehood1; %后验
posterior2=pior2*likehood2; %后验
%第五步:判别函数:g(x)= p(w1|x)-p(w2|x)=p(x|w1)p(w1)-p(x|w2)p(w2)
%判别函数gi(x)=p(x|wi)P(wi);gj(x)=p(x|wj)P(wj)
g=posterior1 - posterior2;
if g > 0
predict = 1;
else
predict = -1;
end
2.贝叶斯分类器测试(testDemo.m)
load data1;
%数据集中的前面2500个作为训练样本,后面500个数据作为测试样本
%训练数据和标签
train_x = data(1:end-1,1:2500);
train_y = data(end,1:2500);
%测试数据和标签
test_x = data(1:end-1,2501:end);
test_y = data(end,2501:end);
[n,m]=size(test_x); %m是测试样本的个数
numTestSamples = m;
right = 0;
%测试数据
tic
for i = 1:1:numTestSamples
%贝叶斯分类器
predict = bayesian_Classify(test_x(:,i), train_x, train_y);
if predict == test_y(i)
right = right + 1;
end
end
%精度
accuray = right/numTestSamples
toc
3.测试结果:
accuray =
0.8860
Elapsed time is 5.488179 seconds.