[西瓜書]樸素貝葉斯--numpy + python實現
貝葉斯定理
現在假設有兩個事件分別為A和B,貝葉斯定理則可以描述在事件A發生的前提下B發生的概率以及在事件B發生的前提下事件A發生的概率之間的關係。有點繞?畫個圖就能理解了~
現在假設事件A發生的概率為
上述的公式就是貝葉斯公式。推到過程是不是很簡單~
樸素貝葉斯概率模型
基本思想
回到分類的問題上,我們想要通過上面的公式解決具體的分類問題。首先,我們根據一般的分類問題將上面公式中提到的A和B具體化一下,我們指示A為樣本,其包含樣本所有的特徵資料。B為分類的類別。為更好的對對應起來,我們用x代指一個樣本資料,c代表一個分類類別。那麼就有如下的貝葉斯公式:
這個公式的左邊描述的是,在我們已知一個數據樣本的情況下,其歸屬類別c的概率。很自然的我們就可以想到,將資料x和類別對應的一一計算,分別計算該樣本在被分類到不同類別的概率,找到概率最大的那個類別,就是我們將要分類的類別了。
問題簡化
確定解決的方向之後,因為需要實際的解決問題,我們當然希望計算的過程越簡單越好,所以我們需要對問題模型進行適當的處理,而又儘量的保持原方法的理論準確率。
簡化公式
公式方面,我們觀察到P(x)和類別沒有關係,也就是說對於任何類別的概率計算,p(x)都是一個常數,並不會影響最終的結果。所以我們可以將其從公式中刪除掉,簡化後得到下面的公式:
簡化模型
從上面簡化之後的公式中我們可以看出,其和聯合分佈其實有點類似
在實際情況中,如果考慮特徵之間的關聯性。我們通常沒有辦法直接計算
這樣忽略屬性之間的相關性在周老師的書中被稱之為“屬性條件獨立性假設(attribute conditional independence assumption)”。基於這樣的前提,我們繼續使用聯絡分佈公式,以第二個等式為例:
繼續分解下去我們可以得到
通過上面最後一個公式,我們可以很方便的計算出在已知一個樣本的情況下,其歸屬於不同類別的概率。
那現在就讓我們來程式設計實現一下吧:
python實現
"""
樸素貝葉斯
基於貝葉斯公式,並添加了屬性條件獨立性假設。
"""
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris() # 載入資料
y = iris.target
x = iris.data
def naive_bayes(x, y, predict):
unique_y = list(set(y))
label_num = len(unique_y)
sample_num, dim = x.shape
joint_p = [1] * label_num
# 把所有的類別都過一遍,計算P(c)
for (label_index, label) in enumerate(unique_y):
p_c = len(y[y == label]) / sample_num
for (feature_index, x_i) in enumerate(predict):
tmp = x[y == label]
joint_p[label_index] *= len(
[t for t in tmp[:, feature_index] if t == x_i]) / len(tmp)
joint_p[label_index] *= p_c
tmp = joint_p[0]
max_index = 0
for (i, p) in enumerate(joint_p):
if tmp < p:
tmp = p
max_index = i
return unique_y[max_index]
# 測試所用的資料為資料集中最後一個數據,類別為2
out = naive_bayes(x, y, np.array([5.9, 3., 5.1, 1.8]))
print(out)
好了大功告成~希望對大家有幫助~