一.实验题目
(所用参考教材:《模式分类》---机械工业出版社 李宏东 姚天翔等译)
4-3.考虑对于表格中的数据进行parzen窗估计和设计分类器,窗函数为一个球形的高斯函数,
<a>编写程序,使用parzen窗估计方法对一个任意的样本点x进行分类。对分类器的训练则使用表格中的三维数据。同时令h=1,分类样本点为
(0.5,1.0,0.0)‘,(0.31,1,51,-0.50)’,(-0.3,0.44,-0.1);
<b>现在我们令h=0.1,重复a
4-4.考虑不同维度的空间中,使用k-近邻概率密度估计方法的效果
<a>编写程序,对于一维的情况,当有n个数据样本点时,进行k-近邻概率密度估计。对表格中w3中的特征x1,用程序画出当k=1,3,5时的概率密度估计结果。
<b>编写程序,对于二维的情况,当有n个数据样本点时,进行k-近邻概率密度估计。对表格中的类别w2中的特征(x1,x2)',用程序画出当k=1,3,5时的概率密度估计结果。
<c>对表格中的3个类别的三维特征,使用k-近邻概率密度估计方法,并且对下列点处的概率密度进行估计:
(-0.41,0.82,0.88)‘,(0.14,0.72,4.1)’,(-0.81,0.61,-0.38)‘
二.实验环境
MATLAB 2016版
三.实验分析
1.首先进行对4-3的分析
4-3要求使用parzen窗非参数估计的方法并设计分类器
①Parzen窗方法的理解:
<a>首先由公式:pn(x)=kn/n/Vn 可以计算出非参数的概率密度估计
其中 pn(x)表示p(x)的第n次估计,
Vn为区域Rn的体积,
Kn为Rn中的样本个数。
<b>要使用的窗方法,主要就是定义Vn
设Rn为d维超立方体,hn为其中的一条边,
由此就可以得到落在窗中的样本个数kn的表达式。
<c>在题目中已经给出了使用的窗函数的形式,则可直接使用概率密度进行计算
<d>使用了表格中各类的三维数据作为训练样本,并将各个分类样本作为参数传入到编写的parzen窗函数中:
(事先已将课本上的数据样本导入到我所建的参数估计项目之下,生成了mat数据文件以备之后的程序使用)
Parzen窗函数代码:
1 %生成函数计算样本个数kn的表达式 2 %使用可球型的高斯函数作为窗函数,并令hn=1, 3 %a为使用三维数据,h为超立方体的边长,x为测试样本 4 function px=parzen(a,h,x) 5 hn=h; 6 [m,n]=size(a); %返回m为样本的个数,m为行,n为列 7 px=0; 8 vn=4*pi*h^3/3; %求出rn空间的体积vn 9 for i=1:m 10 px=px+exp((-(x-a(i,:))*(x-a(i,:))')/(2*power(hn,2)))/(vn); 11 %px为概率密度函数 12 end 13 px=px/m; 14 end
在测试脚本中对于h=1或h=0.1做不同的赋值,最后在得到的概率密度px数组中找到相应最大的概率,即可判定分类样本属于哪个类别(即w1/w2/w3)
测试脚本如图所示:
1 %用于进行上机题4-3 2 clear 3 load('w1.mat'); 4 load('w2.mat'); 5 load('w3.mat'); 6 7 %完成4-3第二题<a> 8 x1=[0.5,1.0,0.0]; 9 x2=[0.31,1.51,-0.50]; 10 x3=[-0.3,0.44,-0.1]; 11 p1=[]; 12 p2=[]; 13 p3=[]; 14 h1=1; 15 p11=parzen(w1,h1,x1); 16 p12=parzen(w2,h1,x1); 17 p13=parzen(w3,h1,x1); 18 p1=[p11,p12,p13]; %将每一个类别算出的概率放在一起 19 n1=find(p1==max(p1)); %find函数用于返回所需元素的所在位置 20 %n1,n2,n3返回的是最大概率的值,则表明样本属于那个类 21 p21=parzen(w1,h1,x2); 22 p22=parzen(w2,h1,x2); 23 p23=parzen(w3,h1,x2); 24 p2=[p21,p22,p23]; 25 n2=find(p2==max(p2)); 26 27 p31=parzen(w1,h1,x3); 28 p32=parzen(w2,h1,x3); 29 p33=parzen(w3,h1,x3); 30 p3=[p31,p32,p33]; 31 n3=find(p3==max(p3)); 32 33 disp('当h=1时'); 34 %disp(p1); 35 disp(['样本点1 [ ',num2str(x1),' ] 落在类别 ',num2str(n1),' 中']); 36 disp(['样本点2 [ ',num2str(x2),' ] 落在类别 ',num2str(n2),' 中']); 37 disp(['样本点3 [ ',num2str(x3),' ] 落在类别 ',num2str(n3),' 中']); 38 39 %完成4-3第二题<b> 40 h2=0.1; 41 k1=[]; 42 k2=[]; 43 k3=[]; 44 k11=parzen(w1,h2,x1); 45 k12=parzen(w2,h2,x1); 46 k13=parzen(w3,h2,x1); 47 k1=[k11,k12,k13]; %将每一个类别算出的概率放在一起 48 m1=find(k1==max(k1)); %find函数用于返回所需元素的所在位置 49 %n1,n2,n3返回的是最大概率的值,则表明样本属于那个类 50 k21=parzen(w1,h2,x2); 51 k22=parzen(w2,h2,x2); 52 k23=parzen(w3,h2,x2); 53 k2=[k21,k22,k23]; 54 m2=find(k2==max(k2)); 55 56 k31=parzen(w1,h2,x3); 57 k32=parzen(w2,h2,x3); 58 k33=parzen(w3,h2,x3); 59 k3=[k31,k32,k33]; 60 m3=find(k3==max(k3)); 61 62 disp('当h=0.1时') 63 %p(k1); 64 disp(['样本点1 [ ',num2str(x1),' ] 落在类别 ',num2str(m1),' 中']); 65 disp(['样本点2 [ ',num2str(x2),' ] 落在类别 ',num2str(m2),' 中']); 66 disp(['样本点3 [ ',num2str(x3),' ] 落在类别 ',num2str(m3),' 中']); 67 68 clear %清除所有变量
在不同的h下计算出来,各个分类样本点中,概率密度最大的值均在w2类中。
2.进行4-4的分析
要求使用k-近邻估计概率密度
①k-近邻方法的理解:
让体积成为训练样本的函数,而不是硬性的规定窗函数为全体样本个数的某个函数。
例:从n个训练样本中估计p(x),我们能以点x为中心,让体积扩张,直到包含进kn个样本点位置,其中的kn是关于n的某一个特定函数。
这些样本就被称为点x的kn个最近邻。
②首先对4-4题目中的<a>、<b>问进行分析:
<a> 题目中都要求在n个数据样本点的条件下,即把n个数据样本点作为训练样本,然后将题目<a>的一维数据w3中的x1作为特征值,
将<b>中的二位数据w2中的(x1,x2)作为特征值代入编写的kneighbor函数中。
<b>仍然使用公式:pn(x)=kn/n/Vn 来进行计算。
首先计算出Vn,
调用rand()函数先产生100个0-3之间的训练样本集
对于一维数据Vn为训练样本和测试样本之间差值的长度绝对值;
对于二维数据Vn为训练样本和测试样本之间的欧几里得距离,使用距离公式进行计算。
<c>计算出Vn后,由题目的kn可取1,3,5.分别取值代入函数中计算,得到最终结果为每个随机样本点对应的概率密度估计值。
<d>对于一维数据及二维数据进行k-近邻估计的函数如图所示:
1 %使用kn近邻概率密度估计方法,分别对一维,二维,三维的数据进行估计 2 %k为参数,a为样本 3 %测试数据为一维 4 function px= kneighbor(a,kn,x) 5 [m,n]=size(a); 6 b=x; 7 N=100; 8 if n==1 %当为一维向量时 9 px=zeros(N,1); 10 vn1=zeros(N,1); 11 for i=1:N 12 for j=1:m 13 vn1(j)=abs(b(i)-a(j)); %求出vn,即两个数据点的距离长度 14 end 15 vn1=sort(vn1); %将每一列由小到大排列一遍 16 px(i)=kn/N/(vn1(kn)); %计算概率密度 17 end 18 %disp(px); 19 end 20 21 if n==2 %当为二维向量时 22 px=zeros(N,1); %用于存储概率 23 vn2=zeros(N,1); 24 for i=1:N 25 for j=1:m 26 vn2(j)=sqrt((b(i,1)-a(j,1))^2+(b(i,2)-a(j,2))^2); %计算出两点之间的距离 27 end 28 vn2=sort(vn2); 29 px(i)=kn/N/(vn2(kn)); %计算出概率密度 30 end 31 end 32 33 end
使用变量n可以判定输入的数据维度。
<e>题目<a>的实验结果(kn取1,3,5)
测试所用脚本如图所示:
1 %用于进行上机题4-4 2 clear 3 load('w1.mat'); 4 load('w2.mat'); 5 load('w3.mat'); 6 7 k1=1; 8 k2=3; 9 k3=5; 10 11 %完成4-4第三题<a> 12 a1=w3(:,1); 13 N=100; 14 b=2*rand(N,1); %首先产生100个0-3之间的随机数 15 p1=kneighbor(a1,k1,b); 16 p2=kneighbor(a1,k2,b); 17 p3=kneighbor(a1,k3,b); 18 figure(1); 19 subplot(1,4,1); 20 plot(b,p1,'.'); 21 subplot(1,4,2); 22 plot(b,p2,'.'); 23 subplot(1,4,3); 24 plot(b,p3,'.'); 25 26 %完成4-4第三题<b> 27 b1=[]; 28 a2=w2(:,1); 29 a3=w2(:,2); 30 b1=[a2 a3]; 31 b2=3*rand(N,2); %产生100个0-4的二维随机数 32 33 p11=kneighbor(b1,k1,b2); 34 p12=kneighbor(b1,k2,b2); 35 p13=kneighbor(b1,k3,b2); 36 data1=[b2 p11]; 37 figure(2); 38 plot3(b2(:,1),b2(:,2),p11,'.'); 39 grid on; 40 figure(3); 41 plot3(b2(:,1),b2(:,2),p12,'.'); 42 grid on; 43 figure(4); 44 plot3(b2(:,1),b2(:,2),p13,'.'); 45 grid on; 46 47 clear
实验结果如图:
③对4-4题目中<c>进行分析
<a>对表格中的3个类别的三维特征,使用k-近邻概率密度估计方法,并且对下列点处的概率密度进行估计:
(-0.41,0.82,0.88)‘,(0.14,0.72,4.1)’,(-0.81,0.61,-0.38)‘
将表格中的3个类别的三维数据作为训练样本,来判定分类样本点属于哪个类别。
<b>使用 pn(x)=kn/n/Vn 公式
Vn由norm()求范数的函数求出每一个训练样本与测试样本之间的距离。
<c>编写函数kneighborthree来计算三维数据的概率密度估计值:
具体代码:
1 %a,b,c分别为各类的训练样本 2 %x:测试样本 3 % 完成4.4题目中的<c>问,使用三维特征对特定点进行估计 4 function [num1,num2,num3]=kneighborthree(a,b,c,k,x) 5 k1=k; 6 w=[a;b;c]; 7 [m,n]=size(w); 8 for i=1:m 9 dist(i)=norm(x-w(i,:)); %求出向量范数 10 end 11 t1=sort(dist); %欧式距离排序,将每一列由小到大排列一遍 12 [a1,b1]=size(t1); 13 f1=find(dist<=t1(k1+1)); %找到k个最近邻编号 14 %disp(t1); 15 num1=length(find(f1>0&f1<11)); 16 num2=length(find(f1>10&f1<21)); 17 num3=length(find(f1>20&f1<31)); 18 end
测试脚本为:
1 %完成4-4第三题<c> 2 x1=[-0.41,0.82,0.88]; 3 x2=[0.14,0.72,4.1]; 4 x3=[-0.81,0.61,-0.38]; 5 x4=[0.011,1.03,-0.21]; 6 [n11,n12,n13]=kneighborthree(w1,w2,w3,k3,x1); 7 figure(5); 8 draw3(w1,w2,w3,n11,n12,n13,x1); %绘制出图像 9 grid on; 10 [n21,n22,n23]=kneighborthree(w1,w2,w3,k3,x2); 11 draw3(w1,w2,w3,n21,n22,n23,x2); 12 grid on; 13 [n31,n32,n33]=kneighborthree(w1,w2,w3,k3,x3); 14 draw3(w1,w2,w3,n21,n22,n23,x3); 15 16 clear
编写了draw3()方法来绘制出图像。
实验结果如图:
图中不同颜色表示3个类别。圆圈是已经分好类的测试样本数据。
四.实验总结
通过对于parzen窗方法和k-近邻估计方法的使用,可以得知初始kn值选取是比较重要的,会影响结果的概率密度估计值。
Kn需要取一个合适的值,并且parzen窗方法和k-近邻估计方法的差异也比较明显,对于parzen窗方法需要首先确定一个窗函数,而k-近邻估计方法是让体积成为训练样本的函数,而不是硬性的规定窗函数为全体样本个数的某个函数。
作为机器学习的初学者,也是在老师的指导下,慢慢摸索研究,有许多方法函数的编写也很稚嫩,虚心的向各位机器学习的大神讨教,哪里有问题非常欢迎指出与探讨,自己也会在之后重新修改与测试,代码的编写、方法的使用也需要更多的成熟性与实用性。
补充draw3()函数
1 function m=draw3(w1,w2,w3,num1,num2,num3,x) 2 %UNTITLED3 此处显示有关此函数的摘要 3 %画出根据三维数据特征,使用k-近邻概率估计方法 4 %并对点,进行估计分类 5 plot3(w1(:,1),w1(:,2),w1(:,3),'r+'); 6 hold on; 7 grid on; 8 plot3(w2(:,1),w2(:,2),w2(:,3),'c+'); 9 plot3(w3(:,1),w3(:,2),w3(:,3),'g+'); 10 if(num1>num2)&&(num1>num3) 11 plot3(x(1,1),x(1,2),x(1,3),'ro'); 12 disp(['[ ',num2str(x),' ] 是w1类']); 13 elseif (num2>num1)&&(num2>num3) 14 plot3(x(1,1),x(1,2),x(1,3),'co'); 15 disp(['[ ',num2str(x),' ] 是w2类']); 16 elseif (num3>num1)&&(num3>num2) 17 plot3(x(1,1),x(1,2),x(1,3),'go'); 18 disp(['[ ',num2str(x),' ] 是w3类']); 19 else 20 disp('无法分类'); 21 end 22 m=0; 23 24 end 25