樸素貝葉斯分類器

# -*- coding: UTF-8 -*- 
from numpy import *

#獲取輸入詞條和分類標簽
def loadataset():
    postinglist=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],\
    ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],\
    ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],\
    ['stop', 'posting', 'stupid', 'worthless', 'garbage'],\
    ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],\
    ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classvec=[0,1,0,1,0,1]
    return postinglist,classvec

#獲取詞條的所有單詞集合(詞匯表),以列表形式返回
def createvocablist(dataset):
    vocabset=set()
    for i in dataset:
        vocabset=vocabset|set(i)
    return list(vocabset)

#輸入待分類詞條,測試詞條在詞匯表中是否出現,記為1
#此處為詞集模型,只判斷特征值出現與否,對出現頻率未加考慮
def setofwords2vec(vocabset,input):
    inputvec=[0]*len(vocabset)
    for word in input:
        if word in vocabset:
            inputvec[vocabset.index(word)]=1
        else:
            print 'the word %s is not in the vocabset' %word
    return inputvec

#詞袋模型。對多次出現的特征值累加計數
def bagofwords2vec(vocabset,input):
    inputvec=[0]*len(vocabset)
    for word in input:
        if word in vocabset:
            inputvec[vocabset.index(word)]+=1
        else:
            print 'the word %s is not in the vocabset' %word
    return inputvec

#返回類先驗概率和似然函數 <ndarray形式>
def trainnb(trainmatrix,traincategory):
    numtraindoc=len(trainmatrix)
    numwords=len(trainmatrix[0])
    positive=sum(traincategory)/float(numtraindoc)    #計算垃圾詞條的概率,先驗概率
    p0num=ones(numwords);p1num=ones(numwords)
    p0sum=0.0;  p1sum=0.0
    for i in range(numtraindoc):
        if traincategory[i]==1:
            p1num+=trainmatrix[i]   #2個list無法相加,故引入numpy進行對應位置的運算
            p1sum+=sum(trainmatrix[i])
        else:
            p0num+=trainmatrix[i]
            p0sum+=sum(trainmatrix[i])
    p0vect=log(p0num/p0sum)
    p1vect=log(p1num/p1sum)
    return p0vect,p1vect,positive

#貝葉斯公式判斷不同分類的概率大小
def classifynb(vec2classify,p0vect,p1vect,positive):
    p1=sum(vec2classify*p1vect)+log(positive)
    p0=sum(vec2classify*p0vect)+log(1-positive)
    if p1>p0:
        return 1
    else:
        return 0

#分類未知詞條
def testingnb():
    listvec,classvec=loadataset()
    myvocablist=createvocablist(listvec)
    trainmat=[]
    for doc in listvec:
        trainmat.append(bagofwords2vec(myvocablist,doc))  #獲取每個詞條在詞匯表出現與否的列向量
    p0vect,p1vect,positive=trainnb(trainmat,classvec)
    testentry=['love','my','dalmation']
    thisdoc=array(bagofwords2vec(myvocablist,testentry))
    print testentry,'classified as:',classifynb(thisdoc,p0vect,p1vect,positive)
    testentry=['stupid','garbage']
    thisdoc=array(bagofwords2vec(myvocablist,testentry))
    print testentry,'classified as:',classifynb(thisdoc,p0vect,p1vect,positive)

#解析文本文件
def textparse(bigstring):
    import re
    listoftokens=re.split(r'\W*',bigstring)
    return [i.lower() for i in listoftokens if len(i)>2]

#測試算法,使用樸素貝葉斯進行交叉驗證
def spamtext():
    dataset=[]
    category=[]    #類別標簽
    vocabset=[]    #詞匯表
    for i in range(1,26):
        a=open('/Users/enniu/Desktop/jqxx/machinelearninginaction/Ch04/email/ham/%d.txt' %i).read()
        dataset.append(textparse(a))
        category.append(0)
    for i in range(1,26):
        b=open('/Users/enniu/Desktop/jqxx/machinelearninginaction/Ch04/email/spam/%d.txt' %i).read()
        dataset.append(textparse(b))
        category.append(1)
    vocabset=createvocablist(dataset)  #獲取輸入詞條的所有詞匯表

    #隨機選擇10個樣本作為測試集
    testset=[]         #測試樣本序號
    trainset=range(50) #訓練樣本序號。此步通過索引來操作,不需要更改詞集列表
    for i in range(10):
        randindex=int(random.uniform(0,len(trainset)))
        testset.append(trainset[randindex])
        del trainset[randindex]

    #計算剩余40個樣本的似然概率.[P(x1|spam),P(x2|spam),P(x3|spam),...]
    trainmat=[]
    trainclass=[]
    for i in trainset:
        trainmat.append(setofwords2vec(vocabset,dataset[i]))
        trainclass.append(category[i])
    p0vect,p1vect,positive=trainnb(trainmat,trainclass)
    #return p0vect,p1vect,positive

    #計算正確與錯誤的概率
    errorcount=0
    for i in testset:
        wordvect=setofwords2vec(vocabset,dataset[i])
        precategory=classifynb(wordvect,p0vect,p1vect,positive)
        if precategory!=category[i]:
            errorcount+=1
    print 'the error rate is: ',float(errorcount)/len(testset)

if __name__=='__main__':
    i=0
    while i<=10:
        spamtext()
        i=i+1
    

# -*- coding: UTF-8 -*- 
from numpy import *

#獲取輸入詞條和分類標簽
def loadataset():
    postinglist=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],\
    ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],\
    ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],\
    ['stop', 'posting', 'stupid', 'worthless', 'garbage'],\
    ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],\
    ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classvec=[0,1,0,1,0,1]
    return postinglist,classvec

#獲取詞條的所有單詞集合(詞匯表),以列表形式返回
def createvocablist(dataset):
    vocabset=set()
    for i in dataset:
        vocabset=vocabset|set(i)
    return list(vocabset)

#輸入待分類詞條,測試詞條在詞匯表中是否出現,記為1
#此處為詞集模型,只判斷特征值出現與否,對出現頻率未加考慮
def setofwords2vec(vocabset,input):
    inputvec=[0]*len(vocabset)
    for word in input:
        if word in vocabset:
            inputvec[vocabset.index(word)]=1
        else:
            print 'the word %s is not in the vocabset' %word
    return inputvec

#詞袋模型。對多次出現的特征值累計計數
def bagofwords2vec(vocabset,input):
    inputvec=[0]*len(vocabset)
    for word in input:
        if word in vocabset:
            inputvec[vocabset.index(word)]+=1
        else:
            print 'the word %s is not in the vocabset' %word
    return inputvec

#返回類先驗概率和似然函數 <ndarray形式>
def trainnb(trainmatrix,traincategory):
    numtraindoc=len(trainmatrix)
    numwords=len(trainmatrix[0])
    positive=sum(traincategory)/float(numtraindoc)    #計算垃圾詞條的概率,先驗概率
    p0num=ones(numwords);p1num=ones(numwords)
    p0sum=0.0;  p1sum=0.0
    for i in range(numtraindoc):
        if traincategory[i]==1:
            p1num+=trainmatrix[i]   #2個list無法相加,故引入numpy進行對應位置的運算
            p1sum+=sum(trainmatrix[i])
        else:
            p0num+=trainmatrix[i]
            p0sum+=sum(trainmatrix[i])
    p0vect=log(p0num/p0sum)
    p1vect=log(p1num/p1sum)
    return p0vect,p1vect,positive

#貝葉斯公式判斷不同分類的概率大小
def classifynb(vec2classify,p0vect,p1vect,positive):
    p1=sum(vec2classify*p1vect)+log(positive)
    p0=sum(vec2classify*p0vect)+log(1-positive)
    if p1>p0:
        return 1
    else:
        return 0

#分類未知詞條
def testingnb():
    listvec,classvec=loadataset()
    myvocablist=createvocablist(listvec)
    trainmat=[]
    for doc in listvec:
        trainmat.append(bagofwords2vec(myvocablist,doc))  #獲取每個詞條在詞匯表出現與否的列向量
    p0vect,p1vect,positive=trainnb(trainmat,classvec)
    testentry=['love','my','dalmation']
    thisdoc=array(bagofwords2vec(myvocablist,testentry))
    print testentry,'classified as:',classifynb(thisdoc,p0vect,p1vect,positive)
    testentry=['stupid','garbage']
    thisdoc=array(bagofwords2vec(myvocablist,testentry))
    print testentry,'classified as:',classifynb(thisdoc,p0vect,p1vect,positive)

if __name__=='__main__':
    testingnb()
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容