朴素貝葉斯文本分類(python代碼實現)


朴素貝葉斯(naive bayes)法是基於貝葉斯定理與特征條件獨立假設的分類方法。

  • 優點:在數據較少的情況下仍然有效,可以處理多分類問題。
  • 缺點:對入輸入數據的准備方式較為敏感。
  • 使用數據類型:標稱型數據。

下面從一個簡單問題出發,介紹怎么使用朴素貝葉斯解決分類問題。 
一天,老師問了個問題,只根據頭發和聲音怎么判斷一位同學的性別。 
為了解決這個問題,同學們馬上簡單的統計了7位同學的相關特征,數據如下:

頭發 聲音 性別

這個問題之前用決策樹做過了,這里我們換一種思路。 
要是知道男生和女生頭發長短的概率以及聲音粗細的概率,我們就可以計算出各種情況的概率,然后比較概率大小,來判斷性別。 
假設抽樣樣本足夠大,我們可以近似認為可以代表所有數據,假設上位7位同學能代表所有數據,這里方便計算~ 
由這7位同學,我們馬上得出下面表格概率分布。

性別 頭發長 聲音粗
1/3 1
3/5 3/5

假設頭發和聲音都是獨立特征,於是 
男生頭發長聲音粗的概率=3/8*1/3*1=1/8 
女生頭發長聲音粗的概率=5/8*3/5*3/5=9/40 
因為1/8<9/40所以如果一個人,頭發長,聲音粗,那么這個人更可能是女生,於是出現這些特征就是女生。其他特征依次類推。 
這就是朴素貝葉斯分類方法。是的,就是這么簡單。 
下面來解釋原理,先看貝葉斯公式: 
這里寫圖片描述

公式中,事件Bi的概率為P(Bi),事件Bi已發生條件下事件A的概率為P(A│Bi),事件A發生條件下事件Bi的概率為P(Bi│A)。 
帶入我們的例子中,判斷頭發長的人性別: 
P(男|頭發長)=P(頭發長|男)*P(男)/P(頭發長) 
P(女|頭發長)=P(頭發長|女)*P(女)/P(頭發長) 
判斷頭發長、聲音粗的人性別: 
P(男|頭發長聲音粗)=P(頭發長|男)P(聲音粗|男)*P(男)/P(頭發長聲音粗) 
P(女|頭發長聲音粗)=P(頭發長|女)P(聲音粗|女)*P(女)/P(頭發長聲音粗) 
可以看到,比較最后比較概率,只用比較分子即可。也就是前面計算頭發長聲音粗的人是男生女生的概率。

下面應用於文本分類,文本分類不想上面例子有具體的特征,需先建立文本特征。以下為文本分類的一個簡單例子。

 1 # _*_ coding:utf-8 _*_
 2 from numpy import *
 3 import re
 4 import random
 5 
 6 def loadDataSet(): #創建樣例數據
 7     postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
 8                    ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
 9                    ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
10                    ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
11                    ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
12                    ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
13     classVec = [0, 1, 0, 1, 0, 1]  #1代表臟話
14     return postingList, classVec
15 
16 def createVocabList(dataSet):  #創建詞庫 這里就是直接把所有詞去重后,當作詞庫
17     vocabSet = set([])
18     for document in dataSet:
19         vocabSet = vocabSet | set(document)
20     return list(vocabSet)
21 
22 def setOfWords2Vec(vocabList, inputSet):  #文本詞向量。詞庫中每個詞當作一個特征,文本中就該詞,該詞特征就是1,沒有就是0
23     returnVec = [0] * len(vocabList)
24     for word in inputSet:
25         if word in vocabList:
26             returnVec[vocabList.index(word)] = 1
27         else:
28             print("the word: %s is not in my Vocabulary!" % word)
29     return returnVec
30 
31 
32 def trainNB0(trainMatrix, trainCategory):
33     numTrainDocs = len(trainMatrix)
34     numWords = len(trainMatrix[0])
35     pAbusive = sum(trainCategory) / float(numTrainDocs)
36     p0Num = ones(numWords) #防止某個類別計算出的概率為0,導致最后相乘都為0,所以初始詞都賦值1,分母賦值為2.
37     p1Num = ones(numWords)
38     p0Denom = 2
39     p1Denom = 2
40     for i in range(numTrainDocs):
41         if trainCategory[i] == 1:
42             p1Num += trainMatrix[i]
43             p1Denom += sum(trainMatrix[i])
44         else:
45             p0Num += trainMatrix[i]
46             p0Denom += sum(trainMatrix[i])
47     p1Vect = log(p1Num / p1Denom)  #這里使用了Log函數,方便計算,因為最后是比較大小,所有對結果沒有影響。
48     p0Vect = log(p0Num / p0Denom)
49     return p0Vect, p1Vect, pAbusive
50 
51 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #比較概率大小進行判斷,
52     p1 = sum(vec2Classify*p1Vec)+log(pClass1)
53     p0 = sum(vec2Classify*p0Vec)+log(1-pClass1)
54     if p1>p0:
55         return 1
56     else:
57         return 0
58 
59 def testingNB():
60     listOPosts,listClasses = loadDataSet()
61     myVocabList = createVocabList(listOPosts)
62     trainMat=[]
63     for postinDoc in listOPosts:
64         trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
65     p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
66     testEntry = ['love', 'my', 'dalmation'] # 測試數據
67     thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
68     print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
69     testEntry = ['stupid', 'garbage'] # 測試數據
70     thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
71     print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
72 
73 if __name__=='__main__':
74     testingNB()
1 #輸出結果
2 ['love', 'my', 'dalmation'] classified as:  0
3 ['stupid', 'garbage'] classified as:  1

參考: 
- Machine Learning in Action 
- 統計學習方法

轉載:http://blog.csdn.net/csqazwsxedc/article/details/69488938


免責聲明!

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



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