利用朴素贝叶斯进行新闻文本分类
初探文本分類,本文使用的數據是5000條中文新聞文本數據,目的是使用樸素貝葉斯算法,對中文新聞文本進行分類預測。流程如下:
文本數據載入及清洗
搜狗新聞數據源:http://www.sogou.com/labs/resource/ca.php
我們從搜狗下載的數據是類似XML的帶標簽對的數據,因此需要使用正則表達式或者BeautifulSoup等工具處理為dataframe格式,如下圖,大家通過網絡爬蟲獲取的數據處理方法也類似。
文本數據提取這里就不贅述了,下面直接讀入處理后的csv文件
import pandas as pd import jieba data = pd.read_table('news_data/news_data.txt')把數據集分為訓練集和測試集
sk-learn庫中train_test_split函數可以把數據集隨機劃分為訓練集和測試集,訓練集用于模型訓練,測試集用于檢驗模型的優劣,random_state參數是指定隨機種子。
from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(data['新聞內容'], data['類別'], random_state=1)中文分詞
我們使用jieba庫進行分詞,并以空格把分詞連成字符串。
def fenci(train_data):words_df = train_data.apply(lambda x:' '.join(jieba.cut(x)))return words_dfx_train_fenci = fenci(x_train) x_train_fenci[:5]分詞后的數據如下:
3186 中新網 上海 6 月 1 4 日電 ( 記者 于俊 ) 今年 的 父親節 , 人們 可 通過... 632 目前 正值 中 報 發布 之際 , 多家 券商 認為 , 上半年 銀行 整體 利潤 增速 下... 577 作為 中非 合作 論壇 的 重要 分 論壇 之一 , 中 非金融 合作 論壇 將 于 1 3... 2406 雅虎 體育訊 北京 時間 7 月 3 日 下午 , 炎炎夏日 中 山東 球迷 終于 迎來... 4686 歐萊雅集團 的 藥妝 品牌 理膚泉 ( 右圖 ) 和 薇 姿 ( 左圖 ) 。 資料 圖... Name: 新聞內容, dtype: object引入停用詞
infile = open("stopwords.txt",encoding='utf-8') stopwords_lst = infile.readlines() stopwords = [x.strip() for x in stopwords_lst]文本特征提取(詞庫表示法)
CountVectorizer旨在通過計數來將一個文檔轉換為向量。當不存在先驗字典時,Countvectorizer作為Estimator提取詞匯進行訓練,并生成一個CountVectorizerModel用于存儲相應的詞匯向量空間。該模型產生文檔關于詞語的稀疏表示。下面舉一個例子示范:
#用于轉詞向量的語料 yuliao = ['dog cat fish dog dog dog','cat eat fish','i like eat fish']#sklearn庫CountVectorizer轉詞向量 from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer() vector = cv.fit_transform(yuliao) vector.todense()轉換后的矩陣為
matrix([[1, 4, 0, 1, 0],[1, 0, 1, 1, 0],[0, 0, 1, 1, 1]], dtype=int64)接下來我們看下提取到的特征分別是
#提取到的文本特征 cv.vocabulary_得到的文本特征
{'cat': 0, 'dog': 1, 'eat': 2, 'fish': 3, 'like': 4}從上面的例子可以看出,語料中每個詞作為一個特征,詞頻數作為特征的值,如第一句中dog出現了4次,因此特征值為4。下面我們使用CountVectorizer把分詞后的新聞文本轉為向量。sklearn庫中可以指定stopwords,我們把之前準備好的停用詞表穿進去就好,這樣我們的文本特征提取就做好啦。
vectorizer = CountVectorizer(stop_words=stopwords, max_features=5000) vectorizer.fit(x_train_fenci)機器學習建模
這里我們使用樸素貝葉斯分類器,關于樸素貝葉斯算法,劉建平的博客寫得非常不錯,我就不再花時間整理啦,給大家推薦一波https://www.cnblogs.com/pinard/p/6069267.html
from sklearn.naive_bayes import MultinomialNB classifier = MultinomialNB() #模型訓練 classifier.fit(vectorizer.transform(x_train_fenci), y_train) #使用訓練好的模型進行預測 classifier.score(vectorizer.transform(fenci(x_test)), y_test)得到的準確率為
0.80479999999999996預測的準確率是80.5%,棒棒噠
文本特征提取(TF-IDF)
TF-IDF(term frequency–inverse document frequency),詞頻-逆文件頻率。
是一種用于資訊檢索與資訊探勘的常用加權技術。TF-IDF是一種統計方法,用以評估一字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降
一個詞語在一篇文章中出現次數越多, 同時在所有文檔中出現次數越少, 越能夠代表該文章.
下面直接給出一個詞x的IDF的基本公式如下:
IDF(x)=lg?NN(x)IDF(x)= \lg {\frac{N}{N(x)}}IDF(x)=lgN(x)N? 其中,N代表語料庫中文本的總數,而N(x)代表語料庫中包含詞x的文本總數
TF?IDF(x)=TF(x)?IDF(x)TF?IDF(x)=TF(x)?IDF(x)TF?IDF(x)=TF(x)?IDF(x) 其中TF(x)指詞x在當前文本中的詞頻
詞庫表示法的缺點:一些普遍出現的詞,詞頻較高,看起來似乎是更重要的特征,但因為這個詞普遍出現,這個詞可能不是非常的重要。如果我們的向量化特征僅僅用詞頻表示就無法反應這一點。因此我們需要進一步的預處理來反應文本的這個特征,而這個預處理就是TF-IDF。
用scikit-learn進行TF-IDF預處理
from sklearn.feature_extraction.text import TfidfVectorizer #使用tf-idf把文本轉為向量 tv = TfidfVectorizer(stop_words=stopwords, max_features=5000, lowercase = False) tv.fit(x_train_fenci) #模型訓練 classifier.fit(tv.transform(fenci(x_train)), y_train) #利用訓練好的模型測試 classifier.score(tv.transform(fenci(x_test)), y_test)得到的準確率為
0.81599999999999995可以看出使用TF-IDF預處理后,得到的預測準確率有了明顯的提高。
TF-IDF是非常常用的文本挖掘預處理基本步驟,使用了IF-IDF并標準化以后,我們就可以使用各個文本的詞特征向量作為文本的特征,進行分類或者聚類分析。
N-gram模型
在樸素貝葉斯算法中,為了避免維度災難,有一個大膽的假設,即X的n個維度之間相互獨立:
P(X1=x1,X2=x2,...Xn=xn∣Y=Ck)=P(X1=x1∣Y=Ck)P(X2=x2∣Y=Ck)...P(Xn=xn∣Y=Ck)P(X_1=x_1,X_2=x_2,...X_n=x_n|Y=C_k)=P(X_1=x_1|Y=C_k)P(X_2=x_2|Y=C_k)...P(X_n=x_n|Y=C_k)P(X1?=x1?,X2?=x2?,...Xn?=xn?∣Y=Ck?)=P(X1?=x1?∣Y=Ck?)P(X2?=x2?∣Y=Ck?)...P(Xn?=xn?∣Y=Ck?)
這個假設下,條件分布大大的簡化了,但是這也可能帶來預測的不準確性。n個維度相互獨立,就是完全沒有考慮上下文語境,把每個詞拆開單獨看,這么看的話,貓吃魚、魚吃貓得到的特征向量是完全一樣的。
N-gram模型就是假設XnX_nXn?與附近n個詞是相關的,比如當n=(1,2)時,貓吃魚提取到的特征就是[‘貓’,‘吃’,‘魚’,‘貓吃’,‘吃魚’],為了平衡計算量和上下文關系,N一般取2或者3。樸素貝葉斯n個維度之間完全相互獨立的假設,就是N-gram的n=1時的情況
#轉詞向量 tv_2gram = TfidfVectorizer(stop_words=stopwords, max_features=5000, ngram_range=(1,2),lowercase = False) tv_2gram.fit(x_train_fenci) #訓練模型 clf_2gram = MultinomialNB() clf_2gram.fit(tv_2gram.transform(fenci(x_train)), y_train) #預測 clf_2gram.score(tv_2gram.transform(fenci(x_test)), y_test)得到的準確率為
0.81679999999999997可以看出,指定N-gram模型n=2時,增加了附近2個詞的關聯,預測的準確率又上升了一丟丟,繼續加油~
總結
以上是生活随笔為你收集整理的利用朴素贝叶斯进行新闻文本分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 仿《雷霆战机》飞行射击手游开发--子弹、
- 下一篇: 前端之ps切片