5.5 樸素貝葉斯分類(lèi)
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
譯文沒(méi)有得到原作者授權(quán),不保證與原文的意思嚴(yán)格一致。
前四節(jié)對(duì)機(jī)器學(xué)習(xí)概念進(jìn)行了總體概述。 在本節(jié)和隨后的一節(jié)中,我們將仔細(xì)研究幾種具體的監(jiān)督和無(wú)監(jiān)督學(xué)習(xí)算法,從這里以樸素貝葉斯分類(lèi)開(kāi)始。
樸素貝葉斯模型是一組非??焖俸秃?jiǎn)單的分類(lèi)算法,通常適用于非常高維的數(shù)據(jù)集。 因?yàn)樗鼈兎浅??,并且具有如此少的可調(diào)參數(shù),所以它們最終適合作為分類(lèi)問(wèn)題的快速而粗略的基準(zhǔn)。 本節(jié)專(zhuān)注于直觀的說(shuō)明,關(guān)于貝葉斯分類(lèi)器的工作原理,其次是一些數(shù)據(jù)集上的實(shí)例。
貝葉斯分類(lèi)
樸素貝葉斯分類(lèi)器建立在貝葉斯分類(lèi)方法上。 它們依賴于貝葉斯定理,一個(gè)描述統(tǒng)計(jì)量條件概率關(guān)系的方程式。 在貝葉斯分類(lèi)中,給定一些觀察特征,我們的興趣是求出的標(biāo)簽的概率,我們可以將其寫(xiě)為P(L | features)。 貝葉斯定理告訴我們,如何用更直接的計(jì)算量來(lái)表達(dá)這一點(diǎn):

如果我們?cè)噲D在兩個(gè)標(biāo)簽之間作出決定 - 讓我們稱之為L1和L2,那么作出這一決定的一個(gè)方法是,計(jì)算每個(gè)標(biāo)簽的后驗(yàn)概率的比率:

我們現(xiàn)在需要一些模型,我們可以通過(guò)它來(lái)計(jì)算每個(gè)標(biāo)簽的P(features | Li)。 這種模型稱為生成模型,因?yàn)樗付松蓴?shù)據(jù)的假設(shè)隨機(jī)過(guò)程。 為每個(gè)標(biāo)簽指定這個(gè)生成模型是這種貝葉斯分類(lèi)器的訓(xùn)練的主要部分。 這種訓(xùn)練步驟的一般版本是一項(xiàng)非常困難的任務(wù),但是我們可以通過(guò)使用關(guān)于該模型形式的一些簡(jiǎn)化假設(shè)來(lái)使其更簡(jiǎn)單。
這就是“樸素貝葉斯”中的“樸素”:如果我們對(duì)每個(gè)標(biāo)簽的生成模型做出非常樸素的假設(shè),我們可以找到每個(gè)分類(lèi)的生成模型的粗略近似,然后進(jìn)行貝葉斯分類(lèi)。 不同類(lèi)型的樸素貝葉斯分類(lèi)器依賴于數(shù)據(jù)的不同樸素假設(shè),我們將在以下部分中對(duì)其中的幾個(gè)進(jìn)行研究。
我們以標(biāo)準(zhǔn)導(dǎo)入來(lái)開(kāi)始:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
高斯樸素貝葉斯
也許最簡(jiǎn)單的樸素貝葉斯分類(lèi)器,是高斯樸素貝葉斯。 在這個(gè)分類(lèi)器中,假設(shè)來(lái)自每個(gè)標(biāo)簽的數(shù)據(jù),是從簡(jiǎn)單的高斯分布中得出的。 假設(shè)您有以下數(shù)據(jù):
from sklearn.datasets import make_blobs
X, y = make_blobs(100, 2, centers=2, random_state=2, cluster_std=1.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu');

創(chuàng)建簡(jiǎn)單模型的一個(gè)非??旖莸姆椒ㄊ?,假設(shè)數(shù)據(jù)服從維度之間沒(méi)有協(xié)方差(獨(dú)立)的高斯分布。 通過(guò)簡(jiǎn)單地找出每個(gè)標(biāo)簽內(nèi)的點(diǎn)的平均值和標(biāo)準(zhǔn)差,可以得到該模型,這就是您需要定義的分布。 這個(gè)樸素高斯假設(shè)的結(jié)果如下圖所示:

這里的橢圓形代表每個(gè)標(biāo)簽的高斯生成模型,橢圓的中心具有較大的概率。 對(duì)于每個(gè)分類(lèi),通過(guò)這個(gè)生成模型,我們有一個(gè)簡(jiǎn)單的秘籍,用于計(jì)算任何數(shù)據(jù)點(diǎn)的可能性P(features | L1),因此我們可以快速計(jì)算后驗(yàn)比率,并確定對(duì)于給定點(diǎn),哪個(gè)標(biāo)簽是最可能的。
Sklearn 的sklearn.naive_bayes.GaussianNB實(shí)現(xiàn)了這個(gè)過(guò)程。
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(X, y);
現(xiàn)在讓我們生成一些新的數(shù)據(jù),并預(yù)測(cè)標(biāo)簽。
rng = np.random.RandomState(0)
Xnew = [-6, -14] + [14, 18] * rng.rand(2000, 2)
ynew = model.predict(Xnew)
現(xiàn)在我們可以繪制新的數(shù)據(jù),來(lái)了解決策邊界在哪里。
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu')
lim = plt.axis()
plt.scatter(Xnew[:, 0], Xnew[:, 1], c=ynew, s=20, cmap='RdBu', alpha=0.1)
plt.axis(lim);

我們?cè)诜诸?lèi)中看到一個(gè)略微彎曲的邊界 - 一般來(lái)說(shuō),高斯樸素貝葉斯的邊界是二次的。
這個(gè)貝葉斯形式的一個(gè)好處是,它自然支持概率分類(lèi),我們可以使用predict_proba方法計(jì)算:
yprob = model.predict_proba(Xnew)
yprob[-8:].round(2)
array([[ 0.89, 0.11],
[ 1. , 0. ],
[ 1. , 0. ],
[ 1. , 0. ],
[ 1. , 0. ],
[ 1. , 0. ],
[ 0. , 1. ],
[ 0.15, 0.85]])
這些列分別提供了第一個(gè)和第二個(gè)標(biāo)簽的后驗(yàn)概率。 如果您正在尋找分類(lèi)中的不確定性估計(jì),這樣的貝葉斯方法可能是有用的方法。
當(dāng)然,最終的分類(lèi)只會(huì)與產(chǎn)生它的模型假設(shè)一樣好,這就是高斯樸素的貝葉斯經(jīng)常不會(huì)產(chǎn)生優(yōu)秀結(jié)果的原因。 然而,在許多情況下,特別是隨著特征數(shù)量的增加,這一假設(shè)并不足以阻止高斯樸素貝葉斯成為有用的方法。
多項(xiàng)式樸素貝葉斯
剛剛描述的高斯假設(shè),絕不是唯一的簡(jiǎn)單假設(shè),可以用于指定每個(gè)標(biāo)簽的生成分布。 另一個(gè)有用的例子是多項(xiàng)式樸素貝葉斯,其中假設(shè)特征從簡(jiǎn)單的多項(xiàng)式分布生成。 多項(xiàng)式分布描述了在多個(gè)類(lèi)別中觀察計(jì)數(shù)的概率,因此多項(xiàng)樸素貝葉斯最適合于表示計(jì)數(shù)或計(jì)數(shù)率的特征。
這個(gè)想法與以前一樣,除了我們不用最佳擬合高斯模型,而用最合適的多項(xiàng)式分布,對(duì)數(shù)據(jù)分布建模。
示例:文本分類(lèi)
經(jīng)常使用多項(xiàng)樸素貝葉斯的一個(gè)地方是文本分類(lèi),其特征與要分類(lèi)的文檔中的字?jǐn)?shù)或頻率有關(guān)。 我們?cè)?a target="_blank" rel="nofollow">特征工程中討論了這些特征的提取; 在這里,我們將使用 20 個(gè)新聞組語(yǔ)料庫(kù)中的稀疏字?jǐn)?shù)特征,來(lái)展示我們?nèi)绾螌⑦@些簡(jiǎn)短文檔分類(lèi)。
讓我們下載數(shù)據(jù)并查看目標(biāo)名稱:
from sklearn.datasets import fetch_20newsgroups
data = fetch_20newsgroups()
data.target_names
['alt.atheism',
'comp.graphics',
'comp.os.ms-windows.misc',
'comp.sys.ibm.pc.hardware',
'comp.sys.mac.hardware',
'comp.windows.x',
'misc.forsale',
'rec.autos',
'rec.motorcycles',
'rec.sport.baseball',
'rec.sport.hockey',
'sci.crypt',
'sci.electronics',
'sci.med',
'sci.space',
'soc.religion.christian',
'talk.politics.guns',
'talk.politics.mideast',
'talk.politics.misc',
'talk.religion.misc']
為了簡(jiǎn)化,我們選擇這些分類(lèi)中的一些,之后下載測(cè)試集。
categories = ['talk.religion.misc', 'soc.religion.christian',
'sci.space', 'comp.graphics']
train = fetch_20newsgroups(subset='train', categories=categories)
test = fetch_20newsgroups(subset='test', categories=categories)
這里是數(shù)據(jù)的一個(gè)簡(jiǎn)單展示:
print(train.data[5])
From: dmcgee@uluhe.soest.hawaii.edu (Don McGee)
Subject: Federal Hearing
Originator: dmcgee@uluhe
Organization: School of Ocean and Earth Science and Technology
Distribution: usa
Lines: 10
Fact or rumor....? Madalyn Murray O'Hare an atheist who eliminated the
use of the bible reading and prayer in public schools 15 years ago is now
going to appear before the FCC with a petition to stop the reading of the
Gospel on the airways of America. And she is also campaigning to remove
Christmas programs, songs, etc from the public schools. If it is true
then mail to Federal Communications Commission 1919 H Street Washington DC
20054 expressing your opposition to her request. Reference Petition number
2493.
為了將這些數(shù)據(jù)用于機(jī)器學(xué)習(xí),我們需要將每個(gè)字符串的內(nèi)容轉(zhuǎn)換為數(shù)值向量。 為此,我們將使用 TF-IDF 向量化器(在特征工程中討論),并創(chuàng)建一個(gè)流水線,將其附加到多項(xiàng)樸素貝葉斯分類(lèi)器:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
model = make_pipeline(TfidfVectorizer(), MultinomialNB())
使用這個(gè)流水簽,我們可以將模型用于訓(xùn)練數(shù)據(jù),并測(cè)試數(shù)據(jù)的預(yù)測(cè)標(biāo)簽。
model.fit(train.data, train.target)
labels = model.predict(test.data)
現(xiàn)在我們已經(jīng)預(yù)測(cè)了測(cè)試數(shù)據(jù)的標(biāo)簽,我們可以評(píng)估它們來(lái)了解估計(jì)器的性能。 例如,這里是測(cè)試數(shù)據(jù)的真實(shí)和預(yù)測(cè)標(biāo)簽之間的混淆矩陣:
from sklearn.metrics import confusion_matrix
mat = confusion_matrix(test.target, labels)
sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=False,
xticklabels=train.target_names, yticklabels=train.target_names)
plt.xlabel('true label')
plt.ylabel('predicted label');

顯然,即使這個(gè)非常簡(jiǎn)單的分類(lèi)器,也可以成功將空間話題與電腦話題分開(kāi),但是在宗教話題和基督教話題之間會(huì)混淆。 這是預(yù)期的混亂。
這里非常酷,我們現(xiàn)在有了工具,用于確定任何字符串的分類(lèi),使用這個(gè)流水線的predict()方法。 這是一個(gè)簡(jiǎn)便的工具函數(shù),它返回單個(gè)字符串的預(yù)測(cè):
def predict_category(s, train=train, model=model):
pred = model.predict([s])
return train.target_names[pred[0]]
讓我們?cè)囋嚳矗?/p>
predict_category('sending a payload to the ISS')
'sci.space'
predict_category('discussing islam vs atheism')
'soc.religion.christian'
predict_category('determining the screen resolution')
'comp.graphics'
記住,這并不比字符串中每個(gè)單詞的(加權(quán))頻率的簡(jiǎn)單概率模型復(fù)雜得多; 然而,結(jié)果是驚人的。 即使是非常匍匐的算法,當(dāng)仔細(xì)使用并對(duì)大量高維數(shù)據(jù)進(jìn)行訓(xùn)練時(shí),會(huì)有效得令人驚奇。
何時(shí)使用樸素貝葉斯
因?yàn)闃闼氐呢惾~斯分類(lèi)器對(duì)數(shù)據(jù)做出了如此嚴(yán)格的假設(shè),所以它們通常不會(huì)和更復(fù)雜的模型一樣好。 也就是說(shuō),它們有幾個(gè)優(yōu)點(diǎn):
- 訓(xùn)練和預(yù)測(cè)都非???/li>
- 提供簡(jiǎn)單的概率預(yù)測(cè)
- 經(jīng)常很容易解釋
- 具有很少的(如果存在)可調(diào)參數(shù)
這些優(yōu)點(diǎn)意味著,樸素的貝葉斯分類(lèi)器通常是初始基本分類(lèi)的不錯(cuò)選擇。 如果適當(dāng)使用,那么恭喜:對(duì)于你的問(wèn)題,你有一個(gè)非??焖伲山忉尩姆诸?lèi)器。 如果表現(xiàn)不佳,那么您可以開(kāi)始探索更復(fù)雜的模型,使用一些基本知識(shí),了解應(yīng)該如何進(jìn)行。
樸素貝葉斯分類(lèi)器在以下情況之一中往往表現(xiàn)得特別好:
- 樸素的假設(shè)實(shí)際匹配數(shù)據(jù)時(shí)(在實(shí)踐中非常罕見(jiàn))
- 對(duì)于分隔良好的分類(lèi),當(dāng)模型復(fù)雜性不太重要時(shí)
- 對(duì)于非常高維的數(shù)據(jù),當(dāng)模型復(fù)雜度不太重要時(shí)
最后兩點(diǎn)看起來(lái)是截然不同的,但它們實(shí)際上是相關(guān)的:隨著數(shù)據(jù)集的維度越來(lái)越大,任何兩點(diǎn)不可能更接近(畢竟,它們必須在每一個(gè)維度上都接近)。 這意味著,如果新維度添加了實(shí)際的信息,平均來(lái)講,高維度的簇比低維度更加分散。 因此,隨著維度增加,像樸素貝葉斯這樣的簡(jiǎn)單分類(lèi)器,往往比復(fù)雜分類(lèi)器有效:一旦你擁有足夠的數(shù)據(jù),即使一個(gè)簡(jiǎn)單的模型也是非常強(qiáng)大的。