樸素貝葉斯分類
使用場景:文字分類、情感分析和垃圾郵件識別。其中情感分析和垃圾郵件識別都是通過文字來進行判斷,樸素貝葉斯也常用於自然語言處理 NLP 的工具。
sklearn 機器學習包
提供了 3 個樸素貝葉斯分類演算法,分別是高斯樸素貝葉斯(GaussianNB)、多項式樸素貝葉斯(MultinomialNB)和伯努利樸素貝葉斯(BernoulliNB)。
- 高斯樸素貝葉斯:特徵變數是連續變數,符合高斯分佈,比如說人的身高,物體的長度。
- 多項式樸素貝葉斯:特徵變數是離散變數,符合多項分佈,在文件分類中特徵變數體現在一個單詞出現的次數,或者是單詞的 TF-IDF 值等。
- 伯努利樸素貝葉斯:特徵變數是布林變數,符合 0/1 分佈,在文件分類中特徵是單詞是否出現。
TF-IDF 值(Term Frequency 和 Inverse Document Frequency)
- 詞頻 TF 計算了一個單詞在文件中出現的次數,它認為一個單詞的重要性和它在文件中出現的次數呈正比。
- 逆向文件頻率 IDF,是指一個單詞在文件中的區分度。它認為一個單詞出現在的文件數越少,就越能通過這個單詞把該文件和其他文件區分開。IDF 越大就代表該單詞的區分度越大。
TF-IDF 實際上是詞頻 TF 和逆向文件頻率 IDF 的乘積。找到 TF 和 IDF 取值都高的單詞作為區分,即這個單詞在一個文件中出現的次數多,同時又很少出現在其他文件中。這樣的單詞適合用於分類。
文件分類步驟:
- 基於分詞的資料準備,包括分詞、單詞權重計算、去掉停用詞;
- 應用樸素貝葉斯分類進行分類,首先通過訓練集得到樸素貝葉斯分類器,然後將分類器應用於測試集,並與實際結果做對比,最終得到測試集的分類準確率。
模組 1:對文件進行分詞
在英文文件中,最常用的是 NTLK 包
import nltk
word_list = nltk.word_tokenize(text) #分詞
nltk.pos_tag(word_list) #標註單詞的詞性
在中文文件中,最常用的是 jieba 包
import jieba
word_list = jieba.cut (text) #中文分詞
模組 2:載入停用詞表
需要自己讀取停用詞表檔案,從網上可以找到中文常用的停用詞儲存在 stop_words.txt,然後利用 Python 的檔案讀取函式讀取檔案,儲存在 stop_words 陣列中。
stop_words = [line.strip().decode('utf-8') for line in io.open('stop_words.txt').readlines()]
模組 3:計算單詞的權重
建立 TfidfVectorizer 類,然後使用 fit_transform 方法進行擬合,得到 TF-IDF 特徵空間 features,可以理解為選出來的分詞就是特徵。
max_df 引數用來描述單詞在文件中的最高出現率。假設 max_df=0.5,代表一個單詞在 50% 的文件中都出現過了,那麼它只攜帶了非常少的資訊,因此就不作為分詞統計。一般很少設定 min_df,因為 min_df 通常都會很小。
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
features = tf.fit_transform(train_contents)
模組 4:生成樸素貝葉斯分類器
alpha 為平滑引數,避免某個單詞在訓練樣本中沒有出現,導致概率被計算成0。
當 alpha=1 時,使用的是 Laplace 平滑。Laplace 平滑就是採用加 1 的方式,來統計沒有出現過的單詞的概率。這樣當訓練樣本很大的時候,加 1 得到的概率變化可以忽略不計,也同時避免了零概率的問題。
當 0<alpha<1 時,使用的是 Lidstone 平滑。對於 Lidstone 平滑來說,alpha 越小,迭代次數越多,精度越高。我們可以設定 alpha 為 0.001。
# 多項式貝葉斯分類器
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
模組 5:使用生成的分類器做預測
首先得到測試集的特徵矩陣。方法是用訓練集的分詞建立一個 TfidfVectorizer 類,使用同樣的 stop_words 和 max_df,然後用這個 TfidfVectorizer 類對測試集的內容進行 fit_transform 擬合,得到測試集的特徵矩陣 test_features。
test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
test_features=test_tf.fit_transform(test_contents)
然後用訓練好的分類器對新資料做預測。方法是使用 predict 函式,傳入測試集的特徵矩陣 test_features,得到分類結果 predicted_labels。predict 函式做的工作就是求解所有後驗概率並找出最大的那個。
predicted_labels=clf.predict(test_features)