情感傾向分析針對帶有主觀描述的中文文本,可自動判斷該文本的情感極性類別并給出相應的置信度。情感類型分為積極、消極、中性。情感傾向分析能夠幫助企業理解用戶消費習慣、分析熱點話題和危機輿情監控,為企業提供有力的決策支持。
上一次的介紹中我們講解了情感分析的作用以及應用場景,技術難點以及百度Senta?系統對這些問題的解決方法以及核心技術。本次的介紹我們則側重于實踐,即利用百度深度學習框架PaddlePaddle Fluid,?實戰Senta?系統。
Senta?是百度開源的情感分析(Sentiment Analysis)?系統,項目的github?地址是(https://github.com/baidu/Senta),Senta?也為百度AI?開放平臺(http://ai.baidu.com/tech/nlp/sentiment_classify)提供了情感傾向分析模塊,供用戶直接使用。
此次我們將講解如何本地構建Senta,?利用PaddlePaddle Fluid深度學習框架來實現情感分析模型的訓練和部署。
運行本目錄下的程序示例需要使用PaddlePaddle Fluid v1.1/1.2?版本。
使用pip?安裝最新穩定版
# Linux CPU
pip install paddlepaddle
# Linux GPU cuda9cudnn7
pip install paddlepaddle-gpu
# Linux GPU cuda8cudnn7
pip install paddlepaddle-gpu==1.1.0.post87
# Linux GPU cuda8cudnn5
pip install paddlepaddle-gpu==1.1.0.post85
更詳細的whl包列表也可以參見whl?包列表.
如果需要安裝最新的開發版,請按照安裝文檔中的說明更新PaddlePaddle Fluid?版本。
Senta?代碼結構
Senta?項目的代碼結構以及簡介如下,本文重點介紹如何利用FluidPython?API完成模型的構建和訓練,關于如何利用Fluid?C-API進行模型的在線部署,可以參考該項目的說明文檔。
Senta
├── C-API/?#?
模型預測C-API接口
├── data/?#?
數據集
│?? ├── test_data/
│?? │?? └── corpus.test
│?? ├── train_data/
│?? │?? └── corpus.train
│?? └── train.vocab
├── eval.sh???????????????#?
模型評價腳本
├── infer.sh?#?
模型預測腳本
├── nets.py?
?#?本例中涉及的各種網絡結構均定義在此文件中,│?#?若進一步修改模型結構,請查看此文件
├── README.md?#?
說明文檔
├── sentiment_classify.py?#?
情感傾向分析主函數,包括訓練、預估、預測│?#?部分
├── train.sh?#?
模型訓練腳本
└── utils.py?#?
定義通用的函數,例如加載詞典,讀入數據等
nets.py?中包含以下幾個模型:
??????????bow_net:Bow(Bag Of Words)?模型,是一個非序列模型。使用基本的全連接結構。
??????????cnn_net:淺層CNN?模型,是一個基礎的序列模型,能夠處理變長的序列輸入,提取一個局部區域之內的特征。
??????????gru_net:單層GRU?模型,序列模型,能夠較好地解序列文本中長距離依賴的問題。
??????????lstm_net:單層LSTM?模型,序列模型,能夠較好地解決序列文本中長距離依賴的問題。
??????????bilstm_net:雙向單層LSTM?模型,序列模型,通過采用雙向lstm結構,更好地捕獲句子中的語義特征。百度AI?平臺上情感傾向分析模塊采用此模型進行訓練和預測。
訓練數據格式是制表符分隔值(tsv)?的格式,每一行代表一條訓練數據,以制表符作為分割符分為兩個字段。第一個字段是情感傾向,取值為0?或1,分別代表消極和積極情感傾向;第二個字段是文本的內容。文本已經經過分詞處理,詞與詞之間用空格分隔。示例訓練樣本如下:
0?方向盤向左稍有偏斜- - - -?上四輪定位調整兩次OK?。價格80元,4S?要300多元,立馬和他說
0?
人非常多,團購的平日票,本來以為人會少點,沒想到人山人海。有些項目小孩不能玩,小孩對造浪池比較感興趣,其它真沒什么可玩的。
0?
環境口味我都很滿意,可是那服務態度還真不能讓人恭維!生意好也不能降低服務態度!味道再美味我消費的時候還要受氣的話我也不會再去消費了!
1?
國恥,不忘歷史。
?測試數據以同樣的方式進行分隔,但在情感類別標簽方面和訓練數據有一些差別。測試數據中情感傾向共有三類,取值為0, 1, 2,?分別代表消極,中性,積極。在模型的預測階段,我們利用模型輸出樣例為積極和消極的概率,如果用于二分類,只要積極的概率比消極的概率高,就歸入積極;而如果用于三分類,則在中間加入了中性,分類的依據是,樣例為積極的概率小于45%?則為消極,大于55%?則為積極,介于二者之間則為中性,用戶也可以根據需要調整中型情感的概率閾值。示例測試樣本如下所示:
2?空間是可以了,后面坐三個170斤的人也不嫌擠,但矮了點,后備箱給力
1?
滿分是10分的話,性價比給8.5分吧!綜合油耗偏高,如果開市區的就不太合算了。
0?
后排中間的突起太高,中間坐人不好放腳。
1?
一般,家用還可以。
因為深度學習模型的需要,需要把每一個詞對應地轉化為一個整數,為此要根據訓練數據構建一個詞典。而且還可以根據詞典對詞典的大小進行限制。這里使用的詞典文件格式非常簡單,每行代表詞典中的一個詞。以下是詞典的示例:
喜歡特臟兮兮
...
注:我們在data目錄下,提供了示例詞典數據,詳見data/train.vocab.
關于詞典構建的功能,參見utils.py中的prepare_data(data_path, word_dict_path, batch_size, mode)函數,詞典加載的功能,參見utils.py中的load_vocab(file_path)函數。
因為實際使用的數據比較大,github?項目中僅自帶了一份小的示例數據,如果需要使用自定義的數據,將訓練和測試需要用的語料處理成符合上述要求的格式,存放為data/train_data/corpus.train和data/test_data/corpus.test即可。
模型的訓練,評價和預測都集成在sentiment_classify.py文件里,默認使用的模型是bilstm_net雙向LSTM?模型。默認使用cpu?進行模型訓練,但還可以支持使用gpu,通過--use_gpu True打開。另外,訓練還支持并行,通過--is_parallel參數設置。
具體支持的參數可以通過python sentisentiment_classify.py --help查看。
python sentiment_classify.py \
???--train_data_path ./data/train_data/corpus.train \?#?
訓練數據路徑
???--word_dict_path ./data/train.vocab \?#?
詞典路徑
???--mode train \????# train
模式
???--model_path ./models?#?
模型保存路徑
使用GPU?的訓練腳本
export CUDA_VISIBLE_DEVICES=0,1?#?指定可用的GPU?序號
python sentiment_classify.py \
???--train_data_path ./data/train_data/corpus.train \??????#?
訓練數據路徑
???--word_dict_path ./data/train.vocab \?#?
詞典路徑
???--mode train \?# train
模式
???--model_path ./models?#?
模型保存路徑
???--use_gpu True?????????????????????????#?
使用GPU?訓練模型
???--is_parallel True?#?
使用并行
執行后可以看到如下的輸出:一共對訓練語料進行了10?次迭代,并且輸出了在測試數據集上的準確率和平均cost.
[train info]: pass_id: 0, avg_acc: 0.821615, avg_cost: 0.388542
[train info]: pass_id: 1, avg_acc: 0.960837, avg_cost: 0.122814
[train info]: pass_id: 2, avg_acc: 0.987280, avg_cost: 0.052349
[train info]: pass_id: 3, avg_acc: 0.994591, avg_cost: 0.024470
[train info]: pass_id: 4, avg_acc: 0.997796, avg_cost: 0.012553
[train info]: pass_id: 5, avg_acc: 0.998197, avg_cost: 0.008723
[train info]: pass_id: 6, avg_acc: 0.999599, avg_cost: 0.003929
[train info]: pass_id: 7, avg_acc: 0.999700, avg_cost: 0.002423
[train info]: pass_id: 8, avg_acc: 0.999900, avg_cost: 0.001672
[train info]: pass_id: 9, avg_acc: 0.999900, avg_cost: 0.001001
也可以直接使用目錄下的train.sh?根據需要進行修改。
python sentiment_classify.py \
???--test_data_path ./data/test_data/corpus.test \?#?
測試數據路徑
???--word_dict_path ./data/train.vocab \?#?
詞典路徑
???--mode eval \?# eval
模式
???--model_path ./models/epoch9/?#?
預測模型路徑
可以看到類似如下的輸出
[test info] model_path: ./models/epoch9/, class2_acc: 0.828402, class3_acc: 0.710000
說明模型能夠完成情感分類任務,只是因為示例數據集太小,過擬合比較明顯,在訓練數據集上準確率可以達到99.9%,?而測試數據集上的二分類準確率只有82.8%.?用戶可以通過使用自定義的更大的數據集,以及調整模型超參數以獲得更好的效果。
python sentiment_classify.py \
???--test_data_path ./data/test_data/corpus.test \?#?
測試數據路徑
???--word_dict_path ./data/train.vocab \??????????????????????#?
詞典路徑
???--mode infer \?# infer
模式
???--model_path ./models/epoch9/?#?
預測模型路徑
即可執行預測,可以得到類似如下的輸出
predict label: 0, pos_prob: 0.004343, neg_prob: 0.995657
predict label: 2, pos_prob: 0.798888, neg_prob: 0.201112
predict label: 0, pos_prob: 0.000564, neg_prob: 0.999436
predict label: 0, pos_prob: 0.024923, neg_prob: 0.975077
predict label: 2, pos_prob: 0.999526, neg_prob: 0.000474
predict label: 2, pos_prob: 0.994914, neg_prob: 0.005086
predict label: 0, pos_prob: 0.065424, neg_prob: 0.934576
predict label: 0, pos_prob: 0.000119, neg_prob: 0.999881
predict label: 0, pos_prob: 0.000709, neg_prob: 0.999291
predict label: 2, pos_prob: 0.986198, neg_prob: 0.013802
.......
可以觀察模型對于每一個樣例的預測結果和詳細情況。
上述的實驗中,使用的訓練和測試語料都已經經過分詞處理,并且都被人工標了情感極性標簽,用于訓練和評價模型的能力,但是在實際應用中,面對的語料都是生語料,比如線上商品的評價信息,并沒有經過分詞之類的處理。這種情況下需要預先對語料進行加工處理,百度也開源了詞法分析提供工具LAC。
在本工程目錄的C-API目錄下,就有調用LAC?進行分詞并且結合上述模型完成情感分析所需的文件,將分詞處理和情感分析集成在一起。具體的使用方法,可以進一步參考Senta?項目的說明文檔,?以及LAC?項目的說明文檔.