上一篇《AI Challenger 2018 進行時》文尾我們提到 AI Challenger 官方已經在 GitHub 上提供了多個賽道的 Baseline: AI Challenger 2018 Baseline ,其中文本挖掘相關的3個主賽道均有提供,非常適合用來學習:英中文本機器翻譯的 baseline 就直接用了Google官方基於Tensorflow實現的Tensor2Tensor跑神經網路機器翻譯Transformer模型,這個思路是我在去年《AI Challenger 2017 奇遇記》裏的終極方案,今年已成標配;細粒度用戶評論情感分析提供了一個基於支持向量機(SVM)的多分類模型 baseline;觀點型問題閱讀理解提供一個深度學習模型 baseline , 基於pytorch實現論文《Multiway Attention Networks for Modeling Sentence Pairs》裏的思路。

本次 AI Challenger 2018, 除了英中文本機器翻譯,另一個我比較關注的賽道是: 細粒度用戶評論情感分析。情感分析是自然語言處理裡面的一個經典任務,估計很多同學入門NLP的時候都玩過 IMDB Movie Reviews Dataset , 這個可以定義為一個二分類的情感分類問題。不過這次 AI Challenger 的細粒度用戶評論情感分析問題,並不是這麼簡單:

簡介

在線評論的細粒度情感分析對於深刻理解商家和用戶、挖掘用戶情感等方面有至關重要的價值,並且在互聯網行業有極其廣泛的應用,主要用於個性化推薦、智能搜索、產品反饋、業務安全等。本次比賽我們提供了一個高質量的海量數據集,共包含6大類20個細粒度要素的情感傾向。參賽人員需根據標註的細粒度要素的情感傾向建立演算法,對用戶評論進行情感挖掘,組委將通過計算參賽者提交預測值和場景真實值之間的誤差確定預測正確率,評估所提交的預測演算法。

數據說明數據集分為訓練、驗證、測試A與測試B四部分。數據集中的評價對象按照粒度不同劃分為兩個層次,層次一為粗粒度的評價對象,例如評論文本中涉及的服務、位置等要素;層次二為細粒度的情感對象,例如「服務」屬性中的「服務人員態度」、「排隊等候時間」等細粒度要素。評價對象的具體劃分如下表所示。層次一(The first layer)層次二(The second layer)位置(location)交通是否便利(traffic convenience)距離商圈遠近(distance from business district)是否容易尋找(easy to find)服務(service)排隊等候時間(wait time)服務人員態度(waiter』s attitude)是否容易停車(parking convenience)點菜/上菜速度(serving speed)價格(price)價格水平(price level)性價比(cost-effective)折扣力度(discount)環境(environment)裝修情況(decoration)嘈雜情況(noise)就餐空間(space)衛生情況(cleaness)菜品(dish)分量(portion)口感(taste)外觀(look)推薦程度(recommendation)其他(others)本次消費感受(overall experience)再次消費的意願(willing to consume again)

每個細粒度要素的情感傾向有四種狀態:正向、中性、負向、未提及。使用[1,0,-1,-2]四個值對情感傾向進行描述,情感傾向值及其含義對照表如下所示:

情感傾向值(Sentimental labels)10-1-2含義(Meaning)正面情感(Positive)中性情感(Neutral)負面情感(Negative)情感傾向未提及(Not mentioned)

首先有20個粒度的評價指標,每個粒度又有4種情感狀態,從官方baseline來看,分別訓練了20個(4標籤)分類器。抱著學習的態度,我跑了一下官方的 baseline,不過結果有點慘不忍睹,最終的F1均值只有0.2多一點,不知道哪個環節出了問題,另外一個問題是,整個訓練過程大概花了2、3天,對於我來說稍微有點長。對於文本分類問題,自從有了 fastText,我最喜歡用 fastText 做 baseline,最大的原因就是快,另外就是結果也不遜於傳統的機器學習模型。

但是,要用facebook官方的 fastText 以及自帶的 Python fastText 工具包做這件事並不容易,或者說對於20個多標籤分類器來說這事很繁瑣。不過沿著 AI Challenger 2018官方提供的 baseline 代碼思路,它裡面用了sklearn的分類器介面,我在想能否借用這個介面把fastText引入,這個時候,自然想到了google,google了一下關鍵詞"fasttext sklearn", 果然發現了兩個第三方工具:

sklearn-fasttext:A scikit learn based interface to facebook fasttext.

skift:scikit-learn wrappers for Python fastText.

分別試了一下,發現後者能滿足我的需求,於是動手修改了一下 AI Challenger 官方的 baseline 代碼,引入 fastText,於是就有了這個版本:fastText for AI Challenger Sentiment Analysis

Github地址:github.com/panyang/fast

AI Challenger 2018 Sentiment Analysis Baseline with fastText

功能描述本項目主要基於AI Challenger官方baseline修改了一個基於fastText的baseline,方便參賽者快速上手比賽,主要功能涵蓋完成比賽的全流程,如數據讀取、分詞、特徵提取、模型定義以及封裝、 模型訓練、模型驗證、模型存儲以及模型預測等。baseline僅是一個簡單的參考,希望參賽者能夠充分發揮自己的想像,構建在該任務上更加強大的模型。

開發環境

  • 主要依賴工具包以及版本,詳情見requirements.txt

項目結構

  • src/config.py 項目配置信息模塊,主要包括文件讀取或存儲路徑信息
  • src/util.py 數據處理模塊,主要包括數據的讀取以及處理等功能
  • src/main_train.py 模型訓練模塊,模型訓練流程包括 數據讀取、分詞、特徵提取、模型訓練、模型驗證、模型存儲等步驟
  • src/main_predict.py 模型預測模塊,模型預測流程包括 數據和模型的讀取、分詞、模型預測、預測結果存儲等步驟

使用方法

  • 準備 virtualenv -p python3 venv & source venv/bin/activate & pip install -r requirement.txt
  • 配置 在config.py中配置好文件存儲路徑
  • 訓練 運行 python main_train.py -mn your_model_name 訓練模型並保存,同時通過日誌可以得到驗證集的F1_score指標
  • 預測 運行 python main_predict.py -mn your_model_name 通過載入上一步的模型,在測試集上做預測

以下是我在家裡這臺深度學習機器上的測試,不過並沒有用到GPU,主要用的是CPU和內存:CPU是Intel/英特爾 Xeon E5-1620V4 CPU 4核心8線程,內存是48G。因為 skift 只支持python3, 所以是在Ubuntu16.04, python3.5的環境下測試的,其他環境是否能順利測試通過不清楚。

git clone https://github.com/panyang/fastText-for-AI-Challenger-Sentiment-Analysis.git
cd fastText-for-AI-Challenger-Sentiment-Analysis/
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirement.txt

注意準備工作做完後,需要在config裏設置相關文件的路徑,默認配置大概是這樣的:

import os

data_path = os.path.abspath(..) + "/data"
model_path = data_path + "/model/"
train_data_path = data_path + "/train/train.csv"
validate_data_path = data_path + "/valid/valid.csv"
test_data_path = data_path + "/test/testa.csv"
test_data_predict_output_path = data_path + "/predict/testa_predict.csv"

注意運行代碼前需要將相關輸入輸出路徑建好,並將相關數據路徑指定好,可以直接拷貝AI Challenger官方提供的數據文件,也可以用軟連接指向。如果不做任何設定,可以直接用默認配置參數訓練fasttext多模型,直接運行「python main_train.py」 即可。這樣大概跑了不到10分鐘,內存峯值佔用不到8G,在驗證集上得到一個f1均值約為0.5451的fasttext多分類模型(20個),模型存儲位置在 model_path 下:fasttext_model.pkl,大概1.8G,在驗證集上詳細的F1值大致如下:

location_traffic_convenience:0.5175700387941342
location_distance_from_business_district:0.427891674259875
location_easy_to_find:0.570805555583767
service_wait_time:0.5052181634999748
service_waiters_attitude:0.6766570408968818
service_parking_convenience:0.5814636947460745
service_serving_speed:0.5701241141533907
price_level:0.6161258412096242
price_cost_effective:0.5679586399625348
price_discount:0.5763345656700684
environment_decoration:0.5554146717297597
environment_noise:0.563452055291662
environment_space:0.5288336794721515
environment_cleaness:0.5511776910510577
dish_portion:0.5527095496220675
dish_taste:0.6114994440656155
dish_look:0.43750894239614163
dish_recommendation:0.41756941548558957
others_overall_experience:0.5322283082904627
others_willing_to_consume_again:0.5404900044311536

2018-10-02 14:32:18,927 [INFO] (MainThread) f1_score: 0.5450516545305993

這是默認參數跑出來的結果,另外代碼裏增加了一些fastText可用的參數選項,例如learning_rate,word_ngrams, min_count參數,也可以基於這些參數進行調參:

if __name__ == __main__:
parser = argparse.ArgumentParser()
parser.add_argument(-mn, --model_name, type=str, nargs=?,
default=fasttext_model.pkl,
help=the name of model)
parser.add_argument(-lr, --learning_rate, type=float, nargs=?,
default=1.0)
parser.add_argument(-ep, --epoch, type=int, nargs=?,
default=10)
parser.add_argument(-wn, --word_ngrams, type=int, nargs=?,
default=1)
parser.add_argument(-mc, --min_count, type=int, nargs=?,
default=1)

args = parser.parse_args()
model_name = args.model_name
learning_rate = args.learning_rate
epoch = args.epoch
word_ngrams = args.word_ngrams
min_count = args.min_count

作為一個例子,這裡將word_ngrams設置為2再跑一次:

python main_train.py -mn fasttext_wn2_model.pkl -wn 2

這次大約跑了15分鐘,內存峯值最大到37G,存儲的模型大約在17G,驗證集F1值結果如下:

location_traffic_convenience:0.5482785384602362
location_distance_from_business_district:0.4310319720574882
location_easy_to_find:0.6140713866422334
service_wait_time:0.5247890022873511
service_waiters_attitude:0.6881098513108542
service_parking_convenience:0.5828935095474249
service_serving_speed:0.6168828054420539
price_level:0.6615100420842464
price_cost_effective:0.5954569043369508
price_discount:0.5744529736585073
environment_decoration:0.5743996877298929
environment_noise:0.6186211367923496
environment_space:0.5981761036053918
environment_cleaness:0.6002515744280692
dish_portion:0.5733503000134572
dish_taste:0.6075507493398153
dish_look:0.4424685719881029
dish_recommendation:0.5936671419596734
others_overall_experience:0.5325664419580063
others_willing_to_consume_again:0.5875683298630815

2018-10-02 14:53:00,701 [INFO] (MainThread) f1_score: 0.5783048511752592

這個結果看起來還不錯,我們可以基於這個fasttext多分類模型進行測試集的預測:

python main_predict.py -mn fasttext_wn2_model.pkl

大約運行不到3分鐘,預測結果就出爐了,可以在 test_data_predict_output_path 找到這個預測輸出文件: testa_predict.csv ,然後就可以去官網提交了,在線提交的結果和驗證集F1值大致相差0.01~0.02。這裡還可以做一些事情來優化結果,譬如去停用詞,不過我試了去停用詞和去一些標點符號,結果還有一些降低;調參,learning_rate的影響是比較直接的,min_count設置為2貌似也有一些負向影響,有興趣的同學可以多試試,尋找一個最優組合。

歡迎關注我們的公眾號:AINLP

weixin.qq.com/r/43UNFSb (二維碼自動識別)


推薦閱讀:
相關文章