MATLAB身高体重识别性别

用身高和体重数据进行性别分类的实验报告(二)

一、 基本要求

1、试验非参数估计,体会与参数估计在适用情况、估计结果方面的异同。

2、试验直接设计线性分类器的方法,与基于概率密度估计的贝叶斯分类器进行比较。

3、体会留一法估计错误率的方法和结果。

二、具体做法

1、在第一次实验中,挑选一次用身高作为特征,并且先验概率分别为男生0.5,女生0.5的情况。改用Parzen窗法或者kn近邻法估计概率密度函数,得出贝叶斯分类器,对测试样本进行测试,比较与参数估计基础上得到的分类器和分类性能的差别。

2、同时采用身高和体重数据作为特征,用Fisher线性判别方法求分类器,将该分类器应用到训练和测试样本,考察训练和测试错误情况。将训练样本和求得的决策边界画到图上,同时把以往用Bayes方法求得的分类器也画到图上,比较结果的异同。

3、选择上述或以前实验的任意一种方法,用留一法在训练集上估计错误率,与在测试集上得到的错误率进行比较。

三、原理简述及程序框图

1、挑选身高(身高与体重)为特征,选择先验概率为男生0.5女生0.5的一组用Parzen窗法来求概率密度函数,再用贝叶斯分类器进行分类。

以身高为例

本次实验我们组选用的是正态函数窗,即,窗宽为h是调节的参量,N是样本个数) ,(d表示维度)。因为区域是一维的,所以体积为Parzen公式为。

故女生的条件概率密度为 

clc;
clear all;
[FH FW]=textread('C:\Users\xuyd\Desktop\homework\FEMALE.txt','%f%f');
[MH MW]=textread('C:\Users\xuyd\Desktop\homework\MALE.txt','%f%f');
FA=[FH FW];
MA=[MH MW];
N1=max(size(FA));
h1=4;
hn1=h1/(sqrt(N1));
VN1=h1/(sqrt(N1));
N2=max(size(MA));
h2=4;
hn2=h2/(sqrt(N2));
VN2=h2/(sqrt(N2));
[tH tW]=textread('C:\Users\xuyd\Desktop\homework\test2.txt','%f%f%*s');
X=[tH tW];
[M N]=size(X);
s=zeros(M,1);
A=[X(:,1) X(:,2) s];
error=0;
errorgirl=0;
errorboy=0;
errorrate=0;
errorgirlrate=0;
errorboyrate=0;
girl=0;
boy=0;
bad=0;
for k=1:M  %测试集
    x=A(k);
    p=0.5;%p为属于女生的先验概率,则1-p为男生的先验概率
      for i=1:N1
          pp(i)=1/sqrt(2*pi)*exp(-0.5*(abs(x-FA(i)))^2/(hn1^2));%pp(i)是窗函数
      end
      p1=sum(1/VN1*pp'); 
      y1=1/N1*p1;%是女生的条件概率密度函数
      for j=1:N2
          qq(j)=1/sqrt(2*pi)*exp(-0.5*(abs(x-MA(j)))^2/(hn2^2));
      end
      q1=sum(1/VN2*qq');
      y2=1/N2*q1;%男生的概率密度函数,即其条件概率
      g=p*y1-(1-p)*y2;%g为判别函数
     if g>0
         if k<=50
    s(k,1)=0;%判为女生
    girl=girl+1;
        else 
            errorboy=errorboy+1;
         end
     elseif g<0
         if k<=50
             errorgirl=errorgirl+1;
         else
        s(k,1)=1;%判为男生
        boy=boy+1;
         end
        else
           s(k,1)=-2;%不能判别是指等于0时的情况
           bad=bad+1;
     end
     end 	
errorgirl
errorboy
bad
girl=errorboy+girl
boy=boy+errorgirl
error=errorgirl+errorboy
errorgirlrate=errorgirl/50
errorboyrate=errorboy/250
errorrate=error/M
 %特征是身高与体重,先验概率为0.5、0.5时用Parzen窗法,贝叶斯分类器。
clc;
clear all;
[FH FW]=textread('C:\Users\xuyd\Desktop\homework\FEMALE.txt','%f%f');
[MH MW]=textread('C:\Users\xuyd\Desktop\homework\MALE.txt','%f%f');
FA=[FH FW];
MA=[MH MW];
N1=max(size(FA));
h1=7;
hn1=h1/(sqrt(N1));
VN1=hn1^2;
N2=max(size(MA));
h2=7;
hn2=h2/(sqrt(N2));
VN2=hn2^2;
[tH tW]=textread('C:\Users\xuyd\Desktop\homework\test2.txt','%f%f%*s');
X=[tH tW];
[M N]=size(X);
s=zeros(M,1);
error=0;
errorgirl=0;
errorboy=0;
errorrate=0;
errorgirlrate=0;
errorboyrate=0;
girl=0;
boy=0;
bad=0;
for k=1:M
   A=[X(k,1) X(k,2)];
    x=A;
    p=0.5;%p为属于女生的先验概率,则1-p为男生的先验概率
    pp=0;  
    for i=1:N1
          fa=[FA(i,1) FA(i,2)];
          n=1/sqrt(2*pi)*exp(-0.5*abs((x-fa)*(x-fa)')/(hn1^2));
          pp=pp+n;
    end
      p1=1/VN1*pp';
      y1=1/N1*p1;%是女生的条件概率密度函数
      qq=0;
      for j=1:N2
          ma=[MA(j,1) MA(j,2)];
          m=1/sqrt(2*pi)*exp(-0.5*abs((x-ma)*(x-ma)')/(hn2^2));
          qq=m+qq;
      end
      q1=sum(1/VN2*qq');
      y2=1/N2*q1;%男生的概率密度函数,即其条件概率
      g=p*y1-(1-p)*y2;%g为判别函数
     if g>0
         if k<=50
    s(k,1)=0;%判为女生
    girl=girl+1;
        else 
            errorboy=errorboy+1;
         end
     elseif g<0
         if k<=50
             errorgirl=errorgirl+1;
         else
        s(k,1)=1;%判为男生
        boy=boy+1;
         end
        else
           s(k,1)=-2;%不能判别是指等于0时的情况
           bad=bad+1;
     end
     end 
errorgirl
errorboy
bad
girl=errorboy+girl
boy=boy+errorgirl
error=errorgirl+errorboy
errorgirlrate=errorgirl/50
errorboyrate=errorboy/250
errorrate=error/M

 
 	
%用fisher线性判别法求阈值
function [w,y0]=fisher(AA,BB)
A=AA';
B=BB';
[k1,l1]=size(A);
[k2,l2]=size(B);
M1=sum(AA);
M1=M1';
M1=M1/l1;%男生均值向量
M2=sum(BB);
M2=M2';
M2=M2/l2;%女生均值向量
S1=zeros(k1,k1);%建立矩阵
S2=zeros(k2,k2);
for i=1:l1
    S1=S1+(A(:,i)-M1)*((A(:,i)-M1).');%男生的类内离散度矩阵
end
for i=1:l2
    S2=S2+(B(:,i)-M2)*((B(:,i)-M2).');%女生的类内离散度矩阵
end
Sw=0.5*S1+0.5*S2;%总类内离散度矩阵,先验概率0.5
w=inv(Sw)*(M1-M2);%两列
wT=w';%wT就是使Fisher准则函数JF(w)取极大值时的解,也就是d维X空间到1维Y空间的最好的投影方向
for i=1:l1
    Y1(i)=wT(1,1)*A(1,i)+wT(1,2)*A(2,i);%求出二维男生样本集映射到一维时的量
end
for i=1:l2
    Y2(i)=wT(1,1)*B(1,i)+wT(1,2)*B(2,i);%求出二维女生样本集映射到一维时的量
end
m1=sum(Y1)/l1;
m2=sum(Y2)/l2;
y0=(l1*m1+l2*m2)/(l1+l2);%
%用fisher线性判别函数来判断
clc
clear all
[filename,pathname,filterindex] = uigetfile('*.txt', '请读入男生训练集');
fileAddrs = [pathname,filename];
[A1 A2]=textread(fileAddrs,'%f%f');
[filename,pathname,filterindex] = uigetfile('*.txt', '请读入女生训练集');
fileAddrs = [pathname,filename];
[B1 B2]=textread(fileAddrs,'%f%f');
AA=[A1 A2];
BB=[B1 B2];
[w,y0]=fisher(AA,BB);
wT=w';
girl=0;
boy=0;
bad=0;
errorgirl=0;
errorboy=0;
error=0;
errorgirlrate=0;
errorboyrate=0; 
errorrate=0;
[filename,pathname,filterindex] = uigetfile('*.txt', '请读入测试集');
fileAddrs = [pathname,filename];
[T1 T2]=textread(fileAddrs,'%f%f%*s');
TT=[T1 T2];T=TT';
[k3 l3]=size(T);
for k=1:50
    y(k)=wT*T(:,k);
    if y(k)>y0
        errorgirl=errorgirl+1;
    else if y(k)<y0
            girl=girl+1;
        else
            bad=bad+1;
        end
    end
end
for k=51:300
    y(k)=wT*T(:,k);
     if y(k)>y0
        boy=boy+1;
    else if y(k)<y0
           errorboy=errorboy+1;
        else
            bad=bad+1;
        end
     end
end
errorgirl
errorboy
bad
girl=errorboy+girl
boy=boy+errorgirl
error=errorgirl+errorboy
errorgirlrate=errorgirl/50
errorboyrate=errorboy/250
errorrate=error/l3
%画图

[filename,pathname,filterindex] = uigetfile('*.txt', '请读入男生训练集');
fileAddrs = [pathname,filename];
[A1 A2]=textread(fileAddrs,'%f%f');
[filename,pathname,filterindex] = uigetfile('*.txt', '请读入女生训练集');
fileAddrs = [pathname,filename];
[B1 B2]=textread(fileAddrs,'%f%f');
AA=[A1 A2];
BB=[B1 B2];
A=AA';
B=BB';
[k1,l1]=size(A);
[k2,l2]=size(B);
[w,y0]=fisher(AA,BB);
for i=1:l1
    x=A(1,i);
    y=A(2,i);%x是身高,y是体重
    plot(x,y,'R.');
    hold on
end
for i=1:l2
    x=B(1,i);
    y=B(2,i);
    plot(x,y,'G.');
    hold on
end
a1=min(A(1,:));%男生身高最小值
a2=max(A(1,:));%男生身高最大值
b1=min(B(1,:));%女生身高最小值
b2=max(B(1,:));%女生身高最大值
a3=min(A(2,:));%男生体重最小值
a4=max(A(2,:));%男生体重最大值
b3=min(B(2,:));%女生体重最小值
b4=max(B(2,:));%女生体重最大值
if a1<b1
    a=a1;
else
    a=b1;%a是所有人中身高最小值
end
if a2>b2
    b=a2;
else
    b=b2;%b是所有人中身高最大值
end
if a3<b3
    c=a3;
else
    c=b3;%c是所有人中体重最小值
end
if a4>b4
    d=a4;
else
    d=b4;%d为所有人中体重最大值
end
x=a:0.01:b;
y=(y0-x*w(1,1))/w(2,1);
plot(x,y,'B');
hold on;
%身高体重相关,判别测试样本
%手动先验概率
P1=0.5;
P2=0.5;
FA=A;
MA=B;
a=cov(FA')*(length(FA)-1)/length(FA);
b=cov(MA')*(length(MA)-1)/length(MA);
W1=-1/2*inv(a);
W2=-1/2*inv(b);
Ave1=(sum(FA')/length(FA))';
Ave2=(sum(MA')/length(MA))';
w1=inv(a)*Ave1;
w2=inv(b)*Ave2;
w10=-1/2*Ave1'*inv(a)*Ave1-1/2*log(det(a))+log(P1);
w20=-1/2*Ave2'*inv(b)*Ave2-1/2*log(det(b))+log(P2);
    syms x ;
    syms y ;
    h=[x y]';
   h1=h'*W1*h+w1'*h+w10;
   h2=h'*W2*h+w2'*h+w20 ;
    h=h1-h2;
    ezplot(h,[130,200,30,100])
%功能:应用Fisher准则判断一个身高体重二维数据的性别
vector=[x;y];
yy=(w.')*vector;
if yy>y0
    value=2;%表示样本是男生
else
    value=1;%表示样本是女生
end
%功能:使用留一法求训练样本错误率
[A1 A2]=textread('C:\Users\Administrator\Desktop\模式识别\homework\MALE.txt','%f%f');
[B1 B2]=textread('C:\Users\Administrator\Desktop\模式识别\homework\FEMALE.txt','%f%f');
AA=[A1 A2];
BB=[B1 B2];
A=AA';
B=BB';
m1=2;
m2=2;
n1=50;
n2=50;
tempA=zeros(m1,n1-1);
count=0;
for i=1:n1
    for j=1:(i-1)
        tempA(:,j)=A(:,j);
    end
    for j=(i+1):n1
        tempA(:,j-1)=A(:,j);
    end
    [w,y0]=fisher((tempA.'),BB);
    flag=classify_CH(A(1,i),A(2,i),w,y0);
    if flag==1
        count=count+1;
    end
end
tempB=zeros(m2,n2-1);
for i=1:n2
    for j=1:(i-1)
        tempB(:,j)=B(:,j);
    end
    for j=(i+1):n2
        tempB(:,j-1)=B(:,j);
    end
    [w,y0]=fisher(AA,(tempB.'));
    flag=classify_CH(B(1,i),B(2,i),w,y0);
    if flag==2
        count=count+1;
    end
end
error_ratio=count/(n1+n2)
%使用留一法求测试样本错误率
[T1 T2]=textread('C:\Users\Administrator\Desktop\模式识别\homework\test2.txt','%f%f%*s');
TT=[T1 T2];
T=TT';
[k3 l3]=size(T);
TG=zeros(2,50);
TB=zeros(2,250);
for i=1:50
    TG(:,i)=T(:,i);
end
for j=51:l3
    TB(:,j-50)=T(:,j);
end
m1=2;
m2=2;
n1=50;
n2=250;
tempA=zeros(m1,n1-1);
count=0;
for i=1:n1
    for j=1:(i-1)
        tempA(:,j)=TG(:,j);
    end
    for j=(i+1):n1
        tempA(:,j-1)=TG(:,j);
    end
    [w,y0]=fisher((tempA.'),TB');
    flag=classify_CH(TG(1,i),TB(2,i),w,y0);
    if flag==1
        count=count+1;
    end
end
tempB=zeros(m2,n2-1);
for i=1:n2
    for j=1:(i-1)
        tempB(:,j)=TB(:,j);
    end
    for j=(i+1):n2
        tempB(:,j-1)=TB(:,j);
    end
    [w,y0]=fisher(TG',(tempB.'));
    flag=classify_CH(TB(1,i),TB(2,i),w,y0);
    if flag==2
        count=count+1;
    end
end
error_ratio=count/(n1+n2)

猜你喜欢

转载自blog.csdn.net/zouroot/article/details/55522757