樸素貝葉斯(Naive Bayes)算法

樸素貝葉斯算法屬于分類算法。發(fā)源于古典數(shù)學(xué)理論,對缺失數(shù)據(jù)不太敏感,有穩(wěn)定的分類效率,模型所需估計的參數(shù)很少,算法比較簡單。

樸素貝葉斯算法,貝葉斯是說明這個算法和貝葉斯定理有聯(lián)系,而樸素是因為處理實際的需要,做了一個簡化——假設(shè)每個特征之間是獨立的(如果研究的對象互相之間的影響很強,計算概率時考慮的問題非常復(fù)雜,做了獨立假設(shè),就可以分解后進行研究),這是這個算法模型與貝葉斯定理的區(qū)別。

image.png

將 x 作為特征,y 作為類別,那公式左邊的 P(yi|x)就是說在知道特征 x 的情況下,計算這個特征屬于 yi 類的可能性大小。通過比較找出這個可能性的值最大的屬于哪一類,就將特征 x 歸為這一類。

image.png

第3步的計算就是整個關(guān)鍵所在,計算依據(jù)是上面的貝葉斯公式。

對于每一個類的概率計算,公式右邊的分母的 P(x)都是相同的,所以可以不計算(我們只是對最終結(jié)果進行比較,不影響)。

P(yi)也稱為先驗概率,是 x 屬于 yi 類的一個概率,這個是通過歷史信息得到的(在程序?qū)崿F(xiàn)的時候,歷史信息或者說先驗信息就是我們的訓(xùn)練數(shù)據(jù)集),我們通過對訓(xùn)練樣本數(shù)據(jù)進行統(tǒng)計,分別算出 x 屬于 y1,y2,...,yn 類的概率是多少,這個是比較容易得到的。

所以,主要是求 P(x|yi)= P(a1,a2,...,am|yi)

這個時候?qū)τ谪惾~斯模型的樸素的獨立性假設(shè)就發(fā)揮作用了(綜合的計算變成了獨立計算后的綜合,簡化模型,極大地減少了計算的復(fù)雜程度):

P(a1,a2,...,am|yi) = P(a1|yi)P(a2|yi)...P(am|yi)

所以計算想要得到的東西如下:


image.png

一個程序簡例

'''#########################################################################################
# Name: NB-test
# Author: Wenchao Liu
# Date: 2018-12-23
# Description: To study the Naive Bayes method by using a simple example.
#                    Windows10, Python3.7
#########################################################################################'''

def dealData(D, L):
    '''將訓(xùn)練集中的連續(xù)數(shù)據(jù)離散化,符號數(shù)據(jù)數(shù)值化。'''
    for item in D:
        if(int(item[0]) > 0):
            item[0] = 1
        if(float(item[2]) > 0.5):
            item[2] = 1
        else:
            item[2] = 0
    #print(data)
    for i in range(len(L)):
        if(L[i] == '漲'):
            L[i] = 1
        else:
            L[i] = 0
    #print(L)
    return D, L

def splitData(D, L):
    '''將訓(xùn)練集中的不同類數(shù)據(jù)分開,方便統(tǒng)計處理。'''
    D0 = []
    D1 = []
    for i in range(len(L)):
        if(L[i] == 0):
            D0.append(D[i])
        elif(L[i] == 1):
            D1.append(D[i])
    #print(D0, D1)
    return D0, D1      

def countNumber(data, i, z):
    '''統(tǒng)計某個屬性出現(xiàn)的次數(shù)。'''
    number = 0
    for item in data:
        if(item[i] == z):
            number = number + 1
    return number

def calculateProbobility(D0, D1, L, Z):
    '''對于目標(biāo)對象,計算其屬于各類別的概率大小。'''
    # 計算訓(xùn)練樣本中不同類別的數(shù)量
    num_down = L.count(0)
    num_up = L.count(1)
    # 先驗概率(類別分布不均衡會對概率計算造成較大影響,先不考慮)
    p0 = num_down/len(L)
    p1 = num_up/len(L)
    #print(p0, p1)
    # 存放各屬性對應(yīng)的概率
    p_down = []
    p_up = []
    # 拉普拉斯平滑
    delta = 1    # 取大于 0 的數(shù),一般使用 1 
    feature_num = 2    # 某特征可以取值個數(shù),此處為二值型特征
    for i in range(len(Z)):
        p_down.append((countNumber(D0, i, Z[i])+delta)/(len(D0)+ feature_num*delta))
        p_up.append((countNumber(D1, i, Z[i])+delta)/(len(D1)+ feature_num*delta))
    #print(p_down, p_up)
    pc0 = 1
    pc1 = 1
    for i in range(len(Z)):
        pc0 = pc0 * p_down[i]
        pc1 = pc1 * p_up[i]
    Pc = [pc0, pc1]
    #print(pc0,pc1)
    return Pc

def selectClass(Pc, Lc):
    '''找出對應(yīng)概率最大的類別,預(yù)測目標(biāo)對象為此類別。'''
    max_index = Pc.index(max(Pc))
    print('********** NB算法預(yù)測結(jié)果 **********')
    print('預(yù)測目標(biāo)結(jié)果為:' + Lc[max_index])
 
def main():
    # 訓(xùn)練集。樣本數(shù)量6;屬性4:交點、前一天漲跌(0跌1漲)、振幅(%)、高低開(0低1高)
    D = [[0, 1, 1.33, 1], [7, 1, 0.55, 0], [0, 1, 1.29, 0], [0, 1, 0.75, 0], [0, 0, 0.43, 1], [0, 1, 0.52, 1],  [0, 0, 1.13, 0]]
    # 訓(xùn)練樣本的類別標(biāo)簽集
    L = ['漲', '漲', '跌', '跌', '漲', '漲', '跌']
    # 測試目標(biāo)(2018-12-21)
    Z = [3, 0, 1.00, 0]
    # 預(yù)測類別標(biāo)簽
    Lc = ['跌', '漲']
    if (Z[0] > 0):
        Z[0] = 1
    if(Z[2] > 0.5):
        Z[2] = 1
    D, L = dealData(D, L)
    D0, D1 = splitData(D, L)
    Pc = calculateProbobility(D0, D1, L, Z)
    selectClass(Pc, Lc)

if __name__ == '__main__':
    main()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容