貝葉斯分類算法是統(tǒng)計(jì)學(xué)的一種分類方法,它是一類利用概率統(tǒng)計(jì)知識(shí)進(jìn)行分類的算法。該算法的優(yōu)點(diǎn)在于簡(jiǎn)單易懂、學(xué)習(xí)效率高、在某些領(lǐng)域的分類問題中能夠與決策樹、神經(jīng)網(wǎng)絡(luò)相媲美。接下來(lái)我們介紹一下這個(gè)算法:
一、基礎(chǔ)知識(shí)
在我們講貝葉斯分類器之前,我們先補(bǔ)充一下相關(guān)的數(shù)學(xué)知識(shí):
1、條件概率
條件概率是指事件A在另一個(gè)事件B已經(jīng)發(fā)生條件下發(fā)生的概率。條件概率表示為P(A/B),讀作“在B條件下A的概率”。
若只有兩個(gè)事件A,B,那么:P(AB) = P(A\B)P(B) = P(B\A)P(A)
即:
2、全概率公式
表示若事件A1,A2,…,An構(gòu)成一個(gè)完備事件組且都有正概率,則對(duì)任意一個(gè)事件B都有公式成立:
同時(shí)P(B)也可以表示為:
3、貝葉斯公式
由條件概率公式可以得到貝葉斯表達(dá)式:
將全概率公式代入到條件概率公式當(dāng)中,對(duì)于事件和事件B有:
a、P(A)是 A 的先驗(yàn)概率,之所以稱為“先驗(yàn)”是因?yàn)樗豢紤]任何 B 方面的因素。
b、P(A|B)是已知 B 發(fā)生后 A 的條件概率,也由于得自 B 的取值而被稱作 A 的后驗(yàn)概率。
c、P(B|A)是已知 A 發(fā)生后 B 的條件概率,也由于得自 A 的取值而被稱作 B 的后驗(yàn)概率。
d、P(B)是 B 的先驗(yàn)概率,也作標(biāo)淮化常量(normalizing constant)。
二、貝葉斯定理
設(shè)X是類標(biāo)號(hào)未知的數(shù)據(jù)樣本。設(shè)H為某種假定,如,數(shù)據(jù)樣本X屬于某特定的類C。對(duì)于分類問題,我們希望確定P(H\X)-給定觀測(cè)數(shù)據(jù)樣本,假定H成立的概率。P(H\X)是后驗(yàn)概率,或條件X下,H的后驗(yàn)概率。例如,假定數(shù)據(jù)樣本世界是由水果組成,用它們的顏色和形狀描述,假定X表示紅色和圓的,H表示假定X是蘋果,則P(H\X)反映當(dāng)我們看到X是紅色并是圓時(shí),我們對(duì)X是蘋果的確信程度。P(H)是先驗(yàn)概率,或H的先驗(yàn)概率,對(duì)于我們的例子,它是任意給定的數(shù)據(jù)樣本為蘋果的概率,而不管數(shù)據(jù)樣本看上去如何。后驗(yàn)概率P(H\X)比先驗(yàn)概率P(H)基于更多的信息(如,背景知識(shí))。P(H)是獨(dú)立于X的。
類似的,P(X\H)是條件H下,X的后驗(yàn)概率。即,它是已知X是蘋果,X是紅色并且是圓的的概率。P(X)是X的先驗(yàn)概率。
“如何計(jì)算這些概率?”,給定數(shù)據(jù)集,P(X)、P(H)、P(X|H)我們是可以求出來(lái)的,這時(shí)候貝葉斯就發(fā)揮了作用,它提供了一種由P(X)、P(H)、P(X|H)計(jì)算后驗(yàn)概率P(H|X)的方法:
三、樸素貝葉斯分類器的公式
假設(shè)某個(gè)體有n項(xiàng)特征(Feature),分別為F1,F(xiàn)2,...,F(xiàn)n。現(xiàn)在有m個(gè)類別(Category),分別為C1,C2,C3,...,Cm。貝葉斯分類器就是計(jì)算出概率最大的那個(gè)分類,也就是求下面這個(gè)算式的最大值:
由于P(F1F2...Fn)對(duì)于所有的分類都是相同的,可以省略,問題就變成了求
的最大值。
樸素貝葉斯分類器則是更進(jìn)一步,假設(shè)所有特征都彼此獨(dú)立,因此:
上式等號(hào)右邊的每一項(xiàng),都可以從統(tǒng)計(jì)資料中得到,由此就可以計(jì)算出每個(gè)類別對(duì)應(yīng)的概率,從而找出最大概率的那個(gè)類。雖然"所有特征彼此獨(dú)立"這個(gè)假設(shè),在現(xiàn)實(shí)中不太可能成立,但是它可以大大簡(jiǎn)化計(jì)算。
四、拉普拉斯平滑(Laplace smoothing)
也就是參數(shù)為1時(shí)的貝葉斯估計(jì),當(dāng)某個(gè)分量在總樣本某個(gè)分類中(觀察樣本庫(kù)/訓(xùn)練集)從沒出現(xiàn)過,會(huì)導(dǎo)致整個(gè)實(shí)例的計(jì)算結(jié)果為0。為了解決這個(gè)問題,使用拉普拉斯平滑進(jìn)行處理。它的思想非常簡(jiǎn)單,就是對(duì)先驗(yàn)概率的分子(劃分的計(jì)數(shù))加1,分母加上類別數(shù);對(duì)條件概率分子加1,分母加上對(duì)應(yīng)特征的可能取值數(shù)量。這樣在解決零概率問題的同時(shí),也保證了概率和依然為1.
這里舉個(gè)例子,假設(shè)在文本分類中,有3個(gè)類,C1,C2,C3,在指定的訓(xùn)練樣本中,某個(gè)詞語(yǔ)F1,在各個(gè)類中觀測(cè)計(jì)數(shù)分別為0,990,10,則概率為P(F1|C1)=0,P(F1|C2)=0.99,P(F1|C3)=0.01,對(duì)這三個(gè)量使用拉普拉斯平滑的計(jì)算方法如下:1/1003=0.001,991/1003=0.988,11/1003=0.011
五、樸素貝葉斯定理的應(yīng)用
貝葉斯算法在文本領(lǐng)域有重要的應(yīng)用:
文本挖掘典型場(chǎng)景
1、網(wǎng)頁(yè)自動(dòng)分類
2、垃圾郵件判斷
3、評(píng)論自動(dòng)分析
4、通過用戶訪問內(nèi)容判別用戶喜好
這里我們進(jìn)行兩個(gè)實(shí)例的講解:
-
文本分類
數(shù)據(jù)集我們使用sklearn自帶的新聞數(shù)據(jù)集20news-bydate_py3.pkz,將它劃分訓(xùn)練集與測(cè)試集進(jìn)行預(yù)測(cè)
#導(dǎo)包
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics.classification import classification_report
1、獲取數(shù)據(jù)集
def naivebayes():
"""
樸素貝葉斯進(jìn)行分本分類
:return:
"""
#獲取數(shù)據(jù)集
news = fetch_20newsgroups(subset='all')
print(news)
if __name__ == "__main__":
naivebayes()
結(jié)果我就不展示了,有興趣的同學(xué)加載一下看看。
2、進(jìn)行數(shù)據(jù)集的分割和特征提取
def naivebayes():
"""
樸素貝葉斯進(jìn)行分本分類
:return:
"""
#獲取數(shù)據(jù)集
news = fetch_20newsgroups(subset='all')
print(news)
#對(duì)數(shù)據(jù)集進(jìn)行分割
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
#進(jìn)行特征抽取
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
print(tf.get_feature_names())#輸出特征名
x_test = tf.transform(x_test)
if __name__ == "__main__":
naivebayes()

3、進(jìn)行貝葉斯算法預(yù)測(cè)并輸出準(zhǔn)確率、精確率和召回率
def naivebayes():
"""
樸素貝葉斯進(jìn)行分本分類
:return:
"""
#獲取數(shù)據(jù)集
news = fetch_20newsgroups(subset='all')
print(news)
#對(duì)數(shù)據(jù)集進(jìn)行分割
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
#進(jìn)行特征抽取
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
print(tf.get_feature_names())#輸出特征名
x_test = tf.transform(x_test)
#進(jìn)行貝葉斯算法預(yù)測(cè)
mlt = MultinomialNB(alpha=1.0)
print(x_train.toarray())
mlt.fit(x_train,y_train)
y_predict = mlt.predict(x_test)
print("預(yù)測(cè)的文章類型為:",y_predict)
#得出準(zhǔn)確率
print("準(zhǔn)確率為:",mlt.score(x_test,y_test))
#得出精確率召回率
print("每個(gè)類別的精確率和召回率:",classification_report(y_test,y_predict,target_names=news.target_names))#target_names表示每個(gè)類別的名稱(比如文章分科技、娛樂等)
return None
if __name__ == "__main__":
naivebayes()


- 貝葉斯拼寫檢查器
#正則匹配、字典
import re,collections
#把語(yǔ)料中的單詞全部抽取出來(lái),轉(zhuǎn)成小寫,并且去除單詞中間的特殊符號(hào)
def words(text):#正則匹配
return re.findall('[a-z]+',text.lower())#大寫變小寫
#如果遇到一個(gè)新詞,拼寫完全正確,但是語(yǔ)料庫(kù)中沒有包含這個(gè)詞,那么這個(gè)詞也永遠(yuǎn)不會(huì)出現(xiàn)在訓(xùn)練集中
#這時(shí)我們返回這個(gè)詞的概率是0,但是這樣不符合實(shí)際,因?yàn)楦怕蕿?就代表了這個(gè)事件絕對(duì)不會(huì)發(fā)生
#而在我們的概率模型中,我們期望用一個(gè)很小的概率來(lái)代表這種情況,詞頻設(shè)為1
def train(features):
model=collections.defaultdict(lambda:1)#返回一個(gè)類似字典的對(duì)象
for f in features:
model[f]+=1#詞頻+1
return model
NWORDS=train(words(open('E:\\學(xué)習(xí)文件\\機(jī)器學(xué)習(xí)\\數(shù)據(jù)集\\貝葉斯算法\\test.txt').read()))#返回字典類型
alphabet='abcdefghijklmnopqrstuvwxyz'
#編輯距離:兩個(gè)詞之間的編輯距離定義為使用了幾次插入(在詞中插入一個(gè)單字母),刪除(刪除一個(gè)單字母)
#交換(交換相鄰兩個(gè)字母),替換(一個(gè)字母換成另一個(gè))的操作從一個(gè)詞變成另外一個(gè)詞
#返回所有與單詞w編輯距離為1的姐
def edits(word):
n=len(word)
return set([word[0:i]+word[i+1:] for i in range(n)]+
[word[0:i]+word[i+1:]+word[i]+word[i+2:] for i in range(n-1)]+
[word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet]+
[word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet])
#編輯距離為2的單詞也會(huì)存在,但是單詞數(shù)會(huì)非常多這里把編輯距離小于2的詞中,只把那些正確的詞作為候選詞
def edits2(word):
return set(e2 for e1 in edits(word) for e2 in edits(e1))
#正常來(lái)說(shuō)把一個(gè)元音拼成另一個(gè)的概率要大于輔音(因?yàn)槿顺30裩ello打成hallo這樣)把單詞的第一個(gè)字母拼錯(cuò)的概率會(huì)相對(duì)小,等等。
#但是為了簡(jiǎn)單起見,選擇了一個(gè)簡(jiǎn)單的方法:編輯距離為1的正確單詞比編輯距離為2的優(yōu)先級(jí)高,而編輯距離為0的正確單詞優(yōu)先級(jí)比編輯距離為1的高
def known_edits(word):
return set(e2 for e1 in edits(word) for e2 in edits(e1) if e2 in NWORDS)
def known(words):
return set(w for w in words if w in NWORDS)
#如果known(set)非空,candidate就會(huì)選取這個(gè)集合,而不繼續(xù)計(jì)算后面的
def correct(word):
candidates=known([word]) or known(edits(word)) or known_edits(word) or [word]
return max(candidates,key=lambda w:NWORDS[w])
correct('tha')

代碼相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,相關(guān)說(shuō)明都已經(jīng)在代碼中注釋了,大家可以看一下~
六、算法總結(jié)
1、優(yōu)點(diǎn)
- 樸素貝葉斯模型發(fā)源于古典數(shù)學(xué)理論,有穩(wěn)定的分類效率
- 對(duì)缺失數(shù)據(jù)不太敏感,算法也比較簡(jiǎn)單,常用于文本分類
- 分類準(zhǔn)確度高,速度快
2、缺點(diǎn)
- 由于使用了樣本屬性獨(dú)立性的假設(shè),所以如果樣本屬性有關(guān)聯(lián)時(shí),其效果不好
樸素貝葉斯定理就講到這里,有興趣的同學(xué)可以將上面的代碼執(zhí)行一下。