樸素貝葉斯算法(Naive Bayes) 原理總結

樸素貝葉斯算法是基於貝葉斯定理和特徵條件獨立假設的分類方法。對於給定的訓練數據集,首先基於特徵條件獨立假設學習輸入輸出的聯合概率分佈;然後基於此模型,對給定的輸入x,利用貝葉斯定理求出後驗概率最大的輸出y。

1 數學知識

貝葉斯定理:

特徵條件獨立假設:

 

2 樸素貝葉斯

2.1 算法原理

輸入空間:技術分享

輸出空間:y={C1,C2,…,CK}。

訓練集:T={(x1,y1),(x2,y2),…,(xN,yN)}。

對於每個實例,其P(X,Y)獨立同分布。樸素貝葉斯算法通過訓練數據集學習聯合概率分佈P(X,Y)。具體地,分爲學習先驗概率分佈和條件概率分佈。然後據此計算出後驗概率分佈。

1) 先驗概率分佈:

P(Y=Ck),k=1,2,..,K。

先驗概率的極大似然估計:

技術分享

2)條件概率分佈:

技術分享

則極大似然估計:

技術分享技術分享

  說明:每個實例有n個特徵,分別爲x_{1},x_{2},...,x_{n},每個特徵分別有s_{1},s_{2},...,s_{n}種取值,即特徵x_{i}s_{i}種取值。則計算該條件概率分佈P(x|y_{i})的時間複雜度爲:O(s_{1}*s_{2}*...*s_{n}),  若類別取值有m個,參數個數爲m\prod_{i=1}^{n}s_{i},   時間複雜度非常的高。

3)對新的實例進行分類:

         爲了計算將新的實例進行分類,我們需要計算該實例屬於每類的後驗概率,最終將此實例分給後驗概率最大的類。

後驗概率爲:

技術分享

所以,樸素貝葉斯算法對條件概率分佈作了條件獨立性假設。即在分類確定的情況下,x的各特徵相互獨立。因爲用到了此假設故而在貝葉斯前面加了樸素二字。於是有:

技術分享

所以有:

技術分享

由於對同一個實例,P(X=x)的概率相通同,故而只需考慮分子部分即可。

技術分享

2.2  樸素貝葉斯的改進

         在計算條件概率時,有可能出現極大似然函數爲0的情況,這時需要在分子分母上添加上一個正數,使得其值不爲0.

技術分享

技術分享

同樣,先驗概率的貝葉斯估計也需要改進:

技術分享

2.3  後驗概率最大化

         樸素貝葉斯將實例分到後驗概率最大的類中,等價於0-1損失函數時期望風險最小化。

0-1損失函數爲:

技術分享

期望風險爲:

技術分享

爲了使期望風險最小化,只需對X=x逐個極小化,

技術分享

即通過期望風險最小化,得到了後驗概率最大化。

 

3 三種常見模型

樸素貝葉斯算法有三種常見模型:多項式模型、高斯模型、伯努利模型。

1)多項式模型

當特徵是離散時,採用多項式模型。 

2)高斯模型

當特徵是連續變量時,採用高斯模型。

高斯模型的前提是----假設數據每一維特徵都服從高斯分佈,則p(x_{i}|y_{k})的計算公式爲:

p(x_{i}|y_{k})=\frac{1}{\sqrt{2\pi \sigma _{y_{k,i}^{2}}}}e^{-\frac{x_{i}-\mu _{y_{k,i}}}{2\sigma_{y_{k,i}}^{2}}}

i 是第i維特徵

3)伯努利模型

 

4 python 實現

import numpy as np


class NaiveBayesian:
    def __init__(self, alpha):
        self.classP = dict()
        self.classP_feature = dict()
        self.alpha = alpha  # 平滑值

    # 加載數據集
    def createData(self):
        data = np.array(
            [
                [320, 204, 198, 265],
                [253, 53, 15, 2243],
                [53, 32, 5, 325],
                [63, 50, 42, 98],
                [1302, 523, 202, 5430],
                [32, 22, 5, 143],
                [105, 85, 70, 322],
                [872, 730, 840, 2762],
                [16, 15, 13, 52],
                [92, 70, 21, 693],
            ]
        )
        labels = np.array([1, 0, 0, 1, 0, 0, 1, 1, 1, 0])
        return data, labels

    # 計算高斯分佈函數值
    def gaussian(self, mu, sigma, x):
        return 1.0 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))

    # 計算某個特徵列對應的均值和標準差
    def calMuAndSigma(self, feature):
        mu = np.mean(feature)
        sigma = np.std(feature)
        return (mu, sigma)

    # 訓練樸素貝葉斯算法模型
    def train(self, data, labels):
        numData = len(labels)
        numFeaturs = len(data[0])
        # 是異常用戶的概率
        self.classP[1] = (
                (sum(labels) + self.alpha) * 1.0 / (numData + self.alpha * len(set(labels)))
        )
        # 不是異常用戶的概率
        self.classP[0] = 1 - self.classP[1]

        # 用來存放每個label下每個特徵標籤下對應的高斯分佈中的均值和方差
        # { label1:{ feature1:{ mean:0.2, var:0.8 }, feature2:{} }, label2:{...} }
        self.classP_feature = dict()
        # 遍歷每個特徵標籤
        for c in set(labels):
            self.classP_feature[c] = {}
            for i in range(numFeaturs):
                feature = data[np.equal(labels, c)][:, i]
                self.classP_feature[c][i] = self.calMuAndSigma(feature)

    # 預測新用戶是否是異常用戶
    def predict(self, x):
        label = -1  # 初始化類別
        maxP = 0

        # 遍歷所有的label值
        for key in self.classP.keys():
            label_p = self.classP[key]
            currentP = 1.0
            feature_p = self.classP_feature[key]
            j = 0
            for fp in feature_p.keys():
                currentP *= self.gaussian(feature_p[fp][0], feature_p[fp][1], x[j])
                j += 1
            # 如果計算出來的概率大於初始的最大概率,則進行最大概率賦值 和對應的類別記錄
            if currentP * label_p > maxP:
                maxP = currentP * label_p
                label = key
        return label

if __name__ == "__main__":
    nb = NaiveBayesian(1.0)
    data, labels = nb.createData()
    nb.train(data, labels)
    label = nb.predict(np.array([134, 84, 235, 349]))
    print("未知類型用戶對應的行爲數據爲:[134,84,235,349],該用戶的可能類型爲:{}".format(label))

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章