朴素貝葉斯原理、實例與Python實現


初步理解一下:對於一組輸入,根據這個輸入,輸出有多種可能性,需要計算每一種輸出的可能性,以可能性最大的那個輸出作為這個輸入對應的輸出。

那么,如何來解決這個問題呢?

貝葉斯給出了另一個思路。根據歷史記錄來進行判斷。

思路是這樣的:

1、根據貝葉斯公式:P(輸出|輸入)=P(輸入|輸出)*P(輸出)/P(輸入)

2、P(輸入)=歷史數據中,某個輸入占所有樣本的比例;

3、P(輸出)=歷史數據中,某個輸出占所有樣本的比例;

4、P(輸入|輸出)=歷史數據中,某個輸入,在某個輸出的數量占所有樣本的比例,例如:30歲,男性,中午吃面條,其中【30歲,男性就是輸入】,【中午吃面條】就是輸出。

 

一、條件概率的定義與貝葉斯公式

二、朴素貝葉斯分類算法

朴素貝葉斯是一種有監督的分類算法,可以進行二分類,或者多分類。一個數據集實例如下圖所示:

 

 

現在有一個新的樣本, X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中),目標是利用朴素貝葉斯分類來進行分類。假設類別為C(c1=是 或 c2=否),那么我們的目標是求出P(c1|X)和P(c2|X),比較誰更大,那么就將X分為某個類。

下面,公式化朴素貝葉斯的分類過程。

 

 

三、實例

下面,將下面這個數據集作為訓練集,對新的樣本X = (年齡:<=30, 收入:中, 是否學生:是, 信譽:中)  作為測試樣本,進行分類。

我們可以將這個實例中的描述屬性和類別屬性,與公式對應起來,然后計算。

參考python實現代碼

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

class NaiveBayes(object):
    def getTrainSet(self):
        dataSet = pd.read_csv('F://aaa.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類型
        labelset = set(labels)
        P_y = {}       #存入label的概率
        for label in labelset:
            P_y[label] = labels.count(label)/float(len(labels))   # p = count(y) / count(Y)
            print(label,P_y[label])

        #求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))
                print(pkey,P_xy[pkey])

        #求條件概率
        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]
                print(pkey,P[pkey])

        #求[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]
                print(str(x),str(y),F[y])

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


if __name__ == '__main__':
    nb = NaiveBayes()
    # 訓練數據
    trainData, labels = nb.getTrainSet()
    # x1,x2
    features = [8]
    # 該特征應屬於哪一類
    result = nb.classify(trainData, labels, features)
    print(features,'屬於',result)
    
    
#coding:utf-8
#朴素貝葉斯算法   貝葉斯估計, λ=1  K=2, S=3; λ=1 拉普拉斯平滑
import pandas as pd
import numpy as np

class NavieBayesB(object):
    def __init__(self):
        self.A = 1    # 即λ=1
        self.K = 2
        self.S = 3

    def getTrainSet(self):
        trainSet = pd.read_csv('F://aaa.csv')
        trainSetNP = np.array(trainSet)     #由dataframe類型轉換為數組類型
        trainData = trainSetNP[:,0:trainSetNP.shape[1]-1]     #訓練數據x1,x2
        labels = trainSetNP[:,trainSetNP.shape[1]-1]          #訓練數據所對應的所屬類型Y
        return trainData, labels

    def classify(self, trainData, labels, features):
        labels = list(labels)    #轉換為list類型
        #求先驗概率
        P_y = {}
        for label in labels:
            P_y[label] = (labels.count(label) + self.A) / float(len(labels) + self.K*self.A)

        #求條件概率
        P = {}
        for y in P_y.keys():
            y_index = [i for i, label in enumerate(labels) if label == y]   # y在labels中的所有下標
            y_count = labels.count(y)     # y在labels中出現的次數
            for j in range(len(features)):
                pkey = str(features[j]) + '|' + str(y)
                x_index = [i for i, x in enumerate(trainData[:,j]) if x == features[j]]   # x在trainData[:,j]中的所有下標
                xy_count = len(set(x_index) & set(y_index))   #x y同時出現的次數
                P[pkey] = (xy_count + self.A) / float(y_count + self.S*self.A)   #條件概率

        #features所屬類
        F = {}
        for y in P_y.keys():
            F[y] = P_y[y]
            for x in features:
                F[y] = F[y] * P[str(x)+'|'+str(y)]

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


if __name__ == '__main__':
    nb = NavieBayesB()
    # 訓練數據
    trainData, labels = nb.getTrainSet()
    # x1,x2
    features = [10]
    # 該特征應屬於哪一類
    result = nb.classify(trainData, labels, features)
    print(features,'屬於',result)

 

參考鏈接:

https://blog.csdn.net/ten_sory/article/details/81237169

https://www.cnblogs.com/yiyezhouming/p/7364688.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM