Part 1: 本篇內(nèi)容簡(jiǎn)介
在前一篇文章完全手寫,自給自足完成貝葉斯文本分類中,我們使用首先假設(shè)在文檔中出現(xiàn)的單詞彼此獨(dú)立,利用貝葉斯定理,完成了一個(gè)簡(jiǎn)單的文本分類器的編寫,在真實(shí)數(shù)據(jù)的測(cè)試上,顯示了良好的效果。
其實(shí)要是了解sklearn的人都應(yīng)該知道,這個(gè)python的機(jī)器學(xué)習(xí)庫,實(shí)現(xiàn)了我們常用的大部分機(jī)器學(xué)習(xí)算法,免除了我們重復(fù)造輪子的痛苦。我們使用和上一篇博客同樣的數(shù)據(jù),使用sklearn自帶的貝葉斯分類器完成文本分類,同時(shí)和上一篇文章手寫的分類器,進(jìn)行分類精度、速度、靈活性對(duì)比。
Part 2: 樸素貝葉斯的在文本分類中常用模型:多項(xiàng)式、伯努利
這部分的內(nèi)容,我參考了樸素貝葉斯分類器的應(yīng)用這篇文章。樸素貝葉斯分類器是一種有監(jiān)督學(xué)習(xí),常見有兩種模型,多項(xiàng)式模型(multinomial model)即為詞頻型和伯努利模(Bernoulli model)即文檔型。二者的計(jì)算粒度不一樣,多項(xiàng)式模型以單詞為粒度,伯努利模型以文件為粒度,因此二者的先驗(yàn)概率和類條件概率的計(jì)算方法都不同。計(jì)算后驗(yàn)概率時(shí),對(duì)于一個(gè)文檔d,多項(xiàng)式模型中,只有在d中出現(xiàn)過的單詞,才會(huì)參與后驗(yàn)概率計(jì)算,伯努利模型中,沒有在d中出現(xiàn),但是在全局單詞表中出現(xiàn)的單詞,也會(huì)參與計(jì)算,不過是作為“反方”參與的。這里暫不慮特征抽取、為避免消除測(cè)試文檔時(shí)類條件概率中有為0現(xiàn)象而做的取對(duì)數(shù)等問題。
Part 2.1: 多項(xiàng)式模型

Part 2.2: 伯努利模型

Part 2.3: 兩個(gè)模型的區(qū)別

Part 3:在真實(shí)數(shù)據(jù)上的實(shí)驗(yàn)結(jié)果
和上一篇博客一樣,我使用相同的數(shù)據(jù),我這里使用在康奈爾大學(xué)下載的2M影評(píng)作為訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù),里面共同、共有1400條,好評(píng)和差評(píng)各自700條,我選擇總數(shù)的70%作為訓(xùn)練數(shù)據(jù),30%作為測(cè)試數(shù)據(jù),來檢測(cè)sklearn自帶的貝葉斯分類器的分類效果。數(shù)據(jù)的下載鏈接見前一篇博客,或者直接郵件找我。
def get_dataset():
data = []
for root, dirs, files in os.walk(r'E:\研究生階段課程作業(yè)\python\好玩的數(shù)據(jù)分析\樸素貝葉斯文本分類\tokens\neg'):
for file in files:
realpath = os.path.join(root, file)
with open(realpath, errors='ignore') as f:
data.append((f.read(), 'bad'))
for root, dirs, files in os.walk(r'E:\研究生階段課程作業(yè)\python\好玩的數(shù)據(jù)分析\樸素貝葉斯文本分類\tokens\pos'):
for file in files:
realpath = os.path.join(root, file)
with open(realpath, errors='ignore') as f:
data.append((f.read(), 'good'))
random.shuffle(data)
return data
data = get_dataset()
以上的代碼就是讀取全部數(shù)據(jù),包括訓(xùn)練集和測(cè)試集,并隨機(jī)打亂,返回打亂后的結(jié)果。
def train_and_test_data(data_):
filesize = int(0.7 * len(data_))
# 訓(xùn)練集和測(cè)試集的比例為7:3
train_data_ = [each[0] for each in data_[:filesize]]
train_target_ = [each[1] for each in data_[:filesize]]
test_data_ = [each[0] for each in data_[filesize:]]
test_target_ = [each[1] for each in data_[filesize:]]
return train_data_, train_target_, test_data_, test_target_
train_data, train_target, test_data, test_target = train_and_test_data(data)
以上的代碼是用來劃分訓(xùn)練集和測(cè)試集。按照7:3的比例劃分。
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer, HashingVectorizer, CountVectorizer
from sklearn import metrics
from sklearn.naive_bayes import BernoulliNB
nbc = Pipeline([
('vect', TfidfVectorizer(
)),
('clf', MultinomialNB(alpha=1.0)),
])
nbc_6.fit(train_data, train_target) #訓(xùn)練我們的多項(xiàng)式模型貝葉斯分類器
predict = nbc_6.predict(test_data) #在測(cè)試集上預(yù)測(cè)結(jié)果
count = 0 #統(tǒng)計(jì)預(yù)測(cè)正確的結(jié)果個(gè)數(shù)
for left , right in zip(predict, test_target):
if left == right:
count += 1
print(count/len(test_target))
out: 0.793
和我們上一篇完全手寫的貝葉斯分類器相比,使用sklearn自帶的多項(xiàng)式模型貝葉斯分類器,使用相同的訓(xùn)練集和測(cè)試集,結(jié)果后者在測(cè)試集上的精度達(dá)到了79%,比我們?cè)际謱懙木雀叱鰧⒔?0%百分點(diǎn),效果顯而易見,并且訓(xùn)練和分類的速度也大大提高。下面我們使用sklearn自帶的伯努利模型分類器進(jìn)行實(shí)驗(yàn)。
nbc_1= Pipeline([
('vect', TfidfVectorizer(
)),
('clf', BernoulliNB(alpha=0.1)),
])
predict = nbc_1.predict(test_data) #在測(cè)試集上預(yù)測(cè)結(jié)果
count = 0 #統(tǒng)計(jì)預(yù)測(cè)正確的結(jié)果個(gè)數(shù)
for left , right in zip(predict, test_target):
if left == right:
count += 1
print(count/len(test_target))
out: 0.781
和多項(xiàng)式模型相比,使用伯努利模型的貝葉斯分類器,在文本分類方面的精度相比,差別不大,我們可以針對(duì)我們面對(duì)的具體問題,進(jìn)行實(shí)驗(yàn),選擇最為合適的分類器。
Part 4:總結(jié)
sklearn真是太強(qiáng)大了,里面分裝了絕大部分我們常見的機(jī)器學(xué)習(xí)算法,熟悉這些算法的用法,可以讓我們省去重復(fù)造輪子的時(shí)間,把更多的精力面對(duì)我們要解決的問題。所以,如果你不是特別的強(qiáng)迫癥患者,還是使用自帶的算法,因?yàn)檫@些自帶的算法都是經(jīng)過很多人檢驗(yàn),優(yōu)化,兼顧速度和精度上的優(yōu)點(diǎn)。本文選用的訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)都可以從前一篇博客中下載到,如果你嫌麻煩,那么可以直接問我要所有的源代碼和數(shù)據(jù)。
人生苦短,我用python
QQ : 1527927373
EMAIL: 1527927373@qq.com