摘要:貝葉斯是基于概率論的分類方法,通過概率的方式來描述對象劃分到某個分類的可能性。對象有多個屬性假設各個屬性之間是相互獨立的,求解在出現的條件下各個類別出現的概率,選擇最大的作為的分類,通過這種方法構造的分類算法稱為樸素貝葉斯。
貝葉斯是基于概率論的分類方法,通過概率的方式來描述對象劃分到某個分類的可能性。對象X有多個屬性$$X={a_{1}, a_{2}, a_{3}, ... , a_{n}}$$假設各個屬性之間是相互獨立的,求解在X出現的條件下各個類別 $$C_{i}$$出現的概率,選擇最大的 $$P(C_{i}|X) $$作為X的分類,通過這種方法構造的分類算法稱為樸素貝葉斯。1.樣本空間與概率論
假設為Ω實驗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為樣本空間Ω的一個劃分。假設A為E的一個事件,由全概率公式得:
$$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發生的前提下,事件A發生的概率,公式表示為:
$$P(A|B)=frac{P(AB)}{P(B)}$$
P(B|A)是根據A參數值判斷對象屬于類別B的概率,稱為后驗概率。P(B)是直接判斷某個樣本屬于類別B的概率,稱為先驗概率。P(A|B)是在類別B中觀測到A的概率,P(A)是在數據集中觀測到A的概率,則有:
$$P(B|A)=frac{P(A|B)P(B)}{P(A)}$$
公式的證明很簡單,參考條件概率公式。于是有:
$$=>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})}$$
對于樸素貝葉斯,對象的各個特征值相互獨立,則有:
$$=>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})}$$
設X={a1, a2, a3, ..., an}為一個待分類項,每個a為X的一個特征屬性,特征屬性彼此獨立
設C={c1, c2, c3, ..., cn}為樣本類別集合
計算P(c1|X)P(c2|X)P(c3|X)...P(cn|X)
計算P(ck|X) = max{P(c1|X), P(c2|X), P(c3|X), ..., P(cn|X)},則X屬于類別ck
2.2 案例1:電腦購買數據集:
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"}
計算每個類的先驗概率:
$$P(c_{1})=9/14,P(c_{2})=5/14$$
計算每個屬性對于每個類別的條件概率:
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
計算條件概率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
計算每個類的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
分類結果為buy_computer="yes"
要從文本中獲取特征,需要先拆分文本。這里的特征是來自文本的詞條(token),一個詞條是字符的任意組合。將每個文本片段表示為一個詞條向量,其中值為1表示詞條出現在文檔中,0表示詞條未出現。
準備數據:將文本片段切分成一系列詞條集合,每個文本片段人工標記為:貶義文字和正常文字。
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表示正常文字
構建詞向量:
def createVocabList(dataSet): vocabSet = set([]) for document in dataSet: vocabSet = vocabSet | set(document) # 兩個集合的并集 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函數將所有文本片段的詞條組成一個不含重復元素的集合。作為一個無序的集合,set不記錄元素位置或者插入點,所以每次的返回結果都不一樣。
測試:
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]
根據詞向量計算概率:
流程如下:
計算每個類別中的文檔數目 對每個訓練文檔片段: 對每個類別: 如果詞條出現在文檔中 → 增加該詞條的計數 增加所有詞條的計數 對每個類別: 對每個詞條: 將該詞條的數目除以總詞條數目得到條件概率 返回每個類別的條件概率
# 樸素貝葉斯分類器訓練函數 def trainNB(trainMatrix, trainClass): numTrainDocs = len(trainMatrix) # 訓練文檔的個數 numWords = len(trainMatrix[0]) # 每個文檔的詞條個數 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
測試:
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,計算正確;詞匯表的第一個詞是 take,take 在類別1出現1次,在類別0出現0次,對應的條件概率 0.05263158 > 0,計算正確;p1V中最大的概率值是 p1V[14] = 0.15789474,對應的詞匯為vocabList[14] = "stupid",這意味著"stupid"是最能表征類別1的詞條。
構建分類函數
在計算P(w|c)時,如果其中一個概率為0,則最后的乘積也為0。為降低這種影響,所有詞的出現次數初始化為1,并將分母初始化為2,即修改trainNB函數代碼:
p0Num = ones(numWords) p1Num = ones(numWords) p0Denom = 2.0 p1Denom = 2.0
同時,為了避免多個小數想成結果太小,造成下溢,對p1Vect和p0Vect取對數
p1Vect = log(p1Num / p1Denom) # 正常文檔條件概率 p0Vect = log(p0Num / p0Denom) # 貶義文檔條件概率
構造分類函數:
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. 樸素貝葉斯評價
算法邏輯簡單,易于實現;
分類過程時空開銷少;
算法穩定;
特征屬性是非連續的,如果是連續的需要特殊處理;
特征屬性是相互獨立,現實中很難滿足,對于互相聯系的特征需要特殊處理;
4. 吐槽一下這個編輯器的行內公式$xxx$無效啊,4個$可成功嵌入獨立一行的公式,參考latex公式編寫
5.參考資料python集合(set)類型的操作
十大經典算法樸素貝葉斯
機器學習實戰第4章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43742.html
摘要:至于為什么選取樸素貝葉斯,很大一個原因是因為樸素貝葉斯在垃圾郵件分類上有不錯的效果,而確定一個句子屬于那種情感,和判斷一封郵件是否為垃圾郵件有異曲同工之妙。 前言 前段時間更新了一系列基礎的機器學習算法,感覺有些無味,而且恰好那時買了了國內某公司的云服務器,就打算部署一套文本處理的WEB API,順別應用一下之前學習到的機器學習算法。(文末放出地址) 本文不會涉及過于復雜的數學原理,主...
閱讀 2020·2023-04-25 22:50
閱讀 2834·2021-09-29 09:35
閱讀 3390·2021-07-29 10:20
閱讀 3153·2019-08-29 13:57
閱讀 3356·2019-08-29 13:50
閱讀 3032·2019-08-26 12:10
閱讀 3530·2019-08-23 18:41
閱讀 2634·2019-08-23 18:01