[貝葉斯四]之貝葉斯分類器設計
<個人網頁blog已經上線,一大波乾貨即將來襲:https://faiculty.com/>
/* 版權聲明:公開學習資源,只供線上學習,不可轉載,如需轉載請聯繫本人 .*/
這一小節我們將簡單的闡述一般貝葉斯分類器設計的方法。分類器流程如下所示。
- 輸入:d-dim 特徵向量
- 計算決策函數值(針對每個類別)
- 選取最大的值
- 做出決策
- 輸出結果
如下圖可以清楚的表達整個分類器工作的流程。
借用《演算法雜貨鋪——分類演算法之樸素貝葉斯分類(Naive Bayesian classification)》的一張圖來表示整個設計的流程。
下面我們將以兩個小例子來貫穿貝葉斯分類器設計的整個流程。
一、MNIST手寫體識別
1.0 數據集簡介
MNIST是一個0-9的手寫數字資料庫。MNIST數據集中包含60000張手寫數字圖片,10,000 張測試圖片。每張圖片的大小為28*28,包含一個手寫數字。如下圖所示。數據集鏈接:http://yann.lecun.com/exdb/MNIST/。
數據集中包含四個文件。
1. train-images-idx3-ubyte.gz: training set images (9912422 bytes) 2. train-labels-idx1-ubyte.gz: training set labels (28881 bytes) 3. t10k-images-idx3-ubyte.gz: test set images (1648877 bytes) 4. t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)
整理一下MNIST數據集。
- 四個文件。train_image,train_label,test_image,test_label
- 圖像數據。2828的圖像尺寸的灰度圖像,所以每張圖像為2828*1
- 標籤。針對每個數據給出0-9中一個數字作為類別。
1.1、特徵向量準備
搞個三部曲:
- 數據準備
- 模型設計
- 模型訓練
貝葉斯決策論也不例外,首要的,我們需要將原始數據經過一系列清洗得到輸入的特徵向量。
咋輸入數據?
MNIST數據集四個文件是用二進位進行編寫,詳細的格式如下圖所示,展示image file 和 label file。
數據的預處理可以分為兩部分:第一部分就是讀入數據,第二部分就是提取成想要的特徵向量。(1)讀入數據。實驗中我們採用MATLAB編寫,利用文件指針逐個位元組讀取,得到一個mat,然後reshape到784N的數據形式,注意這裡得到的都是0-255像素。對於label也是同理得到N1的數據形式。(2)提取特徵向量。 最後我們需要對讀入的數據進行處理得到我們想要的特徵向量。這裡實驗做法十分暴力,直接將圖像變成二值化(將0-255 resize到0、1),然後向量長度不變。所以得到的形式是784*N的二值化的矩陣。Label不做任何處理。
這裡主要是闡述整個設計流程,所以直接用最簡單的方式提取特徵。感興趣的同學可以嘗試用PCA等特徵生成的方式將輸入的圖像做特徵提取。
1.2、決策函數設計
接下來是分類器設計的主要步驟:決策函數設計。首先我們從最頂層開始往下進行推導。貝葉斯分類的核心就是找到最大的後驗概率,也就是給出一個樣本,它屬於的概率最大,那麼我們就認為樣本是屬於第類的。由此我們的分類器設計的目標就是計算概率值.
下面我們先給出形式化的定義。
- 表示我們的數據集;
- 是784維的向量,表示第個樣本;
- 是標註的第個樣本的類別,取值範圍是0-9;
- 表示第個樣本的第維。
決策函數定義一般情況下,貝葉斯都是採用了最小錯分準則,這裡也是如此。由此我們可以得到我們的目標決策函數。
也就是說對於一個樣本,我們只需要計算出它們屬於每一類的後驗概率,並將樣本判定給後驗概率大的那一類. 接下來我們就此解釋該如何計算出這個後驗概率,也就是模型的建立過程。
1.2.1 模型建立
根據最小錯分原則,所以我們的目標就是求解最大的後驗概率,由此得到結果類別。寫成公式如下。
對於一個784維的樣本,它的每一維出現是相互獨立的(屬性之間相互獨立,也被稱為樸素貝葉斯)。由此我們可以將我們目標後驗概率寫成如下公式。
其中:
- 表示樣本的第個元素
接下來轉換目標為求解每個像素點的相應後驗概率(也就是樣本每個元素的後驗概率)。根據貝葉斯公式,我們得到一個設計模型。該式子的意義為:針對一個樣本的第個元素出現,屬於第類樣本的概率。
這個模型非常好理解。我們要求的就是已知樣本第個元素(像素)情況下,這個樣本是屬於第j類的概率。這個概率就可以用貝葉斯得到。由此我們通過訓練樣本可以得到如下概率值(因為我們的特徵向量元素取值為0或者1)。
因為每個像素只可能為0或者1,所以我們直接計算的是像素為1的情況。由此我們的模型就已經建立了。Model中就是這三個根據訓練數據得到概率值,接下來我們將討論如何根據這個模型判斷某個樣本的類別。
1.2.2 模型測試
根據給出的訓練數據集,我們能計算出如上的、和. 根據這幾個結果,我們得到了後驗概率.
問題是,針對測試樣本,我們該如何計算?這是該貝葉斯分類器設計中的核心,很多人覺得在這裡很繞。之前我們是根據給出的訓練數據計算出的一個模型,換句話有點像最大似然估計法:用有限的觀測數據來估計一個未知參數的模型。比如對於一個拋硬幣測試,我們想知道硬幣正反出現的概率模型,那麼我們經過大量的實驗,然後計算最大似然。由此得到一個模型參數。這裡也是一樣,我們得到的是叫做貝葉斯模型。根據這個模型,然後加上輸入的測試樣本,我們計算出最大的後驗概率。
假設這個時候來了一個樣本,對於這個樣本的第個元素顯然是服從二分布的,要不為1,要不為0。所以我們根據之前的模型計算中的後驗概率計算方法,首先計算出這個樣本低個元素的出現概率。
同理,對於第類情況下,樣本的第個元素也是服從二分布的。由此我們可以得到如下的式子。
同理,用通俗易懂的式子描述如下。
整理後,我們得到樣本出現的後驗概率為(這裡採用貝葉斯定理即可得到)。
對於輸入的測試樣本,我們已知了每個元素的值,那麼我們將該值帶入到上式進行計算就好了。比如我們可以得到。
由此就能計算出。到此為止,我們決策函數的分析徹底結束。接下來就是模型的訓練。
1.3 模型訓練
這一部分主要就是工程問題,首先根據輸入的訓練數據,計算出上述的模型(也就是train文件)。然後寫一個輸入樣本得到預測結果的文件(也就是test文件)。
二、字母分類設計
接下來,趁熱打鐵,我們接著擼一個類似的例子。同學們可以根據需求,自己先推一邊。過程是一模一樣的。
數據集來自於UCI:UCI字母分類數據集鏈接
2.0 數據集分析
老套路,我們對數據集先做個簡單的分析,主要是知道數據集的數據形式,便於寫程序進行讀取和預處理。
這個數據集原始數據一共包含20000張圖像(一般取前16000張圖像作為訓練,後4000張圖像作為測試),每張圖像經過作者處理後得到了一個16維的特徵(特徵值是一個0-15的整數),標籤就是所代表的字母A-Z。數據形式如下:
1. lettr capital letter (26 values from A to Z) 2. x-box horizontal position of box (integer) 3. y-box vertical position of box (integer) 4. width width of box (integer) 5. high height of box (integer) 6. onpix total # on pixels (integer) 7. x-bar mean x of on pixels in box (integer) 8. y-bar mean y of on pixels in box (integer) 9. x2bar mean x variance (integer) 10. y2bar mean y variance (integer) 11. xybar mean x y correlation (integer) 12. x2ybr mean of x * x * y (integer) 13. xy2br mean of x * y * y (integer) 14. x-ege mean edge count left to right (integer) 15. xegvy correlation of x-ege with y (integer) 16. y-ege mean edge count bottom to top (integer) 17. yegvx correlation of y-ege with x (integer)
其中20000張圖像的分布如下:
1. 789 A 766 B 736 C 805 D 768 E 775 F 773 G 2. 734 H 755 I 747 J 739 K 761 L 792 M 783 N 3. 753 O 803 P 783 Q 758 R 748 S 796 T 813 U 4. 764 V 752 W 787 X 786 Y 734 Z
整理一下這個數據集。
- 一個文件。共20000條數據,我們將前16000條數據作為訓練數據,後4000條數據作為測試數據。
- 數據格式。16維的特徵向量,一個A-Z的label
2.1 特徵向量生成
由第1章問題的描述中我們可以知道,字母數據集已經幫我們做好了特徵向量提取的工作。數據形式如下所示。
由此我們只需要經過簡單的處理就能得到我們想要的數據。- Image數據。上圖所示每行16維向量,每個特徵值取值為0-15的整數。形式為16*N。
- Label。上圖中每行第1列,A-Z。
Step1:數據讀入(loadData.m)
% load data from file, start --start line, end --end linefunction [labels, features] = loadData(filename,start,endl)[data1,data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14,data15,data16,data17] = textread(filename, %c%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d,delimiter,,);labels = data1(start:endl,1);features = [data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14,data15,data16,data17];features = features(start:endl,:);%labels = labels.;features = features. + 1;% 注意:這裡的下標是0~15end
2.2 決策函數
2.2.1 模型建立
我們需要訓練的模型跟上述數字手寫體分類一樣,目標如下。
物理解釋是:針對每個輸入測試樣本,我們需要求解一個它屬於j類的後驗概率,這個後驗概率等於16維特徵屬於j類的後驗概率。是代表:給出樣本的第的元素,那麼這個元素屬於第類中實例的概率。因為我們認為每個樣本特徵之間是相互獨立的,所以採用乘法。
由此我們的目標就變成了如何計算這個樣本第個元素值屬於第類的後驗概率問題。
其中:
- 表示類別出現的概率
- 表示樣本第個元素為的概率
- 表示樣本屬於第類情況下第個元素的值為的概率
這個就是我們需要訓練的模型。
Step2: 訓練模型(bc_train.m)
function [model] = bc_train(x, y, J)[K,N] = size(x); %K為維度,N為樣本數% p(w): 類別 i 出現的概率py = zeros(J,1);for i=1:J py(i,:) = sum(y == i)/N;end% p(x_k_i): 樣本中第k個元素為i的個數 / 樣本總數pki = zeros(16,16);for k=1:16 for i=1:16 pki(k,i) = sum(x(k,:) == i)/N; endend% p(x_k_i | j): 第j類樣本中第k個元素為i的樣本數 / 第j類樣本總數pkij = zeros(16,16,J);for j=1:J for k=1:16 xj = x(:,y==j); %屬於第j類的樣本 for i=1:16 pkij(k,i,j) = sum(xj(k,:)==i)/size(xj,2); end endendmodel.pki = pki;model.py = py;model.pkij = pkij;end
2.2.2 模型測試
假定給出一個樣本,我們可以根據每個特徵的值計算出屬於第類的後驗概率。
上式中,給出的測試樣本顯然是確定的,所以中值是一個確定值。根據上述得到的model,我們就能計算出屬於第j類的後驗概率了。最後將特徵值的後驗概率相乘,取最大值所在的類,就是我們計算得到的類別。
其中,runChar.m文件為主程序,代碼如下:
經測試,模型在測試集上的分類正確率為:73.43%。
Step3: 測試數據(bc_predict.m)
function [yp] = bc_predict(model,x,J)[K,N] = size(x);pki = model.pki;py = model.py;pkij = model.pkij;% p(y_j|i): 樣本第i個元素為 x(:,i) 情況下,類別為j的概率pyji = zeros(J,16,N);for j=1:J for i = 1:16 for n=1:N pyji(j,i,n) = pkij(i,x(i,n),j) * py(j) / pki(i,x(i,n)); end endendresult = prod(pyji,2);yp = zeros(N,1);for i=1:N [m,yp(i,:)] = max(result(:,:,i));end
Step4: 主程序(runChar.m)
clearclc%% Step1: read data[train_labels,train_char] = loadData(./char/letter-recognition.data.txt,1,16000);[test_labels,test_char] = loadData(./char/letter-recognition.data.txt,16001,20000);%% Step2: train modeltrain_labels = train_labels - A + 1;model = bc_train(train_char, train_labels, 26);%% Step3: predicttest_labels = test_labels - A + 1;yp = bc_predict(model,test_char,26);accuary_test = sum(yp == test_labels) / length(test_labels);
#四、 參考文獻
[1] MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges.下載鏈接[2] UCI Machine Learning Repository: Letter Recognition Data Set.下載鏈接[3] Using the MNIST Dataset.下載鏈接[4] 周志華. 《機器學習》[M]. 清華大學出版社, 2016.[5] 李航. 《統計學習方法》[M].清華大學出版社,2013.[6]機器學習之貝葉斯分類器[7]機器學習通俗入門-樸素貝葉斯分類器PS: 如需數據和代碼請上faiculty留言
推薦閱讀:
※AlphaGo之父談人工智慧:超越人類認知的極限
※斯坦福CS231n項目實戰(三):Softmax線性分類
※機器學習面試之偏差方差
※感知機(PLA)
※CS259D:數據挖掘與網路安全講義筆記
TAG:機器學習 |