1. 程式人生 > 其它 >樸素貝葉斯分類器

樸素貝葉斯分類器

目錄

 

基本概念

樸素貝葉斯分類器計算一個樣本屬於某一類的概率(後驗概率),進而比較概率大小來決定樣本的分類結果。分類器需要資料集作為已知樣本集,還需要這些樣本的分類結果,最後對新給出的樣本集進行分類。

具體來說,假設已經得到樣本集 \(D=\{x_1,\cdots,x_n\}\) ,每一個 \(x_i\) 都有 \(k\) 個特徵,分別記為 \(a_i\) , 可能類別為 \(Y=\{y_1,\cdots,y_m\}\) ,根據每個 \(x_i\) 的特徵,它會被分類到某一個 \(y_j\) 類中。

現在我們已經知道 \(D\) 分類的結果,分類器需要根據已經有的這些資訊對新的樣本 \(x=(a_1,\cdots,a_k)\)

進行分類。換句話說, \(y_j\) 就是一些模型,我們需要根據現有分類資料判斷 \(x\) 最有可能符合哪一個模型。

 

離散分類

需要計算已知 \(x\) 時分類到 \(y_j\) 的概率 \(\Pr(y_j|x)\) ,然後比較其中最大的概率,選擇對應的 \(y_j\) 作為分類結果。根據貝葉斯公式

\[\Pr(y_j|x) = \dfrac{\Pr(x|y_j)\Pr(y_j)}{\Pr(x)} \]

與先前類似,其中 \(\Pr(x)\) 可以忽略,我們用 \(D\) 中分類到 \(y_j\) 的元素佔 \(D\) 所有元素的比例來估計 \(y_j\) 出現的概率 \(\Pr(y_j)\)

於是重點就在於計算 \(\Pr(x|y_j)\) ,我們知道 \(x\) 有一些特徵,那麼

\[\Pr(x|y_j) = \prod_{i=1}^k\Pr(a_i|y_j) \]

也就是 \(x\)每一個特徵都出現\(y_j\) 中的概率,其中 \(\Pr(a_i|y_j)\)\(a_i\) 出現在 \(y_j\) 分類中的比例。最終就得到

\[\Pr(y_j|x) \varpropto \Pr(y_j)\prod_{i=1}^k\Pr(a_i|y_j) \]

計算右邊的最大值,然後選擇對應的 \(y_j\) 作為分類結果即可。

 

以下面離散資料集的程式碼為例,首先給出已知資料

fea_dis = [[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]',[1,2,2,1,1,1,2,2,3,3,3,2,2,3,3]'];	% 已經分類的資料集
gnd_dis = [-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]';		                        % 對應的分類結果集

需要對 \((a_1,a_2)=(2,1)\) 進行分類,可以看出有 \(-1,1\) 兩類,記為 \(y_1,y_2\)

target_dis = [2,1];

因此需要計算每個分類中不同特徵出現的概率

\[\begin{matrix} \Pr(a_1| y_1) & \Pr(a_2| y_1)\\ \Pr(a_1| y_2) & \Pr(a_2| y_2) \end{matrix} \]

用一個矩陣來存放上面的概率

% 記錄概率 P(a_i|y_j)
P = zeros(2,2);

% 統計 1 和 -1 兩類分別有多少元素
p_count1 = sum(gnd_dis == 1);
p_count2 = sum(gnd_dis == -1);

% x = (a1,a2) = (2,1)
% 統計 1 類中 2 和 1 出現的概率
P(1,1) = sum(fea_dis(:,1) == 2 & gnd_dis == 1) / p_count1;
P(1,2) = sum(fea_dis(:,2) == 1 & gnd_dis == 1) / p_count1;

% 統計 -1 類中 2 和 1 出現的概率
P(2,1) = sum(fea_dis(:,1) == 2 & gnd_dis == -1) / p_count2;
P(2,2) = sum(fea_dis(:,2) == 1 & gnd_dis == -1) / p_count2;

然後計算出似然估計

\[\Pr(x|y_1) = \Pr(a_1| y_1) \Pr(a_2| y_1)\cdot \Pr(y_1)\\ \Pr(x|y_2) = \Pr(a_1| y_2) \Pr(a_2| y_2)\cdot \Pr(y_2)\\ \]
p1 = P(1,1) * P(1,2) * p_count1 / (p_count1 + p_count2);
p2 = P(2,1) * P(2,2) * p_count2 / (p_count1 + p_count2);

比較兩個概率的大小決定分到哪一類即可。

 

連續分類

對於連續資料,通常是將其轉化為離散資料集,包括兩種方法

  • 將特徵取值範圍分成幾個較少的區間
  • 假設每個類別中樣本特徵服從不同期望方差下的正態分佈

第一種方法下,直接使用上面的方案即可;如果是第二種方法,我們假定 \(y_j\) 類中出現的特徵 \(a_i\) 服從正態分佈

\[g(x,\mu,\sigma) = \dfrac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{(x-\mu)^2}{2\sigma^2}) \]

這樣就可令 \(\Pr(a_i|y_j) = g(a_i,\mu,\sigma)\) ,其中 \(\mu\)\(\sigma^2\)\(y_j\) 中出現的特徵 \(a_i\) 的期望和方差。我們用平均值來近似期望,使用無偏方差

\[D(X) = \dfrac{1}{n-1}\sum_{i=1}^n(X_i-\overline{X})^2 \]

假定不同特徵的協方差為 \(0\) ,也就是它們相互獨立。

 

我們生成一個連續資料集

% 生成連續資料
mu = [0,2];
sigma = [1 0;0,1];
r1 = mvnrnd(mu,sigma,200);
target_r1 = mvnrnd(mu,sigma,10);
mu = [3,6];
sigma = [1 0;0,1];
r2 = mvnrnd(mu,sigma,200);
target_r2 = mvnrnd(mu,sigma,10);

% 資料集
fea_con = [r1;r2];
gnd_con = [ones(200,1);-1*ones(200,1)];
target_con = [target_r1;target_r2];

% 清除無用資料
clear mu sigma r1 r2 target_r1 target_r2

這裡是利用二元正態分佈生成了兩組資料集,分別為 \(1,-1\) 類,然後將它們拼在一起,不過這不重要。

 

這次要對 \(10\) 個樣本進行分類,還是按照之前的方法計算 \(\Pr(y_j)\) ,而 \(\Pr(a_i|y_j)\) 則採用上面的正態分佈估計,就得到

% 統計 1 和 -1 兩類分別有多少元素
p_count1 = sum(gnd_con == 1);
p_count2 = sum(gnd_con == -1);

% 獲取 1 類和 -1 類的元素
y1 = fea_con(gnd_con == 1,:);
y2 = fea_con(gnd_con == -1,:);

% 計算平均值作為期望
mu1 = [mean(y1(:,1)) mean(y1(:,2))];
mu2 = [mean(y2(:,1)) mean(y2(:,2))];

% 計算方差
sigma1 = [(y1(:,1) - mu1(1))' * (y1(:,1) - mu1(1)) / (p_count1 - 1) 0;
    0 (y1(:,2) - mu1(2))' * (y1(:,2) - mu1(2)) / (p_count1 - 1)];
sigma2 = [(y2(:,1) - mu2(1))' * (y2(:,1) - mu2(1)) / (p_count2 - 1) 0;
    0 (y2(:,2) - mu2(2))' * (y2(:,2) - mu2(2)) / (p_count2 - 1)];

% 目標長度
n = length(target_con);

% 記錄概率 P(a_i|y_j) 通過正態分佈估計
P = zeros(2,2);
res = zeros(n,1);

% x = (a1,a2)
for i = 1:n
    % 當前元素的兩個特徵
    a1 = target_con(i,1);
    a2 = target_con(i,2);
    
    % 計算 1 類中 a1 a2 的概率
    P(1,1) =  1 / sqrt(2*pi) / sigma1(1,1) * exp(-(a1-mu1(1))^2/(2 * sigma1(1,1)^2));
    P(1,2) =  1 / sqrt(2*pi) / sigma1(2,2) * exp(-(a2-mu1(2))^2/(2 * sigma1(2,2)^2));
    
    % 計算 -1 類中 a1 a2 的概率
    P(2,1) =  1 / sqrt(2*pi) / sigma2(1,1) * exp(-(a1-mu2(1))^2/(2 * sigma2(1,1)^2));
    P(2,2) =  1 / sqrt(2*pi) / sigma2(2,2) * exp(-(a2-mu2(2))^2/(2 * sigma2(2,2)^2));
    
    % 計算條件概率
    p1 = P(1,1) * P(1,2) * p_count1 / (p_count1 + p_count2);
    p2 = P(2,1) * P(2,2) * p_count2 / (p_count1 + p_count2);
    
    % 根據概率大小判斷分類
    if p1 > p2
        res(i) = 1;
    else
        res(i) = -1;
    end
end

由於只有兩類,所以分類也較為簡單,不過更多類的情況也是類似的。

 

準確度

只介紹簡單的分類準確度指標 accuracy ,定義為分類正確的樣本數與總樣本數之比。

% 計算準確度
acc = sum(res == target_con_gnd) / n;