朴素贝叶斯

数据集链接

R,1,1,5,5
L,1,2,1,1
B,1,2,1,2
R,1,2,1,3

625个训练样例,每个样例有4个属性,每个属性值可以取值{1,2,3,4,5}。数据集中的每个样例都有标签"L","B"或"R"。

我们在这里序号末尾为1的样本当作测试集,共有63个,其他的作为训练集,共有562个

第一步,实现类的标签"L","B","R"转换成数字1,2,3

ex=importdata('balance-scale.data.txt');  %读入文件,文件名balance-scale.data,要放在matlab路径下面
X=ex.data;  %就是一个结构体,ex.data是[625x4]double,,ex.textdata是文本
m=size(ex.textdata);  %数据大小,返回625,用于后面循环
Y=zeros(m);
for i=1:m
    if strcmp(ex.textdata(i),'L')==1   %strcmp比较后面两个字符串相等不相等,true1  false0
        Y(i)=1;
    elseif strcmp(ex.textdata(i),'B')==1
        Y(i)=2;
    else Y(i)=3;  %if, else if,  else
    end
end

第二步,参数估计

%朴素贝叶斯算法实现分类问题(三类y=1,y=2,y=3)
%我们把所有数字序号末尾为1的留作测试集,其他未训练集
m=625;   %样本总数
m1=562;  %训练集样本数量
m2=63;  %测试集样本数量

%三类样本数量分别记为count1,count2,count3
count1=0;
count2=0;
count3=0;
                  %count_1(i,j)表示在第一类(y=1)的情况下,第i个属性是j的样本个数 比如count_1(2,3)=6,在第一类样本里,第二个属性是3的有6个样本
count_1=zeros(4,5);
                   %count_2(i,j)表示在第二类(y=2)的情况下,第i个属性是j的样本个数
count_2=zeros(4,5);
                   %count_3(i,j)表示在第三类(y=3)的情况下,第i个属性是j的样本个数
count_3=zeros(4,5);


ii=1;     %用来标识测试集的序号


for i=1:m   %样本总数
    if mod(i,10)==1    %我们把所有数字序号末尾为1的留作测试集XX,其他未训练集
        XX(ii,:)=X(i,:);
        YY(ii)=Y(i);
        ii=ii+1;  %ii是测试集的数量
    else
        x=X(i,:);
        if Y(i)==1 % Y是625行的向量,1 2 3是类别RLB
           count1=count1+1;
            for j=1:4    %指示第j个属性1234
                for k=1:5    %第j个属性为哪个值12345
                    if x(j)==k    % x是数据集第i个,有4个值,每个值有5种取值
                      count_1(j,k)=count_1(j,k)+1;  %累加器
                       break;  %break只跳出最近的for循环,因为第j个属性只会有1种取值,已经取到了就没必要继续循环了,浪费计算量
                    end
                end
            end
        elseif Y(i)==2
            count2=count2+1;
            for j=1:4    %指示第j个属性
                for k=1:5    %第j个属性为哪个值
                    if x(j)==k
                       count_2(j,k)=count_2(j,k)+1;
                       break;
                    end
                end
            end
        else count3=count3+1;
            for j=1:4    %指示第j个属性
                for k=1:5    %第j个属性为哪个值
                    if x(j)==k
                       count_3(j,k)=count_3(j,k)+1;
                       break;
                    end
                end
            end
        end
    end
  %以上的循环就把 count_1 count_2 count_3 三个4x5的矩阵算出来了

    %分别计算三类概率y1=p(y=1)、y2=p(y=2)、y3=p(y=3)的估计值
    y1=count1/m1;  % P(y=1)  m1=562;  训练集样本数量
    y2=count2/m1;
    y3=count3/m1;


    %y_1(i,j)表示在第一类(y=1)的情况下,第i个属性取值为j的概率估计值 P(属性i=j|y=1)
    %y_2(i,j)表示在第二类(y=2)的情况下,第i个属性取值为j的概率估计值
    %y_3(i,j)表示在第三类(y=3)的情况下,第i个属性取值为j的概率估计值
    for i=1:4
        for j=1:5
            y_1(i,j)=count_1(i,j)/count1;
            y_2(i,j)=count_2(i,j)/count2;
            y_3(i,j)=count_3(i,j)/count3;
        end
    end
end


%做预测,p1,p2,p3分别表示输入值xx为第1,2,3类的概率




cc=0;   %用cc表示正确分类的样本
for i=1:m2       %m2=63; 测试集样本数量
 %  y_1(i,j)表示在第一类(y=1)的情况下,第i个属性取值为j的概率估计值 P(属性i=j|y=1)
 %  y1=p(y=1)
 %  p1,p2,p3分别表示输入值xx为第1,2,3类的概率 % p(是第一类|四个参数ABCD)=p(四个参数ABCD|是第一类)p(是第一类)/p(四个参数ABCD)=p(A|第一类)p(B|第一类)p(C|第一类)p(D|第一类)p(是第一类)/p(ABCD)
 xx=XX(i,:); yy=YY(i); p1=y1 * y_1(1,xx(1)) * y_1(2,xx(2)) * y_1(3,xx(3)) * y_1(4,xx(4)); p2=y2*y_2(1,xx(1))*y_2(2,xx(2))*y_2(3,xx(3))*y_2(4,xx(4)); p3=y3*y_3(1,xx(1))*y_3(2,xx(2))*y_3(3,xx(3))*y_3(4,xx(4)); %下面分别输出三类的概率 %ans1=p1/(p1+p2+p3) %ans2=p2/(p1+p2+p3)
 %ans3=p3/(p1+p2+p3) 
%下面3个if做的是累加,看预测对了几个,有几个和测试集的符合

if p1>p2&&p1>p3 % &&可以当成&来理解 且 if yy==1 cc=cc+1; end end if p2>p1&&p2>p3 if yy==2 cc=cc+1; end end if p3>p1&&p3>p2 if yy==3 cc=cc+1; end end end%拿训练集做测试集,得到的正确率cc/m2