使用多項式朴素貝葉斯對文檔進行分類


原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/12832908.html

 

過程划分

  1. 基於分詞的數據准備,包括分詞、單詞權重計算、去掉停用詞;
  2. 應用朴素貝葉斯分類進行分類,首先通過訓練集得到朴素貝葉斯分類器,然后將分類器應用於測試集,並與實際結果做對比,最終得到測試集的分類准確率。

 

導入文檔

參考 https://github.com/cystanford/text_classification/tree/master/text%20classification,下載后將整個目錄導入工程目錄即可

 

准備數據

import os

import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB


def cut_words(file_path):
    """
    對文本進行切詞
    :param file_path: txt文本路徑
    :return: 用空格分詞的字符串
    """
    text_with_spaces = ''
    with open(file_path, 'r', encoding='gb18030') as f:
        text = f.read()
    textcut = jieba.cut(text)
    for word in textcut:
        text_with_spaces += word + ' '
    return text_with_spaces


def load_file(file_dir, label):
    """
    將路徑下的所有文件加載
    :param file_dir: 保存txt文件目錄
    :param label: 文檔標簽
    :return: 分詞后的文檔列表和標簽
    """
    file_list = os.listdir(file_dir)
    words_list = []
    labels_list = []
    for file in file_list:
        file_path = file_dir + '/' + file
        words_list.append(cut_words(file_path))
        labels_list.append(label)
    return words_list, labels_list


# 訓練數據
train_words_list1, train_labels1 = load_file('text_classification/train/女性', '女性')
train_words_list2, train_labels2 = load_file('text_classification/train/體育', '體育')
train_words_list3, train_labels3 = load_file('text_classification/train/文學', '文學')
train_words_list4, train_labels4 = load_file('text_classification/train/校園', '校園')

train_words_list = train_words_list1 + train_words_list2 + train_words_list3 + train_words_list4
train_labels = train_labels1 + train_labels2 + train_labels3 + train_labels4

# 測試數據
test_words_list1, test_labels1 = load_file('text_classification/test/女性', '女性')
test_words_list2, test_labels2 = load_file('text_classification/test/體育', '體育')
test_words_list3, test_labels3 = load_file('text_classification/test/文學', '文學')
test_words_list4, test_labels4 = load_file('text_classification/test/校園', '校園')

test_words_list = test_words_list1 + test_words_list2 + test_words_list3 + test_words_list4
test_labels = test_labels1 + test_labels2 + test_labels3 + test_labels4

 

對文檔進行分詞

在准備階段里,最重要的就是分詞。在中文文檔中,最常用的是 jieba 包。jieba 包中包含了中文的停用詞 stop words 和分詞方法。

e.g.

import jieba
word_list = jieba.cut(text)

英文文檔和中文文檔所使用的分詞工具不同。在英文文檔中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用詞 stop words、分詞和標注方法。

e.g.

import nltk
# 分詞
word_list = nltk.word_tokenize(text)
# 標注單詞的詞性
nltk.pos_tag(word_list) 

 

加載停用詞表

with open('text_classification/stop/stopword.txt', 'r', encoding='utf-8') as f:
    stop_words = f.read()
# 列表頭部處理
stop_words = stop_words.encode('utf-8').decode('utf-8-sig')
# 根據分隔符分隔
stop_words = stop_words.split('\n')

 

計算單詞的權重

# 計算單詞權重
tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)

train_features = tf.fit_transform(train_words_list)
test_features = tf.transform(test_words_list)

Note: 

max_df 參數用來描述單詞在文檔中的最高出現率。假設 max_df=0.5,代表一個單詞在 50% 的文檔中都出現過了,那么它只攜帶了非常少的信息,因此就不作為分詞統計。

一般很少設置 min_df,因為 min_df 通常都會很小。

 

生成朴素貝葉斯分類器

將特征訓練集的特征空間 train_features,以及訓練集對應的分類 train_labels 傳遞給貝葉斯分類器 clf,它會自動生成一個符合特征空間和對應分類的分類器。

這里采用的是多項式貝葉斯分類器,其中 alpha 為平滑參數。為什么要使用平滑呢?因為如果一個單詞在訓練樣本中沒有出現,這個單詞的概率就會被計算為 0。但訓練集樣本只是整體的抽樣情況,不能因為一個事件沒有觀察到,就認為整個事件的概率為 0。為了解決這個問題,需要做平滑處理。

當 alpha=1 時,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,來統計沒有出現過的單詞的概率。這樣當訓練樣本很大的時候,加 1 得到的概率變化可以忽略不計,也同時避免了零概率的問題。

當 0<alpha<1 時,使用的是 Lidstone 平滑。對於 Lidstone 平滑來說,alpha 越小,迭代次數越多,精度越高。可以設置 alpha 為 0.001。

clf = MultinomialNB(alpha=0.001)

 

使用生成的分類器做預測

clf.fit(train_features, train_labels)

 

計算准確率

# score: 0.91
print('score:', clf.score(test_features, test_labels))

 

Reference

https://time.geekbang.org/column/article/79762

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM