parzen窗方法和k近鄰方法估計概率密度
機器學習實驗四,詳情請參考《模式分類》第二版第四章課後上機練習4.3、4.4節
實驗環境:
Matlab2016a
Parzen窗估計方法:
已知測試樣本資料x1,x2,…,xn,在不利用有關資料分佈的先驗知識,對資料分佈不附加任何假定的前提下,假設R是以x為中心的超立方體,h為這個超立方體的邊長,對於二維情況,方形中有面積V=h^2,在三維情況中立方體體積V=h^3。
根據以下公式,表示x是否落入超立方體區域中:
估計它的概率分佈:
其中n為樣本數量,h為選擇的窗的長度,φ(.)為核函式,通常採用矩形窗和高斯窗。
k-近鄰估計方法:
在Parzen演算法中,窗函式的選擇往往是個需要權衡的問題,k-最近鄰演算法提供了一種解決方法,是另一種非常經典的非引數估計法。基本思路是:已知訓練樣本資料x1,x2,…,xn而估計p(x),以點x為中心,不斷擴大體積Vn,直到區域內包含k個樣本點為止,其中k是關於n的某一個特定函式,這些樣本被稱為點x的k個最近鄰點。
當涉及到鄰點時,通常需要計算觀測點間的距離或其他的相似性度量,這些度量能夠根據自變數得出。這裡我們選用最常見的距離度量方法:歐幾里德距離。
最簡單的情況是當k=1的情況,這時我們發現觀測點就是最近的(最近鄰)。一個顯著的事實是:這是簡單的、直觀的、有力的分類方法,尤其當我們的訓練集中觀測點的數目n很大的時候。可以證明,k最近鄰估計的誤分概率不高於當知道每個類的精確概率密度函式時誤分概率的兩倍。
實驗內容:
給定以下三個類別的三維資料:
(1)使用parzen窗估計方法,窗函式為一個球形高斯函式:
(a)編寫程式,使用parzen窗方法對一個任意的測試樣本點進行分類,對分類器的訓練使用表格中的三維資料。令h=1,對(0.5,0.1,0.0),(0.31,1.51,-0.50),(-0.3,0.44,-0.1)進行分類。
(b)令h=0.1,重複a。
實驗步驟:
根據parzen窗的概率密度估計公式,編寫parzen窗函式,輸入三個引數,分別為三維資料w、引數h、測試點x,輸出測試點在三個類別中估計的概率密度:
function r=parzen(w,h,x)
[rows,~,dimension]=size(w);
r=zeros(1,dimension);
for i=1:dimension
hn=h;
for j=1:rows
hn=hn/sqrt(j);
r(i)=r(i)+exp(-(x-w(j,:,i))*(x-w(j,:,i))'/(2*power(hn,2)))/(sqrt(2*3.14)*hn);
end
r(i)=r(i)/rows;
End
求出測試點在三個類別中的概率密度後,哪個概率密度大說明測試點屬於哪個類別的概率大。find函式找出最大的概率密度,輸出測試點的類別:
h=1;
for i=1:3
r=parzen(w,h,x(i,:));
result=find(r==max(r));
X=['點[',num2str(x(i,:)),']落在三個類別的概率分別為:',num2str(r)];
Y=['因此,點[',num2str(x(i,:)),']落在第',num2str(result),'類'];
disp(X);disp(Y);disp(' ');
end
程式執行的結果如下:
當h=0.1時,同樣得到結果如下:
(2)使用k近鄰概率密度估計方法。
(a)編寫程式,對於一維的情況,當有n個數據樣本點時,進行k近鄰概率密度估計。對於類別w3中的特徵x1,畫出k=1,3,5時的概率密度估計結果。
(b)編寫程式,對於二維的情況,當有n個數據樣本點時,進行k近鄰概率密度估計。對於類別w2中的特徵(x1,x2),畫出k=1,3,5時的概率密度估計結果。
(c)編寫程式,對於三維的情況,當有n個數據樣本點時,進行k近鄰概率密度估計。對點(-0.41,0.82,0.88),(0.14,0.72,4.1),(-0.81,0.61,-0.38)進行估計。
實驗步驟:
根據式子:,k取不同值使V的值隨之改變,一維情況下,樣本點相當於分佈在一條線上,V的值就等於樣本點到它第k近鄰的距離的兩倍。概率密度畫出來是二維的曲線。觀察樣本點的範圍,以(0.01:0.01:3)取樣300個點作為x軸,求出每個點的概率密度後作為y軸,即可畫出概率密度曲線。需要注意的是,k=1時,求這300個點與10個樣本點的最近距離時,很明顯會有10個點求出的V為0,為了避免0作為除數,程式設計時,V可以加上eps(k=3,5時不存在V=0):
load sample_ex4.mat;
x1=w(:,1,3);
[rows,cols]=size(x1);
p=zeros(1,300);
sample=(0.01:0.01:3);
dist=zeros(300,rows);
for i=1:1:300
for j=1:rows
dist(i,j)=abs(sample(i)-x1(j,1));
end
end
dist_sort=sort(dist,2); %按行排序
for k=1:2:5
for i=1:300
p(i)=k/rows/(2*dist_sort(i,k)+eps); %避免除於0的情況
end
if(k==1)
subplot(131);
plot(sample,p);
elseif(k==3)
subplot(132);
plot(sample,p);
elseif(k==5)
subplot(133);
plot(sample,p);
end
End
畫出概率密度曲線如下:
可以看出,k從1到5,曲線尖峰減少,曲線變平滑。對於二維情況,同樣是使用公式,不過V在二維情況下對應的是一個圓的面積pi*r2。觀察樣本點的波動範圍,可以(-2.95:0.05:2)每隔0.05取樣100個點作為x軸,以(0.04:0.04:4)每隔0.04取樣100個點作為y軸,需要求出這100*100個點的概率密度,畫出為一個三維影象。由於此處不會出現V=0的情況,因此不需加eps。畫出的結果如下:
K增大,同樣可以看出曲面變得平滑。對於第三問,給出了測試點,需要求出測試點在三個類別中的概率密度。此時的V就是球體的體積。
load sample_ex4.mat;
x=[-0.41,0.82,0.88;0.14,0.72,4.1;-0.81,0.61,-0.38];
dist=zeros(3,10,3);
for i=1:3
for j=1:3
for k=1:10
dist(j,k,i)=norm(x(i,:)-w(k,:,j));
end
end
end
dist_sort=sort(dist,2);
k=3;
p=zeros(3,3);
for i=1:3
for j=1:3
p(i,j)=k/10/(4*3.14*dist_sort(j,k,i)^3/3);
end
end
for i=1:3
X=['點 [',num2str(x(i,:)),'] 在三個類別的概率密度分別為:',num2str(p(i,:))];
disp(X);
end
結果如下:
總結:
Parzen窗和K近鄰是非引數估計的兩種經典方法。由式子,n是已知的總的樣本點,k和v未知,parzen窗方法通過固定V而改變k來求概率密度,而k近鄰通過固定k改變V來估計概率密度,parzen窗需要先確定條件概率密度後才能對測試點進行分類,而k近鄰可以直接根據k個近鄰中哪個類別的樣本點最多就將其分為哪一類,k近鄰模型幾乎沒有進行什麼學習,來一個測試點都要重新計算,並且訓練集需要保留,屬於lazy-learning。