【機器學習】--非參數估計實驗 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日 重新修改總結發布

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM