朴素貝葉斯分類算法
1、朴素貝葉斯分類算法原理
1.1、概述
貝葉斯分類算法是一大類分類算法的總稱
貝葉斯分類算法以樣本可能屬於某類的概率來作為分類依據
朴素貝葉斯分類算法是貝葉斯分類算法中最簡單的一種
注:朴素的意思是條件概率獨立性
P(A|x1x2x3x4)=p(A|x1)*p(A|x2)p(A|x3)p(A|x4)則為條件概率獨立
P(xy|z)=p(xyz)/p(z)=p(xz)/p(z)*p(yz)/p(z)
1.2、算法思想
朴素貝葉斯的思想是這樣的:
如果一個事物在一些屬性條件發生的情況下,事物屬於A的概率>屬於B的概率,則判定事物屬於A
通俗來說比如,你在街上看到一個黑人,我讓你猜這哥們哪里來的,你十有八九猜非洲。為什么呢?
在你的腦海中,有這么一個判斷流程:
1、這個人的膚色是黑色 <特征>
2、黑色人種是非洲人的概率最高 <條件概率:黑色條件下是非洲人的概率>
3、沒有其他輔助信息的情況下,最好的判斷就是非洲人
這就是朴素貝葉斯的思想基礎。
再擴展一下,假如在街上看到一個黑人講英語,那我們是怎么去判斷他來自於哪里?
提取特征:
膚色: 黑
語言: 英語
黑色人種來自非洲的概率: 80%
黑色人種來自於美國的概率:20%
講英語的人來自於非洲的概率:10%
講英語的人來自於美國的概率:90%
在我們的自然思維方式中,就會這樣判斷:
這個人來自非洲的概率:80% * 10% = 0.08
這個人來自美國的概率:20% * 90% =0.18
我們的判斷結果就是:此人來自美國!
其蘊含的數學原理如下:
p(A|xy)=p(Axy)/p(xy)=p(Axy)/p(x)p(y)=p(A)/p(x)*p(A)/p(y)* p(xy)/p(xy)=p(A|x)p(A|y)
P(類別 | 特征)=P(特征 | 類別)*P(類別) / P(特征)
1.3、算法步驟
1、分解各類先驗樣本數據中的特征
2、計算各類數據中,各特征的條件概率
(比如:特征1出現的情況下,屬於A類的概率p(A|特征1),屬於B類的概率p(B|特征1),屬於C類的概率p(C|特征1)......)
3、分解待分類數據中的特征(特征1、特征2、特征3、特征4......)
4、計算各特征的各條件概率的乘積,如下所示:
判斷為A類的概率:p(A|特征1)*p(A|特征2)*p(A|特征3)*p(A|特征4).....
判斷為B類的概率:p(B|特征1)*p(B|特征2)*p(B|特征3)*p(B|特征4).....
判斷為C類的概率:p(C|特征1)*p(C|特征2)*p(C|特征3)*p(C|特征4).....
......
5、結果中的最大值就是該樣本所屬的類別
1.4、算法應用舉例
大眾點評、淘寶等電商上都會有大量的用戶評論,比如:
1、衣服質量太差了!!!!顏色根本不純!!! 2、我有一有種上當受騙的感覺!!!! 3、質量太差,衣服拿到手感覺像舊貨!!! 4、上身漂亮,合身,很帥,給賣家點贊 5、穿上衣服帥呆了,給點一萬個贊 6、我在他家買了三件衣服!!!!質量都很差! |
0 0 0 1 1 0 |
其中1/2/3/6是差評,4/5是好評
現在需要使用朴素貝葉斯分類算法來自動分類其他的評論,比如:
a、這么差的衣服以后再也不買了 b、帥,有逼格 …… |
1.5、算法應用流程
1、分解出先驗數據中的各特征
(即分詞,比如“衣服”“質量太差”“差”“不純”“帥”“漂亮”,“贊”……)
2、計算各類別(好評、差評)中,各特征的條件概率
(比如 p(“衣服”|差評)、p(“衣服”|好評)、p(“差”|好評) 、p(“差”|差評)……)
3、分解出待分類樣本的各特征
(比如分解a: “差” “衣服” ……)
4、計算類別概率
P(好評) = p(好評|“差”) *p(好評|“衣服”)*……
P(差評) = p(差評|“差”) *p(差評|“衣服”)*……
5、顯然P(差評)的結果值更大,因此a被判別為“差評”
1.6、朴素貝葉斯分類算法案例
大體計算方法:
P(好評 | 單詞1,單詞2,單詞3) = P(單詞1,單詞2,單詞3 | 好評) * P(好評) / P(單詞1,單詞2,單詞3)
因為分母都相同,所以只用比較分子即可--->P(單詞1,單詞2,單詞3 | 好評) P(好評)
每個單詞之間都是相互獨立的---->P(單詞1 | 好評)P(單詞2 | 好評)P(單詞3 | 好評)*P(好評)
P(單詞1 | 好評) = 單詞1在樣本好評中出現的總次數/樣本好評句子中總的單詞數
P(好評) = 樣本好評的條數/樣本的總條數
同理:
P(差評 | 單詞1,單詞2,單詞3) = P(單詞1,單詞2,單詞3 | 差評) * P(差評) / P(單詞1,單詞2,單詞3)
因為分母都相同,所以只用比較分子即可--->P(單詞1,單詞2,單詞3 | 差評) P(差評)
每個單詞之間都是相互獨立的---->P(單詞1 | 差評)P(單詞2 | 差評)P(單詞3 | 差評)*P(差評)
1 #!/usr/bin/python 2 # coding=utf-8 3 from numpy import * 4 5 # 過濾網站的惡意留言 侮辱性:1 非侮辱性:0 6 # 創建一個實驗樣本 7 def loadDataSet(): 8 postingList = [['my','dog','has','flea','problems','help','please'], 9 ['maybe','not','take','him','to','dog','park','stupid'], 10 ['my','dalmation','is','so','cute','I','love','him'], 11 ['stop','posting','stupid','worthless','garbage'], 12 ['mr','licks','ate','my','steak','how','to','stop','him'], 13 ['quit','buying','worthless','dog','food','stupid']] 14 classVec = [0,1,0,1,0,1] 15 return postingList, classVec 16 17 # 創建一個包含在所有文檔中出現的不重復詞的列表 18 def createVocabList(dataSet): 19 vocabSet = set([]) # 創建一個空集 20 for document in dataSet: 21 vocabSet = vocabSet | set(document) # 創建兩個集合的並集 22 return list(vocabSet) 23 24 # 將文檔詞條轉換成詞向量 25 def setOfWords2Vec(vocabList, inputSet): 26 returnVec = [0]*len(vocabList) # 創建一個其中所含元素都為0的向量 27 for word in inputSet: 28 if word in vocabList: 29 # returnVec[vocabList.index(word)] = 1 # index函數在字符串里找到字符第一次出現的位置 詞集模型 30 returnVec[vocabList.index(word)] += 1 # 文檔的詞袋模型 每個單詞可以出現多次 31 else: print "the word: %s is not in my Vocabulary!" % word 32 return returnVec 33 34 # 朴素貝葉斯分類器訓練函數 從詞向量計算概率 35 def trainNB0(trainMatrix, trainCategory): 36 numTrainDocs = len(trainMatrix) 37 numWords = len(trainMatrix[0]) 38 pAbusive = sum(trainCategory)/float(numTrainDocs) 39 # p0Num = zeros(numWords); p1Num = zeros(numWords) 40 # p0Denom = 0.0; p1Denom = 0.0 41 p0Num = ones(numWords); # 避免一個概率值為0,最后的乘積也為0 42 p1Num = ones(numWords); # 用來統計兩類數據中,各詞的詞頻 43 p0Denom = 2.0; # 用於統計0類中的總數 44 p1Denom = 2.0 # 用於統計1類中的總數 45 for i in range(numTrainDocs): 46 if trainCategory[i] == 1: 47 p1Num += trainMatrix[i] 48 p1Denom += sum(trainMatrix[i]) 49 else: 50 p0Num += trainMatrix[i] 51 p0Denom += sum(trainMatrix[i]) 52 # p1Vect = p1Num / p1Denom 53 # p0Vect = p0Num / p0Denom 54 p1Vect = log(p1Num / p1Denom) # 在類1中,每個次的發生概率 55 p0Vect = log(p0Num / p0Denom) # 避免下溢出或者浮點數舍入導致的錯誤 下溢出是由太多很小的數相乘得到的 56 return p0Vect, p1Vect, pAbusive 57 58 # 朴素貝葉斯分類器 59 def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): 60 p1 = sum(vec2Classify*p1Vec) + log(pClass1) 61 p0 = sum(vec2Classify*p0Vec) + log(1.0-pClass1) 62 if p1 > p0: 63 return 1 64 else: 65 return 0 66 67 def testingNB(): 68 listOPosts, listClasses = loadDataSet() 69 myVocabList = createVocabList(listOPosts) 70 trainMat = [] 71 for postinDoc in listOPosts: 72 trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) 73 p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses)) 74 testEntry = ['love','my','dalmation'] 75 thisDoc = array(setOfWords2Vec(myVocabList, testEntry)) 76 print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb) 77 testEntry = ['stupid','garbage'] 78 thisDoc = array(setOfWords2Vec(myVocabList, testEntry)) 79 print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb) 80 81 # 調用測試方法---------------------------------------------------------------------- 82 testingNB()
運行結果: