1. 程式人生 > >樸素貝葉斯文本分類(詳解)

樸素貝葉斯文本分類(詳解)

詞向量 列表 出現 下標 put The 標註 問題 else

from numpy import zeros,array
from math import log

def loadDataSet():
#詞條切分後的文檔集合,列表每一行代表一個email 
    postingList=[[‘your‘,‘mobile‘,‘number‘,‘is‘,‘award‘,‘bonus‘,‘prize‘],
                 [‘new‘,‘car‘,‘and‘,‘house‘,‘for‘,‘my‘,‘parents‘],
                 [‘my‘,‘dalmation‘,‘is‘,‘so‘,‘cute‘,‘I‘,‘love‘,‘him‘],  
                 [‘today‘,‘voda‘,‘number‘,‘prize‘, ‘receive‘,‘award‘],
                 [‘get‘,‘new‘,‘job‘,‘in‘,‘company‘,‘how‘,‘to‘,‘get‘,‘that‘],
                 [‘free‘,‘prize‘,‘buy‘,‘winner‘,‘receive‘,‘cash‘]]
    #由人工標註的每篇文檔的類標簽
    classVec=[1,0,0,1,0,1] #1-spam, 0-ham
    return postingList,classVec
postingList,classVec = loadDataSet()


#統計所有文檔中出現的詞條列表    
def createVocabList(dataSet): 
    vocabSet=set([])
    #遍歷文檔集合中的每一篇文檔
    for document in dataSet: 
        vocabSet=vocabSet|set(document) 
    return list(vocabSet)
vocabSet = createVocabList(postingList)


#根據詞條列表中的詞條是否在文檔中出現(出現1,未出現0),將文檔轉化為詞條向量    
def setOfWords2Vec(vocabSet,inputSet):
    #新建一個長度為vocabSet的列表,並且各維度元素初始化為0
    returnVec=[0]*len(vocabSet)
    #遍歷文檔中的每一個詞條
    for word in inputSet:
        #如果詞條在詞條列表中出現
        if word in vocabSet:
            #通過列表獲取當前word的索引(下標)
            #將詞條向量中的對應下標的項由0改為1
            returnVec[vocabSet.index(word)]=1
        else: print(‘the word: %s is not in my vocabulary! ‘%‘word‘)
    #返回inputet轉化後的詞條向量
    return returnVec
 
trainMatrix = [setOfWords2Vec(vocabSet,inputSet) for inputSet in postingList] 


#訓練算法,從詞向量計算概率p(w0|ci)...及p(ci)
#@trainMatrix:由每篇文檔的詞條向量組成的文檔矩陣
#@trainCategory:每篇文檔的類標簽組成的向量
def trainNB0(trainMatrix,trainCategory):
    #獲取文檔矩陣中文檔的數目
    numTrainDocs=len(trainMatrix)
    #獲取詞條向量的長度
    numWords=len(trainMatrix[0])
    #所有文檔中屬於類1所占的比例p(c=1)
    pAbusive=sum(trainCategory)/float(numTrainDocs)
    #創建一個長度為詞條向量等長的列表
    p0Num=zeros(numWords) #ham
    p1Num=zeros(numWords) #spam
    p0Denom=0.0
    p1Denom=0.0
    #遍歷每一篇文檔的詞條向量
    for i in range(numTrainDocs):
        #如果該詞條向量對應的標簽為1
        if trainCategory[i]==1:
            #統計所有類別為1的詞條向量中各個詞條出現的次數
            p1Num+=trainMatrix[i]
            #統計類別為1的詞條向量中出現的所有詞條的總數
            #即統計類1所有文檔中出現單詞的數目
            p1Denom+=sum(trainMatrix[i])
        else:
            #統計所有類別為0的詞條向量中各個詞條出現的次數
            p0Num+=trainMatrix[i]
            #統計類別為0的詞條向量中出現的所有詞條的總數
            #即統計類0所有文檔中出現單詞的數目
            p0Denom+=sum(trainMatrix[i])
    print(p1Num, p1Denom, p0Num,p0Denom )
    #利用NumPy數組計算p(wi|c1)
    p1Vect=p1Num/p1Denom  #為避免下溢出問題,需要改為log()
    #利用NumPy數組計算p(wi|c0)
    p0Vect=p0Num/p0Denom  #為避免下溢出問題,需要改為log()
    return p0Vect,p1Vect,pAbusive
 
p0Vect,p1Vect,pAbusive=  trainNB0(trainMatrix,classVec)


#樸素貝葉斯分類函數
#@vec2Classify:待測試分類的詞條向量
#@p0Vec:類別0所有文檔中各個詞條出現的頻數p(wi|c0)
#@p0Vec:類別1所有文檔中各個詞條出現的頻數p(wi|c1)
#@pClass1:類別為1的文檔占文檔總數比例
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    #根據樸素貝葉斯分類函數分別計算待分類文檔屬於類1和類0的概率
    p1=sum(vec2Classify*p1Vec)+log(pClass1)
    p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1)
    if p1>p0:
        return ‘spam‘
    else:
        return ‘not spam‘



testEntry=[‘love‘,‘my‘,‘job‘]
thisDoc=array(setOfWords2Vec(vocabSet,testEntry))
print(testEntry,‘classified as:‘,classifyNB(thisDoc,p0Vect,p1Vect,pAbusive))

 



 

 技術分享圖片 

樸素貝葉斯文本分類(詳解)