1. 程式人生 > >分類——樸素貝葉斯分類器以及Python實現

分類——樸素貝葉斯分類器以及Python實現

核心思想:

根據訓練資料獲取模型的後驗概率,對應後驗概率越大的類即預測類。

演算法簡介:

模型:

  1. 先驗概率:p(y=Ck)
  2. 條件概率:p(X=x|y=Ck)
  3. 後驗概率:p(y=Ck|X=x)
    樸素的含義:輸入向量x的各個維度間是相互獨立的,那麼條件概率的計算公式可以大大簡化p(X=x|y=Ck)=jnp(Xj=xj|y=Ck)其中n為輸入維度數。
    根據貝葉斯定理:
    p(y=Ck|X=x
    )=p(X=x|y=Ck)p(y=Ck)p(X=x)
    由於p(X=x)對所有的類來說是一樣的,故只需要計算分子(聯合概率分佈)即可。

策略

統計機器學習的策略通常是期望風險最小化,實際學習過程中以經驗風險近似期望風險(或加上正則化項)。在樸素貝葉斯方法中,期望風險最小化等價於後驗概率最大化(具體推導過程參考李航《統計學習方法》)。

學習方法(模型的引數估計):

模型中後驗概率的計算需要先獲取先驗概率以及條件概率分佈,這兩個概率的引數是通過訓練資料集學習得到的,具體的學習方法有:極大似然估計以及後驗期望估計。極大似然估計等同於先驗分佈為均勻分佈的後驗期望估計(具體參看上一篇部落格)。具體公式參考李航《統計學習方法》。注意:書中引數的貝葉斯估計就是先驗分佈為均勻分佈的後驗期望估計。

演算法流程

  • Input: 訓練資料集X, y
  • Output: 每個類和,每個維度上取值的聯合概率
  • Step1: 採用後驗期望估計方法估計後驗概率
  • Step2: 採用後驗期望估計方法估計條件概率
  • Step3:根據Step1, 2結果,計算聯合分佈概率

程式碼

"""
樸素貝葉斯分類演算法
採用後驗期望估計引數,先驗概率分佈取均勻分佈
"""

from collections import Counter, defaultdict
import numpy as np


class NBayes:
    def __init__(self, lambda_=1):
        self.lambda_ = lambda_  # 貝葉斯估計方法引數lambda
self.p_prior = {} # 模型的先驗概率, 注意這裡的先驗概率不是指預先人為設定的先驗概率,而是需要估計的P(y=Ck) self.p_condition = {} # 模型的條件概率 def fit(self, X_data, y_data): N = y_data.shape[0] # 後驗期望估計P(y=Ck)的後驗概率,設定先驗概率為均勻分佈 c_y = Counter(y_data) K = len(c_y) for key, val in c_y.items(): self.p_prior[key] = (val + self.lambda_) / (N + K * self.lambda_) # 後驗期望估計P(Xd=a|y=Ck)的後驗概率,同樣先驗概率為均勻分佈 for d in range(X_data.shape[1]): # 對各個維度分別進行處理 Xd_y = defaultdict(int) vector = X_data[:, d] Sd = len(np.unique(vector)) for xd, y in zip(vector, y_data): # 這裡Xd僅考慮出現在資料集D中的情況,故即使用極大似然估計葉沒有概率為0的情況 Xd_y[(xd, y)] += 1 for key, val in Xd_y.items(): self.p_condition[(d, key[0], key[1])] = (val + self.lambda_) / (c_y[key[1]] + Sd * self.lambda_) return def predict(self, X): p_post = defaultdict() for y, py in self.p_prior.items(): p_joint = py # 聯合概率分佈 for d, Xd in enumerate(X): p_joint *= self.p_condition[(d, Xd, y)] # 條件獨立性假設 p_post[y] = p_joint # 分母P(X)相同,故直接儲存聯合概率分佈即可 return max(p_post, key=p_post.get) if __name__ == '__main__': data = np.array([[1, 0, -1], [1, 1, -1], [1, 1, 1], [1, 0, 1], [1, 0, -1], [2, 0, -1], [2, 1, -1], [2, 1, 1], [2, 2, 1], [2, 2, 1], [3, 2, 1], [3, 1, 1], [3, 1, 1], [3, 2, 1], [3, 2, -1]]) X_data = data[:, :-1] y_data = data[:, -1] clf = NBayes(lambda_=1) clf.fit(X_data, y_data) print(clf.p_prior, '\n', clf.p_condition) print(clf.predict(np.array([2, 0])))

我的GitHub
注:如有不當之處,請指正。