1. 程式人生 > >Python實現樸素貝葉斯(NB)

Python實現樸素貝葉斯(NB)

      這篇文章主要關於樸素貝葉斯演算法的用python具體實現,網上關於NB演算法的文章很多,大多圍繞著《機器學習實戰》這本書來著。在此,對於NB演算法的原理我大概介紹一下。

貝葉斯定理:

    已知某條件概率,如何得到兩個條件交換後的概率。即:已知 求


假設 A,B獨立 P(A,B)=P(A)*P(B)

樸素貝葉斯原理:

對於給定的待分類像項,求解在此基礎上每個類別出現的概率,最大的即作為最終分類的類別。

步驟:

1、 設為待分類項,ai為每個待分類屬性

2、 類別集合為

3、 計算的概率

4、 取第3步驟概率值最大的為待分類項的類別。

具體實現步驟:

把上述第3步驟轉化成求每個特徵的條件概率。

因為最終考慮的是在每個類別中概率值的大小,所以去掉除數x,不影響最終分類結果。

1、 即轉化成

2、 假設各個特徵相互獨立,則


========================================================

程式碼:

1、首先實現計算每個類別的概率

2、計算每個特徵在不同類下的條件概率(每個特徵出現的次數/類別下特徵的總個數)

3、計算 

4.判斷大小                      

具體程式碼如下:

# -*- coding: utf-8 -*-
import numpy as np
import glob    
def load_data():
    text=[]
    y=[1,0,1,1,1,0,1]
    with open('e:/a/ceshi.txt','r',encoding='utf-8') as infile:
        for line in infile:
            line=line.strip()
            text.append(line)   
    return text,y

def cteat_dit(alltext):
    term_dict={}
    for doc in alltext:
        for term in doc.split():
            term_dict[term]=1
    term_dict=dict(zip(term_dict.keys(),range(len(term_dict)) ))
    return term_dict
def  get_vec(term_dict,input_data):
    #將詞彙轉化成向量,簡單的詞袋模型
    vec=[0]*len(term_dict)
    for i in input_data.split():
        if i in term_dict:
            vec[term_dict[i]]=1
    return vec

def train_NB(text,y,term_dict):
    #===================================================
    #1.  計算y的概率
    
    class_set=sorted(list(set(y)))
    class_dict=dict(zip(class_set,range(len(class_set))))
   # print(class_dict){0: 0, 1: 1}
    class_prob=[0]*len(class_dict)
    class_count=[0]*len(class_dict)
    for i in y:
        class_count[class_dict[i]]+=1
    class_prob=[i/len(y) for i in class_count]
    #==================================================
    # 2. 計算每個詞在不同類別下出現的次數 
    term_calss_df=np.zeros((len(term_dict),len(class_dict)))  
    
    for i in  range(len(y)):
        class_index=class_dict[y[i]]
        for term in text[i].split():#針對每一個文件
            term_index=term_dict[term]
            term_calss_df[term_index][class_index]+=1
    tf=term_calss_df
    #避免某一個概率值為0,所有詞出現數+1
    tfg=tf+1
    sumh=np.sum(tf,axis=0)
    prob=tfg/sumh
    
    
    return prob,class_prob
def classifyNB(test,prob,class_prob,term_dict):
    '''
    分類函式
    '''
    datavec=[]
    for line in test:
        vec=get_vec(term_dict,line)
        datavec.append(vec)  
    #===================================================
    prob=np.log(prob)#避免下溢,不影響最終分類結果
    class_result=[]
    for i in datavec:
        
        i=np.array(i)
        i=i.reshape(-1,1)
        C_prob=prob*i
        print('############')
        all_prob=np.sum(C_prob,0)+np.log(class_prob)
        class_result.append(all_prob)
    return class_result
        
        
#=========================
#載入測試集

def load():
    text=[]
    with open('e:/a/1.txt','r',encoding='utf-8') as infile:
        for line in infile:
            line=line.strip()
            text.append(line)
    return text

def testNB():
    
    text, y=load_data()
    term_dict=cteat_dit(text)
    
    prob,class_prob =train_NB(text,y,term_dict)
    test=load()
    class_result=classifyNB(test,prob,class_prob,term_dict)
    for all_prob in class_result:
        if all_prob[1] >all_prob[0]:
            print('1') #分類結果
        else: 
            print('0') 
            
if __name__=='__main__':
    
    testNB()