實戰|樸素貝葉斯分類對文檔進行分類

2021-03-02 每天曬白牙
樸素貝葉斯對文檔進行分類

主要使用sklearn這個機器學習包完成對文檔的分類

sklearn機器學習包

sklearn提供了三個樸素貝葉斯分類算法:

高斯樸素貝葉斯:特徵變量是連續變量,符合高斯分布,比如人的身高和體重等多項式樸素貝葉斯:特徵變量是離線變量,符合多項分布,在文檔分類中特徵向量體現在一個單詞出現的次數或者是單詞的TF-IDF值等

伯努利樸素貝葉斯:特徵變量是布爾變量,符合0/1分布,在文檔分類中特徵是單詞是否出現

TF-IDF

多項式樸素貝葉斯中提到了TF-IDF(Term Frequency-Inverse Document Frequence 的縮寫,其中TF代表詞頻,IDF代表逆向文檔頻率),它是一個統計方法,用以評估某一個詞語對於一個文檔集或一個語料庫中的其中一份文檔的重要程度。詞語的重要性隨著它在文檔中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降

詞頻TF:指的是某一個給定的詞語在該文檔中出現的頻率,詞語的重要性和它在文檔中出現的次數正相關

逆向文檔頻率IDF:指的是某一個給定的詞語在文檔中的區分度,詞語出現在的文檔數越少,這個詞語的區分度就越高,越容易用這個詞語把該文檔和其他文檔區分開。IDF越大,這個詞語的區分度就越高所以,我們傾向於找到TF和IDF都高的單詞作為區分,即這個單詞在一個文檔中出現的次數多,但在其他文檔中出現的次數少,所以很適合用於分類

TF-IDF=TF*IDF

其中計算IDF公式的分母中,單詞出現的次數+1是為了避免分子為0

介紹完了sklearn機器學習包中的三個樸素貝葉斯算法,下面就開始用這個包進行對文檔的分類

文檔分類的步驟

對文檔分類,分兩個階段,看下面的圖:

基於分詞的準備:分詞、單詞權重計算、去掉停用詞

應用樸素貝葉斯進行分類:先通過訓練集得到樸素貝葉斯分類器,然後將分類器用於測試集,將預測結果和實際結果做對比並計算準確率

整個過程分為六個步驟

1.對文檔進行分詞

對文檔分詞的時候,英文文檔和中文文檔使用的分詞工具不同。英文文檔常用NTLK包,其中包含了英文的停用詞表、分詞和標註方法中文文檔常用jieba包,其中包含了中文的停用詞表和分詞方法

def get_data(base_path, labels):  # 獲取數據集

   contents = []

   # 數據在文件夾下,需要遍歷各個文檔類別下的文件

   for label in labels:

       files = {fileName for fileName in os.listdir(base_path + label)}

       try:

           for fileName in files:

               file = open(base_path + label + '/' + fileName, encoding='gb18030')

               word = jieba.cut(file.read())  # 對文檔進行分詞 中文文檔多用 jieba 包

               contents.append(' '.join(word))  # 因為切詞,所以用 ' ' 分隔

       except Exception:

           print(fileName + '文件讀取錯誤')

   return contents

# 獲取訓練集

train_contents = get_data(train_base_path, train_labels)

# 獲取測試集

test_contents = get_data(test_base_path, test_labels)

2.加載停用詞表

需要我們先下載常用的停用詞表,然後放到stop_word.txt中,讀取裡面的數據放到數組中

stop_words = [line.strip() for line in open(stop_words_path, encoding='utf-8-sig').readlines()]

3.計算單詞權重

用sklearn裡的TfidfVectorizer類,使用fit_transform方法進行擬合,得到TF-IDF特徵空間features,可以理解為選出來的分詞就是特徵,計算這些特徵在文檔上的特徵向量,得到特徵空間features

tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)

train_features = tf.fit_transform(train_contents)  # 擬合

這裡max_df參數表示單詞在文檔中最高出現頻率。這裡設置0.5代表一個單詞在50%的文檔中都出現過了,攜帶的信息比較少,就不作為分詞統計,這個參數可以調。min_df很少設置

4.生成樸素貝葉斯分類器

把訓練集訓練出來的特徵空間features和訓練集對應的分類labels傳給貝葉斯分類器,會自動生成一個符合特徵空間和對應分類的分類器上面介紹了sklearn包提供的三個樸素貝葉斯分類器,根據特性這裡採用多項式樸素貝葉斯分類器即MultinomialNB,其中alpha為平滑參數。當一個單詞在訓練集中樣本中沒有出現的時候,該單詞的概率被置為0,但是訓練集一般是抽樣的,所以單詞在樣本中不存在就置為0不太合理,需要平滑處理

alpha平滑類別特點0~1Laplace平滑採用+1的方式,當樣本很大的時候,+1得到的概率的影響可以忽略不計,同時也避免了分母為0的情況1Lidstone平滑alpha越小,迭代次數越多,精度越高

代碼

train_labels = ['體育'] * 1337 + ['女性'] * 954 + ['文學'] * 766 + ['校園'] * 249  # 數字是自己算的,也可以用程序判斷

clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)  # MultinomialNB.fit(x,y) 其中 y的數量要等於訓練x的數量

5.使用生成的分類器做預測

主要是得到測試集的特徵矩陣,先創建FfidfVectorizer,使是和訓練集一樣的stop_words和max_df,然後用FfidfVectorizer類對測試集內容進行擬合,得到測試集特徵矩陣,再用訓練好的分類器對測試特徵矩陣進行預測,predict這個函數求解所有的後驗概率並找到最大的那個

test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=tf.vocabulary_)

test_features = test_tf.fit_transform(test_contents)

# 預測

predicted_labels = clf.predict(test_features)

6.計算準確率

計算正確率主要是對模型預測的結果和實際的結果進行對比,給出模型的準確率,用到sklearn中的metrics包中的accuracy_score函數

test_labels = ['體育'] * 115 + ['女性'] * 38 + ['文學'] * 31 + ['校園'] * 16

print('準確率', metrics.accuracy_score(test_labels, predicted_labels))

實戰

實戰用到的數據從專欄老師的github上下載,點擊這裡下載數據介紹:提供了三份數據,一個訓練集文檔(train文件夾下)、一個測試集文檔(test文件夾下)和一個停用詞表,其中訓練集和測試集的文檔分為四種類型:女性、體育、文學、校園用樸素貝葉斯分類對訓練集訓練,並對測試集進行驗證,並給出真確率

我的完整代碼

import os

import jieba

from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.naive_bayes import MultinomialNB

from sklearn import metrics

# 停用詞表地址

stop_words_path = 'D:/workspace/study/python/test_data/text_classification/stop/stop_word.txt'

# 訓練集根目錄

train_base_path = 'D:/workspace/study/python/test_data/text_classification/train/'

# 測試集根目錄

test_base_path = 'D:/workspace/study/python/test_data/text_classification/test/'

# 文檔類別

train_labels = ['女性', '體育', '文學', '校園']

test_labels = ['女性', '體育', '文學', '校園']

def get_data(base_path, labels):  # 獲取數據集

   contents = []

   # 數據在文件夾下,需要遍歷各個文檔類別下的文件

   for label in labels:

       files = {fileName for fileName in os.listdir(base_path + label)}

       try:

           for fileName in files:

               file = open(base_path + label + '/' + fileName, encoding='gb18030')

               word = jieba.cut(file.read())  # 對文檔進行分詞 中文文檔多用 jieba 包

               contents.append(' '.join(word))  # 因為切詞,所以用 ' ' 分隔

       except Exception:

           print(fileName + '文件讀取錯誤')

   return contents

# 1.對文檔進行分詞

# 獲取訓練集

train_contents = get_data(train_base_path, train_labels)

# print(train_contents)

# print('訓練集的長度:', len(train_contents))

# 獲取測試集

test_contents = get_data(test_base_path, test_labels)

# print(test_contents)

# print('測試集的長度:', len(test_contents))

# 2.加載停用詞表

stop_words = [line.strip() for line in open(stop_words_path, encoding='utf-8-sig').readlines()]

# print(stop_words)

# 3.計算單詞權重

tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)

train_features = tf.fit_transform(train_contents)  # 擬合

# 4.生成樸素貝葉斯分類器 這裡使用多項式貝葉斯分類器

train_labels = ['體育'] * 1337 + ['女性'] * 954 + ['文學'] * 766 + ['校園'] * 249

clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)  # MultinomialNB.fit(x,y) 其中 y的數量要等於訓練x的數量

# 5.使用生成的分類器做預測

test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=tf.vocabulary_)

test_features = test_tf.fit_transform(test_contents)

# 預測

predicted_labels = clf.predict(test_features)

# 6.計算準確率

test_labels = ['體育'] * 115 + ['女性'] * 38 + ['文學'] * 31 + ['校園'] * 16

print('準確率', metrics.accuracy_score(test_labels, predicted_labels))

結果

0.62這個結果的準確率我覺得還是挺低的,剛過60%,需要優化

聲明:文中的圖片和知識點內容主要來自極客時間的專欄《數據分析實戰45講》,這是專欄的一道實戰作業題

相關焦點

  • 樸素貝葉斯分類算法原理與實踐
    樸素貝葉斯分類器講了上面的小故事,我們來樸素貝葉斯分類器的表示形式:分類的結果如下:8343 10000 0.8343總共10000條新聞,分類正確的8343條,正確率0.8343,這裡主要是演示貝葉斯的分類過程,只考慮了正確率也沒有考慮其他評價指標,也沒有進行優化。
  • 文本分類和樸素貝葉斯,你真的理解了嗎?
    ,(dm,cm)輸出: 一個分類器 γ : d->c分類器種類a. 樸素貝葉斯 b.K 近鄰二、樸素貝葉斯1. 基於貝葉斯規則的簡單分類方法2.形式化樸素貝葉斯分類器對於一個文檔 d 和一個分類 cMAP 是最大化後驗概率,或者說:最有可能的類別。
  • 教你明白啥是樸素貝葉斯分類器
    前言樸素貝葉斯算法仍然是流行的十大挖掘算法之一,該算法是有監督的學習算法,解決的是分類問題
  • 基於貝葉斯定理的算法——樸素貝葉斯分類
    不過今天我們介紹的樸素貝葉斯分類器通過獨立假設簡化了概率的計算,節省了內存,可以很好地用於數據量大的情況。下面我們首先來了解這一算法的數理背景——貝葉斯定理。這一算法是由我們在概率論中學到的貝葉斯定理延伸出來的。我們知道貝葉斯公式為:其中,
  • scikit-learn—樸素貝葉斯
    分布的假設。儘管貝葉斯分類器的假設明顯過於簡單,但它們在許多實際情況下(在著名的文檔分類和垃圾郵件過濾中)都表現良好,它們需要少量的訓練數據來估計必要的參數。伯努利(Bernoulli)樸素貝葉斯BernoulliNB實現了用於多元Bernoulli分布數據的樸素Bayes訓練和分類算法,即有多個特徵,但每個特徵都假定為二值(Bernoulli,boolean)變量。因此,此類算法要求樣本以二值特徵向量表示。如果傳遞任何其他類型的數據,BernoulliNB實例可以對其輸入進行二值化(取決於binarize 參數)。
  • 樸素貝葉斯分類垃圾簡訊和R實現
    樸素貝葉斯算法思想起源18世紀數學家託馬斯.貝葉斯(Thomas Bayes),基於貝葉斯定理和特徵條件獨立假設的分類方法,它通過特徵計算分類的概率,選取概率大的情況,是基於概率論的一種機器學習分類(監督學習)方法。
  • 機器學習基礎:樸素貝葉斯及經典實例講解
    化簡一下,樸素貝葉斯分類器可表示為:(3)對缺失數據不太敏感,算法也比較簡單,常用於文本分類。缺點:(1)理論上,樸素貝葉斯模型與其他分類方法相比具有最小的誤差率。但是實際上並非總是如此,這是因為樸素貝葉斯模型給定輸出類別的情況下,假設屬性之間相互獨立,這個假設在實際應用中往往是不成立的,在屬性個數比較多或者屬性之間相關性較大時,分類效果不好。
  • 樸素貝葉斯分類器詳解及中文文本輿情分析(附代碼實踐)
    樸素貝葉斯數學原理知識該基礎知識部分引用文章"機器學習之樸素貝葉斯(NB)分類算法與Python實現"(https://blog.csdn.net/moxigandashu/article/details/71480251),也強烈推薦大家閱讀博主moxigandashu的文章,寫得很好。同時作者也結合概率論講解,提升下自己較差的數學。
  • 貝葉斯新聞分類實戰項目詳解
    社會、娛樂、電影等各種分類,數以億計的新聞,通過機器學習完成分類。那麼我們自己能不能自己做一個新聞分類的應用呢?答案是肯定的,本文將帶領大家學習基於貝葉斯方法的新聞分類實戰,快來學習吧。貝葉斯方法解決的問題就是上面舉例中的逆向概率的求解。新聞分類也是一樣,根據一篇新聞的內容,推斷其最有可能哪個類別。下面就開始新聞分類的實戰之旅。新聞分類實戰1. 文本分詞就是將獲取到的新聞數據,轉化成有一個個詞語組成的樣式。
  • 分類算法之貝葉斯網絡
    》2.1、摘要在上一篇文章中我們討論了樸素貝葉斯分類。樸素貝葉斯分類有一個限制條件,就是特徵屬性必須有條件獨立或基本獨立(實際上在現實應用中幾乎不可能做到完全獨立)。當這個條件成立時,樸素貝葉斯分類法的準確率是最高的,但不幸的是,現實中各個特徵屬性間往往並不條件獨立,而是具有較強的相關性,這樣就限制了樸素貝葉斯分類的能力。
  • 機器學習 | Sklearn中的樸素貝葉斯全解
    類含義naive_bayes.BernoulliNB伯努利分布下的樸素貝葉斯naive_bayes.GaussianNB高斯分布下的樸素貝葉斯naive_bayes.MultinomialNB多項式分布下的樸素貝葉斯naive_bayes.ComplementNB補集樸素貝葉斯雖然樸素貝葉斯使用了過於簡化的假設,這個分類器在文檔分類和垃圾郵件過濾等領域中都運行良好
  • Matlab建立SVM,KNN和樸素貝葉斯模型分類繪製ROC曲線
    p=15508繪製ROC曲線通過Logistic回歸進行分類加載樣本數據。通過使用與versicolor和virginica物種相對應的度量來定義二元分類問題。定義二進位響應變量。最大AUC為1,對應於理想分類器。較大的AUC值表示更好的分類器性能。
  • 樸素貝葉斯(Naive Bayes)和校正曲線(Calibration Curve)
    算法回顧圖片來源:medium.com貝葉斯分類算法屬於有監督機器學習(Supervised Learning)。貝葉斯分類器是一類分類算法的總稱,這類算法均以貝葉斯定理為基礎,故統稱為貝葉斯分類。其中樸素貝葉斯分分類是貝葉斯分類中最簡單的,也是最常見的一種分類方法。樸素貝葉斯分類算法的核心如下公式:P(A):它是先驗(Prior Probability),是A發生的概率。P(B): 是邊際可能性(Marginal Likelihood):是B發生的概率。
  • 解讀實踐中最廣泛應用的分類模型:樸素貝葉斯算法
    貝葉斯模型在機器學習以及人工智慧中都有出現,cherry 分類器使用了樸素貝葉斯模型算法,經過簡單的優化,使用 1000 個訓練數據就能得到 97.5% 的準確率。雖然現在主流的框架都帶有樸素貝葉斯模型算法,大多數開發者只需要直接調用 api 就能使用。但是在實際業務中,面對不同的數據集,必須了解算法的原理,實現以及懂得對結果進行分析,才能達到高準確率。
  • 獨家 | 一文讀懂貝葉斯分類算法(附學習資源)
    隨後介紹貝葉斯分類算法的基礎——貝葉斯定理。最後介紹貝葉斯分類中最簡單的一種——樸素貝葉斯分類,並結合應用案例進一步闡釋。貝葉斯分類1. 分類問題綜述對於分類問題,我們每一個人都並不陌生,因為在日常生活中我們都在或多或少地運用它。
  • 機器學習算法實踐-樸素貝葉斯(Naive Bayes)
    ,對垃圾簡訊進行過濾,在最後對分類的錯誤率進行了計算。當然樣本越多我們統計的不同類型的特徵值分布就越準確,使用此分布進行預測則會更加準確。貝葉斯準則樸素貝葉斯分類器中最核心的便是貝葉斯準則,他用如下的公式表示:
  • 樸素貝葉斯算法的案例實現
    一、樸素貝葉斯分類的R函數介紹1、樸素貝葉斯分類算法的實現函數R中的e1071包中的naiveBayes函數可以實現樸素貝葉斯算法,具體的函數格式如下:naiveBayes(x, y,laplace=0)常用變量具體的參數解釋如下:
  • 【機器學習】樸素貝葉斯算法(Naive Bayes,NB)
    樸素貝葉斯是貝葉斯分類算法中的一種,是對貝葉斯的一個改進。樸素貝葉斯與貝葉斯顯著的不同之處在於,樸素貝葉斯進行了獨立性假設,假設各個特徵之間相互獨立不相關。因此,出現了樸素貝葉斯,對特徵值進行獨立性假設。這樣每個特徵值對結果的影響互不相關,則有下面兩個等價公式。這兩個公式中現有的概率均可以通過上面的表格計算得到。例如P(不帥|嫁)可以找到表格中所有「嫁」的一欄中「不帥」佔多少比重,表格顯示嫁有六種情況,在這六種情況中,不帥的有三個,因此 P(不帥|嫁)=3/6=0.5。其他數據同理,帶入即可計算出嫁與不嫁的概率。
  • 乾貨|非常通俗的樸素貝葉斯算法(Naive Bayes)
    閱讀目錄一、病人分類的例子二、樸素貝葉斯分類器的公式三、帳號分類的例子
  • 樸素貝葉斯算法——以20Newsgroups數據集為例
    樸素貝葉斯分類器是由英國數學家託馬斯·貝葉斯提出的。該模型使用概率統計的知識對樣本數據集進行分類,通過計算條件概率進行最終決策。樸素貝葉斯分類器的基本思想是,若在給定條件下,預測的某個樣本屬於某個類別的條件概率最大,則將該樣本判定為該類別。樸素貝葉斯分類器在數據集較大的情況下表現出較高的準確率,同時算法本身也較為簡單。