基于卷積神經(jīng)網(wǎng)絡CNN的文本分類原理和實戰(zhàn)
前言
本文介紹了CNN在NLP中的應用:文本分類鸟缕。
文本分類:是自然語言處理領域最活躍的研究方向之一,目前文本分類在工業(yè)界的應用場景非常普遍蜕径,從新聞的分類、商品評論信息的情感分類到微博信息打標簽輔助推薦系統(tǒng)败京,
卷積神經(jīng)網(wǎng)絡:主要用來做圖片分類兜喻、目標檢測等圖像相關的任務,
文本的預處理
文本的預處理赡麦,主要針對剔除無意義的符號信息朴皆,或其它的冗余信息。
在使用爬蟲獲取的語料集上可能存在一些html標簽泛粹,這些符號對于文本分類任務來說應該是冗余的無意義信息遂铡,可以剔除掉。
分詞:針對中文戚扳、日語等無空格切分字詞的語言忧便,還需要進行分詞處理,將一段文本序列劃分為合理的詞(字)序列帽借。
英文中天生的就有空格把每個詞匯分割開來珠增,所以不需要分詞操作,但由于英文存在時態(tài)砍艾、縮寫等問題蒂教,在預處理階段會有詞干提取、詞性還原脆荷、大小寫轉換等凝垛。去除停用詞。
shuffle打亂數(shù)據(jù)集
中文分詞的工具有非常多的方案蜓谋,我一般習慣于使用Python版的JieBa分詞工具包來進行分詞的操作梦皮,使用非常的簡單,使用pip install jieba就可以很方便的安裝該工具包桃焕,jieba常用的API可以查看GitHub主頁的實例剑肯。
分詞工具
- 中科院計算所NLPIRhttp://ictclas.nlpir.org/nlpir/
- ansj分詞器https://github.com/NLPchina/ansj_seg
- 哈工大的LTPhttps://github.com/HIT-SCIR/ltp
- 清華大學THULAChttps://github.com/thunlp/THULAC
- 斯坦福分詞器,Java實現(xiàn)的CRF算法观堂。https://nlp.stanford.edu/software/segmenter.shtml
- Hanlp分詞器让网,求解的是最短路徑。https://github.com/hankcs/HanLP
- 結巴分詞师痕,基于前綴詞典溃睹,生成句子中所有可能成詞所構成的有向無環(huán)圖 (DAG),采用動態(tài)規(guī)劃查找最大概率路徑, 找出基于詞頻的最大切分組合胰坟,對于未登錄詞因篇,采用了 HMM 模型,使用 Viterbi 算法。https://github.com/yanyiwu/cppjieba
- KCWS分詞器(字嵌入+Bi-LSTM+CRF)惜犀,本質上是序列標注铛碑。https://github.com/koth/kcws
- ZParhttps://github.com/frcchang/zpar/releases
- IKAnalyzerhttps://github.com/wks/ik-analyzer
中文分詞性能對比可以參考
文本的數(shù)值化
文本的數(shù)值化,即使用數(shù)字代表特定的詞匯虽界,因為計算機無法直接處理人類創(chuàng)造的詞匯汽烦。為了讓計算機能夠理解詞匯,我們需要將詞匯信息映射到一個數(shù)值化的語義空間中莉御,這個語義空間我們可以稱之為詞向量空間(詞向量模型)撇吞。
文本的數(shù)值化方式有很多種,例如:TF-IDF礁叔、BOW牍颈、One-Hot、分布式的表示方式(word2vec琅关、Glove)等煮岁。
一般常用的就是最經(jīng)典的word2vec工具,word2vec工具涣易,它是一種無監(jiān)督的學習模型画机,主要思想是“具有相似鄰近詞分布的中心詞之之間具有一定的語義相似度”),實現(xiàn)詞匯信息到語義空間的映射新症,最終獲得一個詞向量模型(每個詞匯對應一個指定維度的數(shù)組)步氏。
python 中使用word2vec工具很多,建議使用Gensim徒爹,通過pip install gensim安裝gensim工具包荚醒。
Gensim官網(wǎng):https://radimrehurek.com/gensim/models/word2vec.html
以上就是深度學習模型需要的數(shù)據(jù)格式的核心處理流程,在整個處理過程中樣本數(shù)據(jù)的處理流程如下圖所示:
文本分類模型
文本分類模型隆嗅,可以大體上分為基于傳統(tǒng)機器學習的文本分類模型界阁,基于深度學習的文本分類模型,目前基于深度學習模型的文本分類模型已經(jīng)成為了主流胖喳,下面基于CNN的文本分類模型铺董。
文本分類模型,從最經(jīng)典的2013年Kim提出Text-CNN模型開始禀晓,深度學習模型在文本分類任務上具有廣泛的應用。2016年Kim跳槽FaceBook后提出了工業(yè)界的文本分類模型的“新寵”—FastText坝锰。
本文選擇使用2013年Kim提出的Text-CNN模型作為文本分類模型粹懒,通過驗證實驗以及業(yè)界的共識,在文本分類任務中顷级,CNN模型已經(jīng)能夠取到比較好的結果凫乖,雖然在某些數(shù)據(jù)集上效果可能會比RNN稍差一點,但是CNN模型訓練的效率更高。所以帽芽,一般認為CNN模型在文本分類任務中是兼具效率與質量的理想模型删掀。
卷積神經(jīng)網(wǎng)絡(CNN)的特點:
sparse interaction(稀疏的交互)
parameter sharing(參數(shù)共享)
equivalent respresentation(等價表示)。
針對海量的文本多分類數(shù)據(jù)导街,也可以嘗試一下淺層的深度學習模型FastText模型披泪,該模型的分類效率更高。
Kim提出的經(jīng)典Text-CNN模型的整體網(wǎng)絡架構如圖所示搬瑰,
整個模型由四部分構成:輸入層款票、卷積層、池化層泽论、全連接層艾少。
輸入層(詞嵌入層):
Text-CNN模型的輸入層需要輸入一個定長的文本序列,我們需要通過分析語料集樣本的長度指定一個輸入序列的長度L翼悴,比L短的樣本序列需要填充(自己定義填充符)缚够,比L長的序列需要截取。最終輸入層輸入的是文本序列中各個詞匯對應的分布式表示鹦赎,即詞向量谍椅。
對于輸入層輸入的詞向量的表達方式,Text-CNN模型的作者Kim在論文中也分析了幾個變種的方式:
1.static(靜態(tài)詞向量)
使用預訓練的詞向量钙姊,即利用word2vec毯辅、fastText或者Glove等詞向量工具,在開放領域數(shù)據(jù)上進行無監(jiān)督的學習煞额,獲得詞匯的具體詞向量表示方式思恐,拿來直接作為輸入層的輸入,并且在TextCNN模型訓練過程中不再調整詞向量膊毁, 這屬于遷移學習在NLP領域的一種具體的應用胀莹。
2.non-static(非靜態(tài)詞向量)
預訓練的詞向量+ 動態(tài)調整 , 即拿word2vec訓練好的詞向量初始化, 訓練過程中再對詞向量進行微調。
3.multiple channel(多通道)
借鑒圖像中的RGB三通道的思想婚温, 這里也可以用 static 與 non-static 兩種詞向量初始化方式來搭建兩個通道描焰。
4.CNN-rand(隨機初始化)
指定詞向量的維度embedding_size后,文本分類模型對不同單詞的向量作隨機初始化, 后續(xù)有監(jiān)督學習過程中栅螟,通過BP的方向更新輸入層的各個詞匯對應的詞向量荆秦。
注意事項
1,CNN輸入層是大小固定的力图,所以對于不同文本步绸,找出最大的文本序列,其他的進行填補吃媒;
2瓤介,詞向量要經(jīng)過大規(guī)模數(shù)據(jù)進行訓練吕喘;
卷積層:
在NLP領域一般卷積核只進行一維的滑動,即卷積核的寬度與詞向量的維度等寬刑桑,卷積核只進行一維的滑動氯质。
在Text-CNN模型中一般使用多個不同尺寸的卷積核。卷積核的高度祠斧,即窗口值闻察,可以理解為N-gram模型中的N,即利用的局部詞序的長度梁肿,窗口值也是一個超參數(shù)蜓陌,需要在任務中嘗試,一般選取2-8之間的值吩蔑。
注意事項
1钮热,CNN在文本分類中,卷積核的寬度和詞向量的寬度一樣烛芬,只做一緯滑隧期;
2,CNN的卷積就是對應相乘求和赘娄,不需要翻轉仆潮,和信號處理卷積不同;
3遣臼,卷積層包括卷積操作和非線性激活函數(shù)性置,圖中f()函數(shù)就是非線性激活函數(shù);
4揍堰,卷積核有多個鹏浅,卷積核的參數(shù)是通過訓練得到的;
池化層:
在Text-CNN模型的池化層中使用了Max-pool(最大值池化)屏歹,即減少模型的參數(shù)隐砸,又保證了在不定長的卷基層的輸出上獲得一個定長的全連接層的輸入。
池化層除了最大值池化之外蝙眶,也有論文討論過 Top K最大值池化季希,即選取每一個卷積層輸出的Top k個最大值作為池化層的輸出。
卷積層與池化層在分類模型的核心作用就是提取特征幽纷,從輸入的定長文本序列中式塌,利用局部詞序信息,提取初級的特征友浸,并組合初級的特征為高級特征峰尝,通過卷積與池化操作,省去了傳統(tǒng)機器學習中的特征工程的步驟尾菇。
但TextCNN的一個明顯缺點就是境析,卷積、池化操作丟失了文本序列中的詞匯的順序派诬、位置信息劳淆,比較難以捕獲文本序列中的否定、反義等語義信息默赂。
全連接層:
全連接層的作用就是分類器沛鸵,原始的Text-CNN模型使用了只有一層隱藏層的全連接網(wǎng)絡,相當于把卷積與池化層提取的特征輸入到一個LR分類器中進行分類缆八。
CNN的結構:(卷積+非線性激活函數(shù)(Relu或tanh)+池化層)× n + 幾個全連接層曲掰;
深度CNN網(wǎng)絡:幾個卷積層+幾個全連接層
模型的效果評估與調優(yōu)
針對分類問題,一般可以使用準確率奈辰、召回率栏妖、F1值、混淆矩陣等指標奖恰,在文本多標簽分類中一般還會考慮標簽的位置加權等問題吊趾。
分類模型中的主要參數(shù):詞向量的維度、卷積核的個數(shù)瑟啃、卷積核的窗口值论泛、L2的參數(shù)、DropOut的參數(shù)蛹屿、學習率等屁奏。
這是在模型優(yōu)化的過程中需要重點關注的參數(shù)。此外错负,一般數(shù)據(jù)集的類別不均衡問題對模型的影響也是比較顯著的坟瓢,可以嘗試使用不同的方法,評估不同方案的模型效果湿颅。
TensorFlow實現(xiàn)CNN文本分類
github代碼载绿,預訓練詞向量下載地址:https://nlp.stanford.edu/projects/glove/, 我用的是400,000個詞匯的300維Glove詞向量油航。
下面是tensorflow中卷積和池化的函數(shù)崭庸,拿出來講解一下。
tf.nn.conv2d
tf.nn.conv2d(input,filter,strides,padding,use_cudnn_on_gpu=None,name=None)
參數(shù):
>>>>input:
一個Tensor谊囚,每個元素的數(shù)據(jù)類型必須為float32或float64怕享。
input的形狀:[batch, in_height, in_width, in_channels],
batch為訓練過程中每迭代一次迭代數(shù)據(jù)條數(shù)。
in_height, in_width分別為矩陣(圖片)的高和寬
in_channels為矩陣(圖片)的通道语盈,比如圖片可以有RGB三通道贝润。
即輸入:(句子個數(shù), 句子長度, embedding尺寸, 通道數(shù))
>>>>filter:
卷積核,也是一個Tensor跌帐,元素類型和input類型一致首懈。
filter的形狀:[filter_height, filter_width, in_channels, out_channels]
(其中out_channels也是該卷積核的個數(shù))。
參數(shù)分別為卷積核的高谨敛,寬究履,輸入的channels和輸出的channels
卷積核:(卷積核尺寸, embedding尺寸, 通道數(shù), 卷積核個數(shù))
>>>>stride:
步長,長度為4的list脸狸,元素類型為int最仑。表示每一維度滑動的步長。其中strides[0] = strides[3] = 1炊甲。strides[1]和strides[2]分別表示在hight和width方向的步長泥彤。
>>>>padding:
可選參數(shù)為"SAME", “VALID”。
SAME表示填充卿啡,VALID不填充吟吝。
>>>>use_cudnn_on_gpu:
bool類型,有True和False兩種選擇牵囤。
>>>>name:
此操作的名字
tf.nn.max_pool
池化
tf.nn.max_pool(value, ksize, strides, padding, name=None)
參數(shù)和卷積很類似:
value:需要池化的輸入爸黄,池化層通常跟在卷積層后面,所以輸入的shape依然是[batch, hei ght, width, channels]揭鳞。
ksize:池化窗口的大小炕贵,四維向量,一般是[1, height, width, 1]野崇,前后兩個1對應的是batch和channels称开,都不池化所以為1
strides:步長,和卷積一樣乓梨,前后都為1鳖轰,中間兩個分表表示窗口在每一個維度上滑動的步長,shape:[1, stride,stride, 1]
padding:‘VALID’ 或’SAME’
返回:一個Tensor扶镀,類型不變蕴侣,shape仍然是[batch, height, width, channels]這種形式
結論
CNN-static和CNN-non-static效果差不多,也就是說詞向量經(jīng)過預訓練的效果不錯臭觉。
關于模型的上線方案:
基于Java的:
請參考:https://www.ioiogoo.cn/2018/04/03/java%E8%B0%83%E7%94%A8keras%E3%80%81tensorflow%E6%A8%A1%E5%9E%8B/
2昆雀、基于Flask等python的web框架:
請參考:https://guillaumegenthial.github.io/serving.html
3、基于google官方的tensorflow Serving框架:
請參考:http://www.reibang.com/p/c1cd2d127ae2
阿里的基于容器部署的方案:https://yq.aliyun.com/articles/60894?spm=a2c4e.11153959.blogcont60601.11.815eea72lw2ij
補充資料
下面推薦一些拓展的資料蝠筑,感興趣的童鞋可以繼續(xù)深入研究狞膘。
各種文本分類模型的實例代碼:https://github.com/brightmart/text_classification
中文文本分類對比:https://github.com/Edward1Chou/Textclassification
CNN-RNN中文文本分類,基于TensorFlow :https://github.com/gaussic/text-classification-cnn-rnn
參考
- http://www.reibang.com/p/e6d71a9b1554
- 2014年基于CNN的文本分類模型:Convolutional Neural Networks for Sentence Classification
- 中文分詞性能對比可以:(https://blog.csdn.net/Mr_Yener/article/details/85636042)
- 基于TensorFlow的CNN文本分類的實現(xiàn):https://github.com/dennybritz/cnn-text-classification-tf
- Implementing a CNN for Text Classification in TensorFlow:http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/
- 文本分類方法對比:https://github.com/brightmart/text_classification
- CNN和RNN文本分類對比:https://github.com/gaussic/text-classification-cnn-rnn