當前位置:
首頁 > 最新 > 基於深度學習和經典方法的文本分類

基於深度學習和經典方法的文本分類

更多騰訊海量技術文章,請關注云加社區:https://cloud.tencent.com/developer

作者:段石石

前言

文本分類應該是自然語言處理中最普遍的一個應用,例如文章自動分類、郵件自動分類、垃圾郵件識別、用戶情感分類等等,在生活中有很多例子,這篇文章主要從傳統和深度學習兩塊來解釋下我們如何做一個文本分類器。

文本分類方法

傳統的文本方法的主要流程是人工設計一些特徵,從原始文檔中提取特徵,然後指定分類器如LR、SVM,訓練模型對文章進行分類,比較經典的特徵提取方法如頻次法、tf-idf、互信息方法、N-Gram。

深度學習火了之後,也有很多人開始使用一些經典的模型如CNN、LSTM這類方法來做特徵的提取, 這篇文章會比較粗地描述下,在文本分類的一些實驗

傳統文本分類方法

這裡主要描述兩種特徵提取方法:頻次法、tf-idf、互信息、N-Gram。

頻次法

頻次法,顧名思義,十分簡單,記錄每篇文章的次數分布,然後將分布輸入機器學習模型,訓練一個合適的分類模型,對這類數據進行分類,需要指出的時,在統計次數分布時,可合理提出假設,頻次比較小的詞對文章分類的影響比較小,因此我們可合理地假設閾值,濾除頻次小於閾值的詞,減少特徵空間維度。

TF-IDF

TF-IDF相對於頻次法,有更進一步的考量,詞出現的次數能從一定程度反應文章的特點,即TF,而TF-IDF,增加了所謂的反文檔頻率,如果一個詞在某個類別上出現的次數多,而在全部文本上出現的次數相對比較少,我們認為這個詞有更強大的文檔區分能力,TF-IDF就是綜合考慮了頻次和反文檔頻率兩個因素。

互信息方法

互信息方法也是一種基於統計的方法,計算文檔中出現詞和文檔類別的相關程度,即互信息

N-Gram

基於N-Gram的方法是把文章序列,通過大小為N的窗口,形成一個個Group,然後對這些Group做統計,濾除出現頻次較低的Group,把這些Group組成特徵空間,傳入分類器,進行分類。

深度學習方法

基於CNN的文本分類方法

最普通的基於CNN的方法就是Keras上的example做情感分析,接Conv1D,指定大小的window size來遍歷文章,加上一個maxpool,如此多接入幾個,得到特徵表示,然後加上FC,進行最終的分類輸出。

基於CNN的文本分類方法,最出名的應該是2014 Emnlp的 Convolutional Neural Networks for Sentence Classi?cation,使用不同filter的cnn網路,然後加入maxpool, 然後concat到一起。

這類CNN的方法,通過設計不同的window size來建模不同尺度的關係,但是很明顯,丟失了大部分的上下文關係,Recurrent Convolutional Neural Networks for Text Classification,將每一個詞形成向量化表示時,加上上文和下文的信息,每一個詞的表示如下:

整個結構框架如下:

如針對這句話」A sunset stroll along the South Bank affords an array of stunning vantage points」,stroll的表示包括c_l(stroll),pre_word2vec(stroll),c_r(stroll), c_l(stroll)編碼A sunset的語義,而c_r(stroll)編碼along the South Bank affords an array of stunning vantage points的信息,每一個詞都如此處理,因此會避免普通cnn方法的上下文缺失的信息。

基於LSTM的方法

和基於CNN的方法中第一種類似,直接暴力地在embedding之後加入LSTM,然後輸出到一個FC進行分類,基於LSTM的方法,我覺得這也是一種特徵提取方式,可能比較偏向建模時序的特徵;

在暴力的方法之上,A C-LSTM Neural Network for Text Classification,將embedding輸出不直接接入LSTM,而是接入到cnn,通過cnn得到一些序列,然後吧這些序列再接入到LSTM,文章說這麼做會提高最後分類的准去率。

代碼實踐

語料及任務介紹

訓練的語料來自於大概31個新聞類別的新聞語料,但是其中有一些新聞數目比較少,所以取了數量比較多的前20個新聞類比的新聞語料,每篇新聞稿字數從幾百到幾千不等,任務就是訓練合適的分類器然後將新聞分為不同類別:

Bow

Bow對語料處理,得到tokens set:

然後,tokens set 以頻率閾值進行濾除,然後對每篇文章做處理來進行向量化:

最終就得到每篇文章的bow的向量,由於這塊的代碼是在我的筆記本上運行的,直接跑佔用內存太大,因為每一篇文章在token set中的表示是極其稀疏的,因此我們可以選擇將其轉為csr表示,然後進行模型訓練,轉為csr並保存中間結果代碼如下:

最後訓練模型代碼如下:

TF-IDF

TF-IDF和Bow的操作十分類似,只是在向量化使使用tf-idf的方法:

這兩類方法效果都不錯,都能達到98+%的準確率。

CNN

語料處理的方法和傳統的差不多,分詞之後,使用pretrain 的word2vec,這裡我遇到一個坑,我開始對我的分詞太自信了,最後模型一直不能收斂,後來向我們組博士請教,極有可能是由於分詞的詞序列中很多在pretrained word2vec裡面是不存在的,而我這部分直接丟棄了,所有可能存在問題,分詞添加了詞典,然後,對於pre-trained word2vec不存在的詞做了一個隨機初始化,然後就能收斂了,學習了!!!

載入word2vec模型和構建cnn網路代碼如下(增加了一些bn和dropout的手段):

另外一種網路結構,韓國人那篇文章,網路構造如下:

LSTM

由於我這邊的task是對文章進行分類,序列太長,直接接LSTM後直接爆內存,所以我在文章序列直接,接了兩層Conv1D+MaxPool1D來提取維度較低的向量表示然後接入LSTM,網路結構代碼如下:

CNN 結果:

C-LSTM 結果:

整個實驗的結果由於深度學習這部分都是在公司資源上跑的,沒有真正意義上地去做一些trick來調參來提高性能,這裡所有的代碼的網路配置包括參數都僅做參考,更深地工作需要耗費更多的時間來做參數的優化。

PS: 這裡發現了一個keras 1.2.2的bug, 在寫回調函數TensorBoard,當histogram_freq=1時,顯卡佔用明顯增多,M40的24g不夠用,個人感覺應該是一個bug,但是考慮到1.2.2而非2.0,可能後面2.0都優化了。

所有的代碼都在github上:tensorflow-101/nlp/text_classifier/scripts

總結和展望

在本文的實驗效果中,雖然基於深度學習的方法和傳統方法相比沒有什麼優勢,可能原因有幾個方面:

Pretrained Word2vec Model並沒有覆蓋新聞中切分出來的詞,而且比例還挺高,如果能用網路新聞語料訓練出一個比較精準的Pretrained Word2vec,效果應該會有很大的提升;

可以增加模型訓練收斂的trick以及優化器,看看是否有準確率的提升;

網路模型參數到現在為止,沒有做過深的優化。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 雲加社區 的精彩文章:

從零開始理解雲計算 Vol.2:雲計算的分類

TAG:雲加社區 |