向AI轉型的程式設計師都關注了這個號👇👇👇
機器學習AI算法工程 公眾號: datayx
文本分類任務是一個經久不衰的課題,其應用包括垃圾郵件檢測、情感分析等。
傳統機器學習的做法是先進行特徵工程,構建出特徵向量後,再將特徵向量輸入各種分類模型(貝葉斯、SVM、神經網絡等)進行分類。
隨著深度學習的發展以及RNN、CNN的陸續出現,特徵向量的構建將會由網絡自動完成,因此我們只要將文本的向量表示輸入到網絡中就能夠完成自動完成特徵的構建與分類過程。
就分類任務而言,CNN比RNN更為合適。CNN目前在圖像處理方向應用最為廣泛,在文本處理上也有一些的應用。本文將參考Denny Britz的WILDML教程
IMPLEMENTING A CNN FOR TEXT CLASSIFICATION IN TENSORFLOW
http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/
來設計一個簡單的CNN,並將其應用於中文垃圾郵件檢測任務。
1.1神經網絡基礎知識
如果你對深度學習或RNN、CNN等神經網絡並不太熟悉,請先移步至這裡
http://www.wildml.com/
尋找相關文章進行精讀,這個博主寫的每一篇文章都很好,由淺至深,非常適合入門。
1.2如何將CNN運用到文本處理
參考understanding-convolutional-neural-networks-for-nlp
http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/
1.3CNN網絡結構和實現方法(必讀)
此博文中的CNN網絡結構和實現方法絕大部分是參考了 IMPLEMENTING A CNN FOR TEXT CLASSIFICATION IN TENSORFLOW 這篇文章的,CNN的結構和實現細節在這篇文章均有詳述。
2 訓練數據
2.1 中文垃圾郵件數據集
說明:對TREC06C進行了簡單的清洗得到,以utf-8格式存儲
完整代碼 數據集下載地址:
1、轉發本文至朋友圈
2、關注微信公眾號 datayx 然後回復 文本分類 即可獲取。
2.2垃圾郵件
spam_5000.utf8
3 預處理
3.1輸入
上述兩個文件 ( spam_5000.utf8 ham_5000.utf8)
embedding_dim (word embedding的維度, 即用多少維度的向量來表示一個單詞)
3.2 輸出:
max_document_length (最長的郵件所包含的單詞個數)
x (所有郵件的向量表示, 維度為[所有郵件個數,max_doument_length, embedding_dim])
y (所有郵件對應的標籤,[0, 1]表示正常郵件,[1, 0]表示垃圾郵件,y的維度為[所有郵件個數, 2])
3.3 主要流程:
3.3.1 過濾字符
為了分詞的方便,示例程序中去除了所有的非中文字符,你也可以選擇保留標點符號,英文字符,數字等其他字符,但要在分詞時進行一定的特殊處理
3.3.2 分詞
為了訓練Word2Vec 模型,需要先對訓練文本進行分詞。這裡為了方便起見,直接對每個中文字符進行分隔,即最後訓練處的word2vec 的向量是對字的embedding, 效果也比較不錯
3.3.3 對齊
為了加快網絡的訓練過程,需要進行批量計算,因此輸入的訓練樣本需要進行對齊(padding)操作,使得其維度一致。這裡的對齊就是把所有的郵件長度增加到max_document_length (最長的郵件所包含的單詞個數),空白的位置用一個指定單詞進行填充(示例程序中用的填充單詞為」PADDING」)
3.3.4 訓練word2vec
在對文本進行分詞和對齊後,就可以訓練處word2vec模型了,具體的訓練過程不在此闡述,程序可以參考項目文件中的word2vec_helpers.py。
4 定義CNN網絡與訓練步驟
4.1 網絡結構
此博文中的CNN網絡結構和實現方法絕大部分是參考了 IMPLEMENTING A CNN FOR TEXT CLASSIFICATION IN TENSORFLOW 這篇文章的,CNN的結構和實現細節在這篇文章均有詳述。重複的地方不再說明,主要說說不同的地方。
那篇文章中實現的CNN是用於英文文本二分類的,並且在卷積之前,有一層embedding層,用於得到文本的向量表示。
而本博文中實現的CNN在上面的基礎上略有修改,用於支持中文文本的分類。CNN的結構的唯一變化是去掉了其中的embedding層,改為直接將word2vec預訓練出的embedding向量輸入到網絡中進行分類。
網絡結構圖如下圖所示:
4.2 訓練步驟
在預處理階段得到了x和y, 接下來將x 和 y 按照一定比例分成訓練集train_x, train_y和測試集dev_x, dev_y。
接著按照batch_size分批將train_x輸入至網絡TextCNN中進行訓練,經過三個卷積層的卷積和max-pool之後,合併得到一個向量,這個向量代表了各個卷積層學到的關於訓練數據的某些特徵,最後將這個向量輸入到一個單層的神經網絡並用softmax分類,得到最終的分類結果,計算損失(交叉熵)並開始後向傳播,執行批量梯度下降來更新網絡參數。
5 結果
準確率:
誤差:
因為數據集並沒有標準的訓練集和測試集,本文只是按照0.1的比例進行了簡單的分割,且並沒有對一些重複的文檔進行篩選,所以準確率能夠達到99%左右。如果用比較標準的數據集,並加入交叉驗證等方法,相信準確率會降低一些,但相信準確率仍能夠超過絕大部分用傳統機器學習的方法寫出的分類器。
閱讀過本文的人還看了以下:
《21個項目玩轉深度學習:基於TensorFlow的實踐詳解》完整版PDF+附書代碼
Machine Learning Yearning 中文翻譯稿
深度學習500問,輕鬆掌握從基礎到進階(附答案)
全球AI挑戰-場景分類的比賽源碼(多模型融合)
CNN-RNN中文文本分類,基於TensorFlow 實現
不斷更新資源
深度學習、機器學習、數據分析、python
搜索公眾號添加: datayx
長按圖片,識別二維碼,點關注
深度學習500問
Batch_Size 值如何選擇?
假如每次只訓練一個樣本,即 Batch_Size = 1。線性神經元在均方誤差代價函數的錯誤面 是一個拋物面,橫截面是橢圓。對於多層神經元、非線性網絡,在局部依然近似是拋物面。此 時,每次修正方向以各自樣本的梯度方向修正,橫衝直撞各自為政,難以達到收斂。
既然 Batch_Size 為全數據集或者 Batch_Size = 1 都有各自缺點,可不可以選擇一個適中的 Batch_Size 值呢?
此時,可採用批梯度下降法(Mini-batches Learning)。因為如果數據集足夠充分,那麼用 一半(甚至少得多)的數據訓練算出來的梯度與用全部數據訓練出來的梯度是幾乎一樣的。