一.實驗題目
(所用參考教材:《模式分類》---機械工業出版社 李宏東 姚天翔等譯)
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日 重新修改總結發布