樸素貝葉斯法(naive Bayes algorithm)

對於給定的訓練數據集,樸素貝葉斯法首先基於iid假設學習輸入/輸出的聯合分佈;而後基於此模型,對給定的輸入x,利用貝葉斯定理求出後驗機率最大的輸出y。html

1、目標


設輸入空間是n維向量的集合,輸出空間爲類標記集合= {c1, c2, ..., ck}。X是定義在上的隨機變量,Y是定義在上的隨機變量。P(X, Y)是X和Y的聯合機率分佈。訓練數據集 T = {(x1, y1), (x2, y2), ..., (xN, yN)}由P(X, Y)獨立同分布產生。python

樸素貝葉斯法的學習目標是習得聯合機率分佈P(X, Y),以此計算後驗機率,從而將實例分到後驗機率最大的類中。因爲P(X, Y) = P(Y)P(X|Y),所以學習目標能夠具體到先驗機率分佈P(Y = ck)和條件機率分佈P(X = x|Y = ck)(k = 1, 2, ..., K)。算法

2、後驗機率最大化的原理


最大化後驗機率等價於最小化指望損失(expected loss),或者說條件風險(conditional risk)。設選擇0-1損失函數數組

其中f(X)是分類決策函數,則指望損失爲函數

因爲指望是對聯合分佈P(X, Y)取的,所以上式可推出學習

貝葉斯斷定準則(Bayes decision rule):最小化整體風險,只需在每一個樣本上選擇那個能使條件風險最小的類別標記。因而spa

這樣一來,根據指望風險最小化準則就獲得後驗機率從最大化準則:code

另外一方面,由條件獨立性假設htm

與貝葉斯定理blog

獲得

因爲上式中分佈對ck都是相同的,所以

3、參數估計:極大似然估計


先驗機率P(Y = ck)的極大似然估計:

條件機率P(X(j) = ajl|Y = ck)的極大似然估計:

其中設第j個特徵x(j)可能的取值集合爲{aj1, aj2, ..., ajSj},I爲指示函數。

4、算法僞碼及實現


書中給中了算法的僞碼

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

下面給出樸素貝葉斯算法的具體實現

『python』代碼摘自https://www.cnblogs.com/yiyezhouming/p/7364688.html

#coding:utf-8
# 極大似然估計  樸素貝葉斯算法
import pandas as pd
import numpy as np

class NaiveBayes(object):
    def getTrainSet(self):
        dataSet = pd.read_csv('C://pythonwork//practice_data//naivebayes_data.csv')
        dataSetNP = np.array(dataSet)  #將數據由dataframe類型轉換爲數組類型
        trainData = dataSetNP[:,0:dataSetNP.shape[1]-1]   #訓練數據x1,x2
        labels = dataSetNP[:,dataSetNP.shape[1]-1]        #訓練數據所對應的所屬類型Y
        return trainData, labels

    def classify(self, trainData, labels, features):
        #求labels中每一個label的先驗機率
        labels = list(labels)    #轉換爲list類型
        P_y = {}       #存入label的機率
        for label in labels:
            P_y[label] = labels.count(label)/float(len(labels))   # p = count(y) / count(Y)

        #求label與feature同時發生的機率
        P_xy = {}
        for y in P_y.keys():
            y_index = [i for i, label in enumerate(labels) if label == y]  # labels中出現y值的全部數值的下標索引
            for j in range(len(features)):      # features[0] 在trainData[:,0]中出現的值的全部下標索引
                x_index = [i for i, feature in enumerate(trainData[:,j]) if feature == features[j]]
                xy_count = len(set(x_index) & set(y_index))   # set(x_index)&set(y_index)列出兩個表相同的元素
                pkey = str(features[j]) + '*' + str(y)
                P_xy[pkey] = xy_count / float(len(labels))

        #求條件機率
        P = {}
        for y in P_y.keys():
            for x in features:
                pkey = str(x) + '|' + str(y)
                P[pkey] = P_xy[str(x)+'*'+str(y)] / float(P_y[y])    #P[X1/Y] = P[X1Y]/P[Y]

        #求[2,'S']所屬類別
        F = {}   #[2,'S']屬於各個類別的機率
        for y in P_y:
            F[y] = P_y[y]
            for x in features:
                F[y] = F[y]*P[str(x)+'|'+str(y)]     #P[y/X] = P[X/y]*P[y]/P[X],分母相等,比較分子便可,因此有F=P[X/y]*P[y]=P[x1/Y]*P[x2/Y]*P[y]

        features_label = max(F, key=F.get)  #機率最大值對應的類別
        return features_label


if __name__ == '__main__':
    nb = NaiveBayes()
    # 訓練數據
    trainData, labels = nb.getTrainSet()
    # x1,x2
    features = [2,'S']
    # 該特徵應屬於哪一類
    result = nb.classify(trainData, labels, features)
    print features,'屬於',result
相關文章
相關標籤/搜索