• 【机器学习】--非参数估计实验 parzen窗以及k-近邻概率密度


    一.实验题目

    (所用参考教材:《模式分类》---机械工业出版社 李宏东 姚天翔等译)

    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  

    作者:魔王是翼伊

    是在大学三年级学习过程中老师布置的实验题目,欢迎指教与探讨。

    2017年4月25日 重新修改总结发布

  • 相关阅读:
    对NumPy中dot()函数的理解
    使用Boostrap框架写一个登录注册界面
    两种方法实现asp.net方案的前后端数据交互(aspx文件、html+ashx+ajax)
    将包含经纬度点位信息的Excel表格数据导入到ArcMap中并输出成shapefile
    [ArcGIS API for JavaScript 4.8] Sample Code-Popups-1-popupTemplate的概念和popup中属性字段值的多种表现形式
    [python爬虫]Requests-BeautifulSoup-Re库方案--robots协议与Requests库实战
    [python爬虫]Requests-BeautifulSoup-Re库方案--Requests库介绍
    [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-widgets简介
    [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-popups简介
    [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-layers简介
  • 原文地址:https://www.cnblogs.com/mowangshiyiyi316/p/6474834.html
Copyright © 2020-2023  润新知