
個人複習統計學習中樸素貝葉斯模型所做的筆記,包括原理講解及其Python語言實作。原理方面重點關注從統計學和機率論的角度給出嚴謹的公式推導,包括模型建構、參數估計和算法三個部分。參考資料包括李航的《統計學習方法》和George Casella的《統計推斷》。
我們定義樣本空間為\(\mathcal{X} \subseteq \mathbb{R}^n\),輸出空間為\(\mathcal{Y} = \{c_1, c_2, ..., c_K\}\)。\(\textbf{X}\)為輸入空間上的随機向量,其取值為\(\textbf{x}\),滿足\(\textbf{x} \in \mathcal{X}\);\(Y\)為輸出空間上的随機變量,設其取值為\(y\),滿足\(y \in \mathcal{Y}\)。我們将容量為\(m\)的訓練樣本表示為:
\[\begin{aligned}
D = \{\{\textbf{x}^{(1)}, y^{(1)}\}, \{\textbf{x}^{(2)}, y^{(2)}\},..., \{\textbf{x}^{(m)}, y^{(m)}\}\}
\end{aligned}\tag{1}
\]
\[
我們遵循機器學習的一個基本假設,即訓練樣本是從一個未知的總體分布\(P(\textbf{X} = \textbf{x}, Y=y)\)中采樣産生,且訓練樣本獨立同分布。
我們采取機率模型的視角,即将分類模型表示為條件機率分布\(P(Y=y|\textbf{X}=\textbf{x})\)。而依據分布\(P(Y=y|\textbf{X}=\textbf{x})\)的求解可将模型分為判别模型和生成模型。判别模型直接對條件機率分布\(P(Y=y|\textbf{X}=\textbf{x})\)進行參數估計(估計方法可采用極大似然估計或貝葉斯估計);而生成模型則利用條件機率公式\(P(Y=y|\textbf{X}=\textbf{x}) = \frac{P(\textbf{X}=\textbf{x}, Y=y)}{P(\textbf{X}=\textbf{x})}\)來計算分布。分子\(P(\textbf{X}=\textbf{x}, Y=y)\)是一個聯合機率分布,能夠還原出聯合機率分布\(P(\textbf{X}=\textbf{x}, Y=y)\)是生成模型的一大特性。
我們對分子繼續運用條件機率公式,進一步得到
P(Y=y|\textbf{X}=\textbf{x}) = \frac{P(\textbf{X}=\textbf{x}|Y=y)P(Y=y)}{P(\textbf{X}=\textbf{x})}
\end{aligned} \tag{2}
這個公式即大名鼎鼎的貝葉斯公式。 這裡我們采用貝葉斯學派的視角,将\(P(Y=y)\)稱為先驗機率分布,表示在資料觀測之前對\(Y\)的信念;\(P(Y = y|\textbf{X}=\textbf{x})\)稱為後驗機率分布,表示經過觀測資料\(\textbf{X}\)(也稱“證據”)校正後對\(Y\)的信念。注意不要和和貝葉斯估計中參數\(\theta\)的先驗和後驗分布搞混了,貝葉斯估計也應用了貝葉斯公式,但先驗機率分布和後驗機率分布的實際含義與這裡完全不同。
我們再将分母運用全機率公式展開,我們得到
P(Y=y|\textbf{X}=\textbf{x})= \frac{P(\textbf{X}=\textbf{x}|Y=y)P(Y=y)}{\sum_{y\in \mathcal{Y}}P(\textbf{X}=\textbf{x}|Y=y)P(Y=y)}
\end{aligned}\tag{3}
這意味着我們隻需要學習機率分布\(P(Y=y)\)和\(P(\textbf{X}=\textbf{x}|Y=y)\),而無需關心\(P(\textbf{X}=\textbf{x})\)。
将随機向量\(\textbf{x}\)沿着其特征次元展開,我們繼續得到
P(\textbf{X} = \textbf{x} | Y = y) = P(X_1 = x_1, ..., X_n = x_n | Y=y), \quad n \text{為特征次元}
\end{aligned}\tag{4}
這裡我們為了簡單起見,假設樣本屬性是離散的,第\(j\)個屬性\(x_j\)的屬性集為\(A_j=\{a_{j1}, a_{j2},...,a_{jl},..., a_{j{N_j}}\}\),滿足\(x_j \in A_j\)。可以看出,條件機率分布\(P(\textbf{X}=\textbf{x}|Y=y)\)的參數總量是指數級的(\(x_j\)的屬性集\(A_j\)大小為\(N_j\),\(j=1, 2, ..., n\),\(Y\)可取值有\(K\)個,那麼參數個數為\(K \prod_{j=1}^{n}N_j\)),不能對其直接進行參數估計。
是以,我們決定對原本擁有指數級參數數量的分布進行拆分。這裡,樸素貝葉斯法做出了條件獨立性假設:樣本特征在類确定的條件下條件獨立(這也是“樸素”(Naive)一詞的得名)。這樣我們就能将原本擁有龐大參數的機率分布進行拆分:
P(\textbf{X} = \textbf{x} | Y=y) = P(X_1 = x_1, ..., X_n = x_n | Y=y) = \prod_{j=1}^nP(X_j = x_j | Y = y)
\end{aligned}\tag{5}
這樣,我們就可以對\(P(\textbf{X} | Y=y)\)分布進行高效的參數估計。之後,我們對于輸入樣本\(\textbf{x}\),計算機率分布\(P(Y=y|\textbf{X}=\textbf{x})\):
P(Y=y|\textbf{X}=\textbf{x})= \frac{P(\textbf{X}=\textbf{x}|Y=y)P(Y=y)}{\sum_{ y \in \mathcal{Y}}P(\textbf{X}=\textbf{x}|Y=y)P(Y=y)}
= \frac{\prod_{j=1}^nP(X_j = x_j | Y=y)P(Y=y)}{\sum_{y \in \mathcal{Y}}[ \prod_{j=1}^nP(X_j = x_j | Y=y)P(Y=y) ]}
\end{aligned}\tag{6}
我們采取後驗機率最大化原則(即最終的輸出分類取使條件機率最大的那個),設\(f(\textbf{x})\)為分類決策函數,即
y = f(\textbf{x}) = \underset{y}{\arg\max} P(Y = y|\textbf{X}=\textbf{x})=\underset{y}{\arg\max}\frac{\prod_{j=1}^nP(X_j = x_j | Y=y)P(Y=y)}{\sum_{y \in \mathcal{Y}}[ \prod_{j=1}^nP(X_j = x_j | Y=y)P(Y=y) ]}
\end{aligned}\tag{7}
我們發現,不管\(y\)取何值,式\((7)\)中分母總是恒定的,是以我們可以将式\((7)\)化簡為
y = f(\textbf{x}) = \underset{y}{\arg\max} P(Y=y|\textbf{X}=\textbf{x}) = \underset{y}{\arg\max}\prod_{j=1}^nP(X_j = x_j | Y=y)P(Y=y)
\end{aligned}\tag{8}
這就是樸素貝葉斯模型分類決策函數的最終表達式。
如式\((8)\)中所述,我們需要對先驗機率分布\(P(Y=y)\)和條件機率分布\(P(X_j = x_j|Y=y)\)進行參數估計。根據極大似然估計(具體的推導過程可以參見李航《統計學習方法》中的習題解答),我們可以運用訓練集\(D\)将先驗機率分布\(P(Y=y)\)估計為
P(Y=y) = \frac{\sum_{i=1}^m(y^{(i)} = y)}{m}, \quad m \text{為}D \text{中樣本個數}
\end{aligned} \tag{9}
同樣,條件機率分布\(P(X_j = x_j|Y=y)\)的估計為
P(X_j = x_j | Y=y) = \frac{P(X_j = x_j, Y = y)}{P(Y = y)} = \frac{\sum_{i=1}^{m}I(x_j^{(i)} =x_j, y^{(i)}=y)}{\sum_{i=1}^{m}I(y^{(i)}=y)}
, \quad m \text{為}D \text{中樣本個數}
\end{aligned} \tag{10}
觀察式\((10)\)可知,如果訓練集中屬性值\(x_j\)和類\(y\)沒有同時出現過,即\(P(X_j=x_j, Y=y)=0\),那麼\(P(X_j = x_j | Y=y)=0\)會直接導緻連乘式。這就意味着不管其他屬性如何,哪怕其他屬性明顯符合要求,樣本\(\prod_{j=1}^nP(X_j = x_j | Y=y)=0\) ,\(\textbf{x}\)屬于類\(y\)的機率都會被判為0,這明顯不太合理。
是以,為了避免其他屬性攜帶的資訊被訓練集中未出現的屬性值“抹去”,我們采用貝葉斯估計,等價于在估計機率值時通常進行“平滑”(smoothing)(具體的推導過程可以參見李航《統計學習方法》中的習題解答)。即令式\((10)\)修正為
P_{\lambda}(X_j = x_j|Y=y) = \frac{\sum_{i=1}^{m}I(x_j^{(i)} =x_j, y^{(i)}=y) + \lambda}{\sum_{i=1}^{m}I(y^{(i)}=y)+N_j \lambda}, \quad \lambda > 0, \quad N_j\text{為屬性}x_j\text{可能的取值數}
\end{aligned} \tag{11}
我們常取\(\lambda=1\),這時稱為拉普拉斯平滑(Laplacian smoothing)。
類似地,式\((9)\)中先驗機率被修正為:
P_\lambda(Y=y) = \frac{\sum_{i=1}^m(y^{(i)} = y)+\lambda}{m+K\lambda}, \quad \lambda > 0, \quad K\text{為标簽}y\text{可能的取值數}
\end{aligned} \tag{12}
可以看出,拉普拉斯平滑解決了訓練集樣本數不足導緻的機率值為 0 的問題。拉普拉斯修正實際上假設了屬性值與類别均勻分布,這是在參數估計的過程中額外引入的關于資料的先驗 (prior)。當樣本容量趨近于無窮時,我們發現修正過程所引入的先驗的影響也趨近于 0,使得計算的機率值趨近于實際的機率值。
在實際的應用中,樸素貝葉斯模型有兩種訓練方式。
若使用的場景對模型的預測速度要求較高,在給定訓練集\(D\)的情況下,我們将機率分布\(P_\lambda(Y=y)\)和機率分布\(P_{\lambda}(X_j = x_j|Y=y)\)所有可能的取值(\(y\in \mathcal{Y}\),\(x_j \in A_j\),\(A_j\)為第\(j\)個樣本屬性的取值集合)都計算出來存好,然後在測試樣本\(\textbf{x}^{*}\)來了之後,通過“查表”的方式将對應的機率值檢索出來,然後再對其類别進行判别。這樣,我們計算機率分布\(P_\lambda(Y=y)\)和機率分布\(P_{\lambda}(X_j = x_j|Y=y)\)所有可能取值的過程即對樸素貝葉斯模型進行顯式訓練的過程。
樸素貝葉斯的訓練和測試算法如下:
如果我們不斷有新的訓練資料産生,可以采用“懶惰學習”(lazy learning)的方法,先不進行任何訓練,測試樣本來了之後再依照測試樣本的屬性\(x_j^{*}\)和目前資料集的狀況來計算單點機率,這樣可以避免對所有可能的屬性都計算單點機率。若訓練資料不斷增加,則可在現有計算結果的基礎上,僅僅對新增樣本的屬性值所涉及的單點機率進行計數修正,這樣可以實作“增量學習”。
使用Python語言實作樸素貝葉斯算法如下(這裡我們采用Iris資料集進行測試)。
最終的測試結果如下:
可以看出我們實作的算法在Iris資料集上取得了90%的精度,說明我們算法的效果不錯。
[1] 李航. 統計學習方法(第2版)[M]. 清華大學出版社, 2019.
[2] 周志華. 機器學習[M]. 清華大學出版社, 2016.
[3] Calder K. Statistical inference[J]. New York: Holt, 1953.
數學是符号的藝術,音樂是上界的語言。