朴素贝叶斯--文档分类
原文:http://ihoge.cn/2018/MultinomialNB.html
把文檔轉換成向量
TF-IDF是一種統計方法,用以評估一個詞語對于一份文檔的重要程度。
- TF表示詞頻, 即:詞語在一片文檔中出現的次數 ÷ 詞語總數
- IDF表示一個詞的逆向文檔頻率指數, 即:對(總文檔數目÷包含該詞語的文檔的數目)的商取對數 log(m/mi?in?m)log(m/mi?in?m)
基礎原理:詞語的重要性隨著它在文檔中出現的次數成正比例增加,但同時會隨著它在語料庫中出現的頻率呈反比下降。
sklearn中有包實現了把文檔轉換成向量的過程,首先把訓練用額語料庫讀入內存:
from time import time from sklearn.datasets import load_filest = time() news_train = load_files('code/datasets/mlcomp/379/train') print(len(news_train.data), "\n",len(news_train.target_names)) print("done in {} seconds".format(time() - t)) 13180 20 done in 6.034918308258057 secondsnews_train.data是一個數組,包含了所有文檔的文本信息。
news_train.target_names也是一個數組,包含了所有文檔的屬性類別,對應的是讀取train文件夾時,train文件夾下所有的子文件夾名稱。
該語料庫總共有13180個文檔,其中分成20個類別,接著需要轉換成由TF-IDF表達的權重信息構成向量。
from sklearn.feature_extraction.text import TfidfVectorizert = time() vectorizer = TfidfVectorizer(encoding = 'latin-1') X_train = vectorizer.fit_transform((d for d in news_train.data)) print("文檔 [{0}]特征值的非零個數:{1}".format(news_train.filenames[0] , X_train[0].getnnz())) print("訓練集:",X_train.shape) print("耗時: {0} s.".format(time() - t)) 文檔 [code/datasets/mlcomp/379/train/talk.politics.misc/17860-178992]特征值的非零個數:108 訓練集: (13180, 130274) 耗時: 3.740567207336426 s.TfidfVectorizer類是用來把所有的文檔轉換成矩陣,該矩陣每一行都代表一個文檔,一行中的每個元素代表一個對應的詞語的重要性,詞語的重要性由TF-IDF來表示。其fit_transform()方法是fit()和transform()的結合,fit()先完成語料庫分析,提取詞典等操作transform()把每篇文檔轉換為向量,最終構成一個矩陣,保存在X_train里。
程序輸出可以看到該詞典總共有130274個詞語,即每篇文檔都可以轉換成一個13274維的向量組。第一篇文檔中只有108個非零元素,即這篇文檔由108個不重復的單詞組成,在這篇文檔中出現的這108個單詞次的TF-IDF會被計算出來,保存在向量的指定位置。這里的到X_train是一個緯度為12180 x 130274的系數矩陣。
訓練模型
from sklearn.naive_bayes import MultinomialNBt = time() y_train = news_train.target clf = MultinomialNB(alpha=0.001) #alpga表示平滑參數,越小越容易造成過擬合;越大越容易欠擬合。 clf.fit(X_train, y_train)print("train_score:", clf.score(X_train, y_train)) print("耗時:{0}s".format(time() - t)) train_score: 0.9974203338391502 耗時:0.23757004737854004s # 加載測試集檢驗結果 news_test = load_files('code/datasets/mlcomp/379/test') print(len(news_test.data)) print(len(news_test.target_names)) 5648 20 # 把測試集文檔數學向量化 t = time() # vectorizer = TfidfVectorizer(encoding = 'latin-1') # 這里注意vectorizer這條語句上文已經生成執行,這里不可重復執行 X_test = vectorizer.transform((d for d in news_test.data)) y_test = news_test.targetprint("測試集:",X_test.shape) print("耗時: {0} s.".format(time() - t)) 測試集: (5648, 130274) 耗時: 1.64164400100708 s. import numpy as np from sklearn import metrics y_pred = clf.predict(X_test) print("Train_score:", clf.score(X_train, y_train)) print("Test_score:", clf.score(X_test, y_test))for i in range(10):r = np.random.randint(X_test.shape[0])if clf.predict(X_test[r]) == y_test[r]:print("√:{0}".format(r))else:print("X:{0}".format(r)) Train_score: 0.9974203338391502 Test_score: 0.9123583569405099 √:1874 √:2214 √:2579 √:1247 √:375 √:5384 √:5029 √:1951 √:4885 √:1980評價模型:
classification_report()查看查準率、召回率、F1
使用classification_report()函數查看針對每個類別的預測準確性:
from sklearn.metrics import classification_reportprint(clf) print("查看針對每個類別的預測準確性:") print(classification_report(y_test, y_pred, target_names = news_test.target_names)) MultinomialNB(alpha=0.001, class_prior=None, fit_prior=True) 查看針對每個類別的預測準確性:precision recall f1-score supportalt.atheism 0.90 0.92 0.91 245comp.graphics 0.80 0.90 0.84 298comp.os.ms-windows.misc 0.85 0.80 0.82 292 comp.sys.ibm.pc.hardware 0.81 0.82 0.81 301comp.sys.mac.hardware 0.90 0.92 0.91 256comp.windows.x 0.89 0.88 0.88 297misc.forsale 0.88 0.82 0.85 290rec.autos 0.93 0.93 0.93 324rec.motorcycles 0.97 0.97 0.97 294rec.sport.baseball 0.97 0.96 0.97 315rec.sport.hockey 0.97 0.99 0.98 302sci.crypt 0.96 0.95 0.96 297sci.electronics 0.91 0.85 0.88 313sci.med 0.96 0.96 0.96 277sci.space 0.95 0.97 0.96 305soc.religion.christian 0.93 0.96 0.94 293talk.politics.guns 0.90 0.96 0.93 246talk.politics.mideast 0.95 0.98 0.97 296talk.politics.misc 0.91 0.89 0.90 236talk.religion.misc 0.89 0.77 0.82 171avg / total 0.91 0.91 0.91 5648confusion_matrix混淆矩陣
通過confusion_matrix函數生成混淆矩陣,觀察每種類別別錯誤分類的情況。例如,這些被錯誤分類的文檔是被錯誤分類到哪些類別里。
from sklearn.metrics import confusion_matrixcm = confusion_matrix(y_test, y_pred) print(cm)# 第一行表示類別0的文檔被正確分類的由255個,其中有2、5、13個錯誤分類被分到了14、15、19類中了。 [[225 0 0 0 0 0 0 0 0 0 0 0 0 0 2 5 0 0 0 13][ 1 267 6 4 2 8 1 1 0 0 0 2 3 2 1 0 0 0 0 0][ 1 12 233 26 4 9 3 0 0 0 0 0 2 1 0 0 0 0 1 0][ 0 9 16 246 7 3 10 1 0 0 1 0 8 0 0 0 0 0 0 0][ 0 2 3 5 236 2 2 1 0 0 0 3 1 0 1 0 0 0 0 0][ 0 22 6 3 0 260 0 0 0 2 0 1 0 0 1 0 2 0 0 0][ 0 2 5 11 3 1 238 9 2 3 1 0 7 0 1 0 2 2 3 0][ 0 1 0 0 1 0 7 302 4 1 0 0 1 2 3 0 2 0 0 0][ 0 0 0 0 0 2 2 3 285 0 0 0 1 0 0 0 0 0 0 1][ 0 1 0 0 1 1 1 2 0 302 6 0 0 1 0 0 0 0 0 0][ 0 0 0 0 0 0 0 0 2 1 299 0 0 0 0 0 0 0 0 0][ 0 1 2 1 1 1 2 0 0 0 0 283 1 0 0 0 2 1 2 0][ 0 11 2 6 5 2 4 5 1 1 1 3 267 1 3 0 0 0 1 0][ 1 1 0 1 1 1 0 0 0 0 0 1 1 265 2 1 0 0 2 0][ 0 3 0 0 1 0 0 0 0 0 0 1 1 1 296 0 1 0 1 0][ 3 1 0 1 0 0 0 0 0 0 1 0 0 2 0 281 0 1 2 1][ 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 237 1 4 1][ 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 3 0 290 1 0][ 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 12 7 210 1][ 16 1 0 0 0 0 0 0 0 0 0 0 0 0 0 12 5 2 4 131]] %matplotlib inline from matplotlib import pyplot as pltplt.figure(figsize=(6, 6), dpi=120) plt.title('Confusion matrix of the classifier') ax = plt.gca() ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['bottom'].set_color('none') ax.spines['left'].set_color('none') ax.xaxis.set_ticks_position('none') ax.yaxis.set_ticks_position('none') ax.set_xticklabels([]) ax.set_yticklabels([]) plt.matshow(cm, fignum=1, cmap='gray') plt.colorbar();# 除對角線外,顏色越淺說明錯誤越多 # 上圖不直觀,重新畫圖 import random from pyecharts import HeatMapx_axis = np.arange(20) y_axis = np.arange(20) data = [[i, j, cm[i][j]] for i in range(20) for j in range(20)] heatmap = HeatMap() heatmap.add("混淆矩陣", x_axis, y_axis, data, is_visualmap=True,visual_text_color="#fff", visual_orient='horizontal') # heatmap.render() # heatmap
原文:http://ihoge.cn/2018/MultinomialNB.html
總結
以上是生活随笔為你收集整理的朴素贝叶斯--文档分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SVM支持向量机绘图
- 下一篇: PCA主成分分析+SVM实现人脸识别