詳細代碼已上傳到github: click mepython
摘 要: 情感分類是對帶有感情色彩的主觀性文本進行分析、推理的過程,即分析說話人的態度,推斷其所包含的情感類別.傳統機器學習在處理情感分類問題的時候一般是基於SVM、CRF、信息熵等傳統算法,其優點在於具備對多種特徵建模的能力,但要用人工標註的單個詞做爲特徵,而語料的不足每每就是性能的瓶頸.對句子進行情感分類的難處在於如何抽取到句子中與情感表達緊密相關的特徵,以人工標註的單個詞做爲特徵會忽略單詞所處的上下文語義信息,致使最終的分類效果不理想.爲了解決特徵抽取的難題,決定使用2018年Google提出的文本預訓練模型Bert(bidirectional encoder representations from transformer)來挑戰此次實驗中的情感多分類任務.Bert利用transformer超強的特徵抽取能力來學習詞語的雙向編碼表示,融合了上下文信息的詞語編碼能更好地進行情感決策.實驗結果也代表使用Bert的效果要比使用傳統算法的baseline好不少.git
關鍵詞: 情感分類;Bert;深度學習;單詞嵌入;字符嵌入github
短信在現代人的通信中被普遍使用,大量的微表情被用來替代幫助人們更好得表達本身的情感.然而,對於對微表情不熟悉的人來講,找到他想要的那個表情並非一件簡單的事(也許你能夠考慮下你的父母以及爺爺奶奶如何使用這些微表情).所以,頗有必要設計一個系統來基於短信的內容自動推薦合適的微表情.以前看Google I/O大會看到Google作的功能相似的一款產品,經過識別短信內容來提供給用戶以微表情替代情感相關文本的選項,感受頗有趣.這項任務其實就是NLP領域經典的情感分類問題,經過對短信做情感分析來爲其匹配一個最合適的微表情類.對這些短信進行情感分類的難點在於: 1.反諷問題,好比"你牛逼你上啊"; 2.領域相關的問題,"個人電腦散熱聲音很大"、"我家洗衣機聲音很大"這些極可能是差評,而"我家音響聲音很大"極可能就是好評; 3.網絡流行語也會影響情感分析,好比"給力"、"不明覺厲"、"累覺不愛"、"細思極恐"等,這些詞利用傳統的分詞通常都會被切開,並且會影響詞性標註,若是想避免只能加入人工干預,修改分詞的粒度和詞性標註的結果; 4.文本比較短,省略較嚴重,致使出現歧義或指代錯誤等,好比"咬死獵人的狗".傳統的統計+規則的方法不能很好得解決這些難點,須要引入深度學習強大的特徵抽取能力.2018年10月份,Google公司提出了NLP集大成者Bert模型[1] .這個模型既引入了lstm的雙向編碼機制同時還採用了GPT中的Transformer來作特徵抽取,具備很是強大的文本特徵提取能力,能學習到句子中潛在的句法和語義信息.除此以外,Bert基於character-level作embedding,就不存在分詞以及測試集包含訓練集中未出現詞的困擾了.這些優勢使得Bert可以比較好得解決情感分類問題中的一些難點,實驗基於Google開源的Bert預訓練好的中文模型作fine-tuning,最終的實驗效果要比採用傳統方法獲得得baseline好不少.算法
現有研究已經產生了可用於情感分析多項任務的大量技術,包括監督和無監督方法.在監督方法中,早期論文使用全部監督機器學習方法(如支持向量機、最大熵、樸素貝葉斯等)和特徵組合.無監督方法包括使用情感詞典、語法分析和句法模式的不一樣方法.大約十年前,深度學習成爲強大的機器學習技術,在不少應用領域產生了當前最優的結果,包括計算機視覺、語音識別、NLP 等.近期將深度學習應用到情感分析也逐漸變得流行.shell
Fig 1 The relationship between Bert and other deep learning modelsjson
圖1 Bert和其它深度學習模型之間的關係api
情感分析可劃分爲3種粒度:文檔粒度,句子粒度,短語粒度.此次的實驗任務主要是基於句子粒度來進行情感分類.Kim等人於2013年提出的CNN文本分類工做[2] ,成爲句子級情感分類任務的重要baseline之一.基本的lstm模型加上pooling策略構成分類模型,也一般用來作句子級情感分析的方法.Tang等人於2015年發表的工做[3] 使用兩種不一樣的RNN網絡,結合文本和主題進行情感分析.這幾年情感分析方面的突破主要都集中在深度學習領域,深度學習經過學習文本編碼表示來抽取文本深層次的特徵,解決傳統方法沒法很好地學習到文本特徵的難題.文獻[4,8]是從2013年至2018年期間深度學習在文本特徵抽取方面的幾項重大成就,其中包括Word2Vec,GLoVe,Transformer,ELMo,GPT.而本次實驗將採用Bert模型[1] 是這幾項工做的集大成者,如上圖1所示是Bert與ELMo等深度學習模型之間的關係,它結合了Transformer和ELMo的優勢,相比LSTM能較好地解決上下文長距離依賴問題,學習到了句子的句法特徵以及深層次的語義特徵,具備更強的特徵抽取能力.因爲時間比較緊,就沒有拿Bert與ELMo等其餘幾個深度學習模型做比較了,可是相比傳統的機器學習方法,效果要好不少.bash
由於Bert模型有一個很是重要的超參:輸入序列的長度,因此要先肯定訓練集和測試集中全部句子的最大長度,最終統計獲得最長句長爲293,所以將模型最大序列長設爲300比較合適.若是設得過小模型也不會報錯,可是會截斷輸入從而致使輸入信息缺失而不能準確預測所含情感.網絡
除此以外,訓練集中的數據並非均勻分佈的,也就是說各個表情所佔比重不同,對各表情聚類統計後發現數據傾斜很是大,最多的表情」心」出現了74788次,最少的表情」哈欠」僅出現了1355次.爲了讓Bert更好得學習到數據集上的特徵,減小數據樣本分佈不均衡的影響,須要調整不一樣表情類的損失權重.表情對應樣本數越多的,其權重值越小,而表情對應樣本數越少的,其權重值越大.具體作法是先統計各表情類的比重,將各表情類的損失值初始化爲對應比重,而後將比重最大和比重最小的2個表情類的對應損失值置換,再將次大和次小的損失值置換,以此循環直到全部表情類的損失值被置換.機器學習
實驗任務給出的數據集中不包含驗證集,須要從訓練集中劃分出一個驗證集.從訓練集每一類中隨機劃分出等數目的樣本,拼湊在一塊兒構成模型的驗證集,驗證集用於評估模型訓練過程當中的 F1 score,將F1 score最高的幾個模型保存到本地,後面預測的時候就能夠加載歷史保留下來的F1 score表現很好的chechpoint用於預測.
使用Bert模型的pytorch版本庫pytorch-pretrained-bert,中文預訓練模型使用Google Search 基於超大規模中文語料庫訓練的chinese_L-12_H-768_A-12,不過這個預訓練模型是提供給tensorflow使用的,pytorch不能直接加載使用,須要先作一個轉換.使用pip安裝好pytorch-pretrained-bert以後,在命令行下執行
export BERT_BASE_DIR=/path/to/bert/chinese_L-12_H-768_A-12 pytorch_pretrained_bert convert_tf_checkpoint_to_pytorch \ $BERT_BASE_DIR/bert_model.ckpt \ $BERT_BASE_DIR/bert_config.json \ $BERT_BASE_DIR/pytorch_model.bin
其中BERT_BASE_DIR爲下載解壓後的預訓練模型所在路徑.執行完成將在BERT_BASE_DIR路徑下生成名爲pytorch_model.bin的pytorch可用預訓練模型文件,此時對應路徑下bert_model.ckpt開頭的三個文件均可以刪除了,由於它們已集成到pytorch_model.bin中,對pytorch已經沒什麼用了.
學習率設置也很關鍵,學習率設置太大不容易收斂到最優值,學習率過小收斂太慢,效率過低.能夠在模型開始訓練逐漸增大學習率來加快收斂,當增大到一個閾值時就開始減少學習率,減緩梯度變化,讓模型更好地落入一個局部最優解.
baseline模型使用了傳統的機器學習來作,先使用tf-idf提取2000個特徵詞,而後每一條短信文本表示成這2000個詞表示的頻率向量,整個訓練集和測試集就被轉換成維度爲樣本數*特徵詞數的頻率矩陣.而後使用樸素貝葉斯分類器在頻率矩陣上進行訓練和預測.
實驗環境: python 3.6.7 configparser 3.7.4 numpy 1.15.4 tqdm 4.32.1 scikit-learn 0.20.2 torch 1.1.0 torchvision 0.3.0 tensorboradX 1.7 pytorch-pretrained-bert 0.6.2 cuda 9.0.176 cudnn 7.3.0 gpu型號: 雙核11G的Tesla K80(4塊) |
全部參數設置都寫進一個shell腳本以下
#! /usr/bin/env bash python sentiment_dev.py \ --data_dir '../input' \ --bert_model_dir '../input/pre_training_models/chinese_L-12_H-768_A-12' \ --output_dir '../output/models/' \ --checkpoint '../output/models/checkpoint-33426' \ --max_seq_length 300 \ --do_predict \ --do_lower_case \ --train_batch_size 60 \ --gradient_accumulation_steps 3 \ --predict_batch_size 15 \ --learning_rate 2e-5 \ --num_train_epochs 3
4.3 實驗結果其中data_dir爲訓練集、驗證集、測試集所在目錄.bert_model_dir爲Bert中文預訓練模型所在目錄.output_dir爲訓練模型保存目錄以及預測結果輸出目錄.checkpoint爲模型加載文件,經過指定的checkpoint來預測或者從指定checkpoint處開始訓練以節省訓練時間,若是想從新開始訓練則去除checkpoint這個參數.max_seq_len爲輸入序列的最大長度,由於數據集中最長句長爲293,因此這裏設爲300以確保能保留全部輸入文本的完整信息.do_predict表示預測,這個參數改成do_train則表示訓練.do_lower_case表示忽略大小寫,英文字母都轉換成小寫.train_batch_size爲一次送入訓練的樣本數目.gradient_accumulation_steps爲梯度累積次數,每gradient_accumulation_steps次梯度計算與反向傳播後更改一次學習率,並將梯度歸零,實際每次送入訓練的樣本數目爲train_batch_size/gradient_accumulation_steps個樣本.predict_batch_size爲一次預測的樣本數目.learning_rate爲學習率,num_train_epoches爲訓練集上的訓練輪數.
下圖2是提交在kaggle上的結果截圖,其中用紅色方框圈出來的結果是提交過的最好結果,這是在訓練集上訓練3輪的結果,test.predict-33426是在訓練集上訓練2輪半提早終止的結果,submission_2epoch是在訓練集上訓練2輪的結果.能夠看到訓練得越久最終的private score越高,代表訓練程度還不夠飽和,還有一些特徵沒有學習到,須要更深一步的訓練.可是訓練時耗太長了,沒來得及作更多輪的訓練做對比.baseline_nb是用第3章提到的baseline model獲得的結果,與Bert獲得的結果相差甚遠,Bert預測結果的F1 score差很少是baseline的10倍左右.終榜前提交的最好成績是0.18777,榜上排名12.
Fig 2 submission results of experiment on kaggle
圖2 實驗在kaggle上的提交結果
文本情感分類是NLP領域的一個經典問題,也是NLP領域的一個難題.本次實驗任務的最大挑戰在於它不是簡單地判別情感的好與壞,而是須要判別每一條短信中所蘊含的具體情感,而後給它匹配最合適的表情.然而標籤數據一共包含72類表情,有時候一條短信可能包含不止一種情感,人爲判斷會以爲能夠匹配多類表情,可是數據集中是每一條短信對應一個表情,這無疑給情感分類帶來巨大挑戰.Bert可能學習到了短信中的多種情感特徵,可是隻能給出一種表情,很容易與真實標籤不一致.所以Bert雖然在這個任務上的表現比baseline好不少,可是光看其在測試集上的F1 score仍是很低的.
本次實驗數據預處理的工做作得不多,只作了一些簡單的統計,沒有對數據進行清洗.訓練集中包含大量的非中文文本,而實驗中使用的是中文預訓練模型,對於非中文文本的編碼表示學習效果可能不太好,後續能夠引入混合多種語言文本的外部語料庫進行訓練,提高模型對非中文文本的特徵學習能力.
References:
[1] Jacob Devlin, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. Bert: pre-training of deepbidirectional transformers for language understanding. CoRR, 2018,abs/1810.04805.
[2] Yoon Kim. Convolutional neural networks for sentence classification. CoRR, 2014,abs/1408.5882.
[3] Duyu Tang, Bing Qin, Xiaocheng Feng, and Ting Liu. Target-dependent sentiment classificationwith long short term memory. CoRR,2015,abs/1512.01100.
[4] Tomas Mikolov, Kai Chen, Greg Corrado, and Jeffrey Dean. Efficient estimation of word represen-tations in vector space. arXiv preprint arXiv, 2013,1301.3781.
[5] Jeffrey Pennington, Richard Socher, and Christopher Manning. Glove: Global vectors for wordrepresentation. In: Proceedings of the 2014 conference on empirical methods in natural languageprocessing (EMNLP), 2014. 1532–1543.
[6] Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez,Łukasz Kaiser, and Illia Polosukhin. Attention is all you need. In: Advances in neural informationprocessing systems, 2017. 5998–6008.
[7] Matthew E. Peters, Mark Neumann, Mohit Iyyer, Matt Gardner, Christopher Clark, Kenton Lee,and Luke Zettlemoyer. Deep contextualized word representations. CoRR, 2018,abs/1802.05365.
[8] Alec Radford, Karthik Narasimhan, Tim Salimans, and Ilya Sutskever. Improving languageunderstanding by generative pre-training. URL https://s3-us-west-2. amazonaws. com/openai-assets/research-covers/languageunsupervised/language understanding paper. pdf, 2018.