上一次的介紹中咱們講解了情感分析的做用以及應用場景,技術難點以及百度Senta 系統對這些問題的解決方法以及核心技術。本次的介紹咱們則側重於實踐,即利用百度深度學習框架PaddlePaddle Fluid, 實戰Senta 系統。html
Senta 是百度開源的情感分析(Sentiment Analysis) 系統,項目的github 地址是(https://github.com/baidu/Senta),Senta 也爲百度AI 開放平臺(http://ai.baidu.com/tech/nlp/sentiment_classify)提供了情感傾向分析模塊,供用戶直接使用。python
這次咱們將講解如何本地構建Senta, 利用PaddlePaddle Fluid深度學習框架來實現情感分析模型的訓練和部署。git
運行本目錄下的程序示例須要使用PaddlePaddle Fluid v1.1/1.2 版本。github
# 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 版本。ide
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 中包含如下幾個模型:post
訓練數據格式是製表符分隔值(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 項目的說明文檔.