摘要:貝葉斯是基于概率論的分類方法,通過(guò)概率的方式來(lái)描述對(duì)象劃分到某個(gè)分類的可能性。對(duì)象有多個(gè)屬性假設(shè)各個(gè)屬性之間是相互獨(dú)立的,求解在出現(xiàn)的條件下各個(gè)類別出現(xiàn)的概率,選擇最大的作為的分類,通過(guò)這種方法構(gòu)造的分類算法稱為樸素貝葉斯。
貝葉斯是基于概率論的分類方法,通過(guò)概率的方式來(lái)描述對(duì)象劃分到某個(gè)分類的可能性。對(duì)象X有多個(gè)屬性$$X={a_{1}, a_{2}, a_{3}, ... , a_{n}}$$假設(shè)各個(gè)屬性之間是相互獨(dú)立的,求解在X出現(xiàn)的條件下各個(gè)類別 $$C_{i}$$出現(xiàn)的概率,選擇最大的 $$P(C_{i}|X) $$作為X的分類,通過(guò)這種方法構(gòu)造的分類算法稱為樸素貝葉斯。1.樣本空間與概率論
假設(shè)為Ω實(shí)驗(yàn)E的樣本空間,B為E的一組事件,滿足
$$B_{i}B_{j}=B_{i}cap B_{j}=phi, i,j=1,2,3,...,n $$
$$B_{1}cup B_{2} cup ... cup B_{n}=Omega$$
則稱B為樣本空間Ω的一個(gè)劃分。假設(shè)A為E的一個(gè)事件,由全概率公式得:
$$P(A)=P(A|B_{1})P(B_{1})+P(A|B_{2})P(B_{2})+...+P(A|B_{n})P(B_{n})=sum_{i=1}^{n}P(A|B_{i})P(B_{i})$$
證明:
$$A=AOmega=Acap(B_{1}cup B_{2} cup ... cup B_{n})=AB_{1}cup AB_{2}cup...cup AB_{n}$$
$$P(ab)=P(a)P(b|a)=P(b)P(a|b),P(a)>0,P(b)>0$$
$$=>P(A)=P(B_{1})P(A|B_{1})+P(B_{2})P(A|B_{2})+...+P(B_{n})P(A|B_{n})$$
P(A|B)表示在事件B發(fā)生的前提下,事件A發(fā)生的概率,公式表示為:
$$P(A|B)=frac{P(AB)}{P(B)}$$
P(B|A)是根據(jù)A參數(shù)值判斷對(duì)象屬于類別B的概率,稱為后驗(yàn)概率。P(B)是直接判斷某個(gè)樣本屬于類別B的概率,稱為先驗(yàn)概率。P(A|B)是在類別B中觀測(cè)到A的概率,P(A)是在數(shù)據(jù)集中觀測(cè)到A的概率,則有:
$$P(B|A)=frac{P(A|B)P(B)}{P(A)}$$
公式的證明很簡(jiǎn)單,參考條件概率公式。于是有:
$$=>P(B_{i}|A) = frac{P(A|B_{i})P(B_{i})}{P(A)} = frac{P(A|B_{i})P(B_{i})}{sum_{i=1}^{n}P(B_{i})P(A|B_{i})}$$
對(duì)于樸素貝葉斯,對(duì)象的各個(gè)特征值相互獨(dú)立,則有:
$$=>P(A|B_{i}) = P(a_{1}|B_{i})P(a_{2}|B_{i})...P(a_{n}|B_{i})=prod_{k=1}^{n}P(a_{k}|B_{i})$$
$$=>P(B_{i}|A) = frac{prod_{k=1}^{n}P(a_{k}|B_{i})P(B_{i})}{sum_{i=1}^{n}P(B_{i})prod_{k=1}^{n}P(a_{k}|B_{i})}$$
設(shè)X={a1, a2, a3, ..., an}為一個(gè)待分類項(xiàng),每個(gè)a為X的一個(gè)特征屬性,特征屬性彼此獨(dú)立
設(shè)C={c1, c2, c3, ..., cn}為樣本類別集合
計(jì)算P(c1|X)P(c2|X)P(c3|X)...P(cn|X)
計(jì)算P(ck|X) = max{P(c1|X), P(c2|X), P(c3|X), ..., P(cn|X)},則X屬于類別ck
2.2 案例1:電腦購(gòu)買數(shù)據(jù)集:
age | income | student | credit_rating | buy_computer ----------------------------------------------------- <=30 high no fail no <=30 high no good no 31-40 high no fail yes >40 medium no fail yes >40 low yes fail yes >40 low yes good no 31-40 low yes good yes <=30 medium no fail no <=30 low yes fail yes >40 medium yes fail yes <=30 medium yes good yes 31-40 medium no good yes 31-40 high yes fail yes >40 medium no good no 待分類樣本: <=30 medium yes fail ?
樣本特征屬性:a1=age、a2=income、a3=student、a4=credit_rating
類別屬性:buy_computer={"c1": "yes", "c2": "no"}
計(jì)算每個(gè)類的先驗(yàn)概率:
$$P(c_{1})=9/14,P(c_{2})=5/14$$
計(jì)算每個(gè)屬性對(duì)于每個(gè)類別的條件概率:
P(age = "<=30" | buy_computer = "yes") = 2/9
P(income = "medium" | buy_computer = "yes") = 4/9
P(student= "yes" | buy_computer = "yes") = 6/9
P(credit_rating = "fail" | buy_computer = "yes") = 6/9
P(age = "<=30" | buy_computer = "no") = 3/5
P(income = "medium" | buy_computer = "no") = 2/5
P(student= "yes" | buy_computer = "no") = 1/5
P(credit_rating = "fail" | buy_computer = "no") = 2/5
計(jì)算條件概率P(X|Ci):
P(X|buy_computer="yes") = 2/9 × 4/9 × 6/9 × 6/9 = 0.044
P(X|buy_computer="no") = 3/5 × 2/5 × 1/5 × 2/5 = 0.019
計(jì)算每個(gè)類的P(X|Ci)P(Ci):
P(X|buy_computer="yes")P(buy_computer="yes") = 0.044 × 9/14 = 0.028
P(X|buy_computer="no")P(buy_computer="no") = 0.019 × 5/14 = 0.007
判定分類:
max(P(buy_computer="yes"|X), P(buy_computer="no"|X))=max{P(X|buy_computer="yes")P(buy_computer="yes"), P(X|buy_computer="no")P(buy_computer="no")} = 0.028
分類結(jié)果為buy_computer="yes"
要從文本中獲取特征,需要先拆分文本。這里的特征是來(lái)自文本的詞條(token),一個(gè)詞條是字符的任意組合。將每個(gè)文本片段表示為一個(gè)詞條向量,其中值為1表示詞條出現(xiàn)在文檔中,0表示詞條未出現(xiàn)。
準(zhǔn)備數(shù)據(jù):將文本片段切分成一系列詞條集合,每個(gè)文本片段人工標(biāo)記為:貶義文字和正常文字。
postList = [["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] # 1代表貶義文字,0表示正常文字
構(gòu)建詞向量:
def createVocabList(dataSet): vocabSet = set([]) for document in dataSet: vocabSet = vocabSet | set(document) # 兩個(gè)集合的并集 return list(vocabSet) def Words2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] = 1 return returnVec
createVocabList函數(shù)將所有文本片段的詞條組成一個(gè)不含重復(fù)元素的集合。作為一個(gè)無(wú)序的集合,set不記錄元素位置或者插入點(diǎn),所以每次的返回結(jié)果都不一樣。
測(cè)試:
vocabList = createVocabList(postList) print(vocabList) print(words2Vec(vocabList, postList[0])) => ["take", "flea", "stop", "my", "mr", "food", "how", "worthless", "love", "not", "I", "help", "steak", "buying", "stupid", "has", "is", "licks", "dalmation", "dog", "him", "so", "ate", "garbage", "quit", "cute", "posting", "problems", "to", "maybe", "park", "please"] => [0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]
根據(jù)詞向量計(jì)算概率:
流程如下:
計(jì)算每個(gè)類別中的文檔數(shù)目 對(duì)每個(gè)訓(xùn)練文檔片段: 對(duì)每個(gè)類別: 如果詞條出現(xiàn)在文檔中 → 增加該詞條的計(jì)數(shù) 增加所有詞條的計(jì)數(shù) 對(duì)每個(gè)類別: 對(duì)每個(gè)詞條: 將該詞條的數(shù)目除以總詞條數(shù)目得到條件概率 返回每個(gè)類別的條件概率
# 樸素貝葉斯分類器訓(xùn)練函數(shù) def trainNB(trainMatrix, trainClass): numTrainDocs = len(trainMatrix) # 訓(xùn)練文檔的個(gè)數(shù) numWords = len(trainMatrix[0]) # 每個(gè)文檔的詞條個(gè)數(shù) pNagtive = sum(trainClass) / float(numTrainDocs) p0Num = zeros(numWords) p1Num = zeros(numWords) p0Denom = 0.0 p1Denom = 0.0 for i in range(numTrainDocs): if trainClass[i] == 1 p1Num += trainMatrix[i] p1Denom += sum(trainMatrix[i]) else: p0Num += trainMatrix[i] p0Denom += sum(trainMatrix[i]) p1Vect = p1Num / p1Denom # 正常文檔條件概率 p0Vect = p0Num / p0Denom # 貶義文檔條件概率 return p0Vect, p1Vect, pNagtive
測(cè)試:
vocabList = createVocabList(postList) trainMat = [] for postinDoc in postList: trainMat.append(Words2Vec(vocabList, postinDoc)) p0V, p1V, pNa = trainNB(trainMat, classVec) => pNa = 0.5 => p1V = [0.05263158 0. 0.05263158 0. 0. 0.05263158 0. 0.10526316 0. 0.05263158 0. 0. 0. 0.05263158 0.15789474 0. 0. 0. 0. 0.10526316 0.05263158 0. 0. 0.05263158 0.05263158 0. 0.05263158 0. 0.05263158 0.05263158 0.05263158 0. ] => p0V = [0. 0.04166667 0.04166667 0.125 0.04166667 0. 0.04166667 0. 0.04166667 0. 0.04166667 0.04166667 0.04166667 0. 0. 0.04166667 0.04166667 0.04166667 0.04166667 0.04166667 0.08333333 0.04166667 0.04166667 0. 0. 0.04166667 0. 0.04166667 0.04166667 0. 0. 0.04166667]
文檔屬于貶義類的概率 pNa = 0.5,計(jì)算正確;詞匯表的第一個(gè)詞是 take,take 在類別1出現(xiàn)1次,在類別0出現(xiàn)0次,對(duì)應(yīng)的條件概率 0.05263158 > 0,計(jì)算正確;p1V中最大的概率值是 p1V[14] = 0.15789474,對(duì)應(yīng)的詞匯為vocabList[14] = "stupid",這意味著"stupid"是最能表征類別1的詞條。
構(gòu)建分類函數(shù)
在計(jì)算P(w|c)時(shí),如果其中一個(gè)概率為0,則最后的乘積也為0。為降低這種影響,所有詞的出現(xiàn)次數(shù)初始化為1,并將分母初始化為2,即修改trainNB函數(shù)代碼:
p0Num = ones(numWords) p1Num = ones(numWords) p0Denom = 2.0 p1Denom = 2.0
同時(shí),為了避免多個(gè)小數(shù)想成結(jié)果太小,造成下溢,對(duì)p1Vect和p0Vect取對(duì)數(shù)
p1Vect = log(p1Num / p1Denom) # 正常文檔條件概率 p0Vect = log(p0Num / p0Denom) # 貶義文檔條件概率
構(gòu)造分類函數(shù):
def classifyNB(vec2Classify, p0Vec, p1Vec, pclass): p1 = sum(vec2Classify * p1Vec) + log(pclass) p0 = sum(vec2Classify * p0Vec) + log(1.0 - pclass) if p1 > p0: return 1 else: return 03. 樸素貝葉斯評(píng)價(jià)
算法邏輯簡(jiǎn)單,易于實(shí)現(xiàn);
分類過(guò)程時(shí)空開(kāi)銷少;
算法穩(wěn)定;
特征屬性是非連續(xù)的,如果是連續(xù)的需要特殊處理;
特征屬性是相互獨(dú)立,現(xiàn)實(shí)中很難滿足,對(duì)于互相聯(lián)系的特征需要特殊處理;
4. 吐槽一下這個(gè)編輯器的行內(nèi)公式$xxx$無(wú)效啊,4個(gè)$可成功嵌入獨(dú)立一行的公式,參考latex公式編寫(xiě)
5.參考資料python集合(set)類型的操作
十大經(jīng)典算法樸素貝葉斯
機(jī)器學(xué)習(xí)實(shí)戰(zhàn)第4章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/43742.html
摘要:至于為什么選取樸素貝葉斯,很大一個(gè)原因是因?yàn)闃闼刎惾~斯在垃圾郵件分類上有不錯(cuò)的效果,而確定一個(gè)句子屬于那種情感,和判斷一封郵件是否為垃圾郵件有異曲同工之妙。 前言 前段時(shí)間更新了一系列基礎(chǔ)的機(jī)器學(xué)習(xí)算法,感覺(jué)有些無(wú)味,而且恰好那時(shí)買了了國(guó)內(nèi)某公司的云服務(wù)器,就打算部署一套文本處理的WEB API,順別應(yīng)用一下之前學(xué)習(xí)到的機(jī)器學(xué)習(xí)算法。(文末放出地址) 本文不會(huì)涉及過(guò)于復(fù)雜的數(shù)學(xué)原理,主...
閱讀 2035·2023-04-25 22:50
閱讀 2846·2021-09-29 09:35
閱讀 3404·2021-07-29 10:20
閱讀 3171·2019-08-29 13:57
閱讀 3372·2019-08-29 13:50
閱讀 3048·2019-08-26 12:10
閱讀 3552·2019-08-23 18:41
閱讀 2647·2019-08-23 18:01