2017知乎看山杯 從入門到第二

利用一個暑假的時間,做了研究生生涯中的第一個正式比賽,最終排名第二,有些小遺憾,但收穫更多的是成長和經驗。我們之前沒有參加過機器學習和文本相關的比賽,只是學過一些理論基礎知識,沒有付諸過實踐,看過的幾篇論文也多虧前輩的分享(一個是用深度學習(CNN RNN Attention)解決大規模文本分類問題 - 綜述和實踐,另一個是brightmart的text_classification,裡面用Keras實現了很多文本分類的模型)。這些為我們的入門打下了良好的基礎,在比賽過程中也是反覆研讀和實踐,在此感謝兩位前輩的無私分享。

先放一波鏈接:

  • 比賽網址:biendata.com/competitio
  • 比賽源碼:github.com/Magic-Bubble
  • 比賽結果:zhuanlan.zhihu.com/p/28

下面對在這次比賽中用到的方法和收穫的經驗,做一個簡單的總結和分享。

用單模型探索數據的極限

1. 任務

  • 典型的文本多標籤分類問題,根據用戶在知乎上發布的問題標題及描述,判斷它屬於哪幾個話題
  • 訓練數據給出了300萬問題及其話題的綁定關係,話題標籤共有1999個,有父子關係,構成有向無環圖
  • 要求對未標註的數據預測其最有可能綁定的Top5話題標籤
  • 評測採用準確率與召回率的調和平均,準確率的計算按照位置加權,越靠前的分數越高(具體見評測方案

2. 數據

比賽提供的數據是300萬問題和話題的標題(下稱title)及描述(下稱desc),分別有對應的字序列(下稱char)和詞序列(下稱word),全部是以id的形式給出。這意味著我們是看不到原始文本的,所以對於badcase的分析也很困難,但好在其數據量夠大(2億多詞,4億多字),還是可以用深度學習來做。知乎官方也提供了訓練好的embedding(維度256),字級別和詞級別的都有,但是是分開訓練,不屬於同一個語義向量空間。

坊間常說:數據和特徵決定了機器學習的上限,而模型和演算法知識逼近這個上限而已。對於深度學習,因為不存在特徵工程,所以數據處理就至關重要了。而良好且合理的數據處理離不開系統詳細的數據分析,要知道數據是什麼樣,數據怎麼分布,才能更好地選擇模型和訓練方式。

2.1 數據分析

這裡主要是對問題的title和desc做長度分析,更為詳細的分析見數據分析

首先是問題title的字詞長度分布:

其次是問題desc的字詞長度分布:

2.2 預處理

  • 隨機shuffle後以9:1的比例劃分線下驗證集和訓練集,防止數據周期的影響
  • 對於embedding矩陣中未出現的詞,添加,並用-0.25~0.25初始化,千萬不能扔掉,這樣會破壞前後的語義關係
  • 對於title和desc,分別根據其平均長度*2,做截斷和補齊至長度一致,便於batch輸入網路訓練

3. 模型

參照brightmart的github開源,我們嘗試了前5種模型,分別是FastTextTextCNN、TextRNN、RCNNHAN

其中,HAN的原始論文中用的是詞和句子兩層Attention,而數據中是看不出句子的,所以這個方法我只用了一層word,效果不好。而RCNN因為同時用到了RNN和CNN的思想,所以整個網路的訓練時間很長,且其效果與單獨的RNN和CNN差不多,因此後期沒有使用此模型。最終用到的模型有:

  • FastText:通過Average抽象出概括性語義信息
  • TextCNN:仿照n-gram捕捉局部語義信息
  • TextRNN:提取序列語義信息

3.1 單模型Score

因為沒有花很多時間在單模型調參訓練上,所以最終單Model的分數普遍偏低,約比別的隊伍低0.5~1個百分點。

3.2 核心思路

這是我們這次參賽的一大亮點和創新點,就是成功地在深度學習上應用了一種類似於AdaBoost的做法,通過訓練多層來不斷修復前面層的偏差。我們在分析數據的時候發現,一個模型的輸出是具有類別傾向性的,所以在某些類別上可能全對,而在某些類別上可能全錯,所以我們針對這種偏差做了一些改進,通過人為地定義偏差的計算方式,指導下一層模型更多關注那些錯的多的類,從而達到整體效果的提升。

通過用這種方法,單模型Score有了質的飛躍,平均提升都在1.5個百分點(FastText因模型過於簡單,提升空間有限),而10層的RNN則更是在用全部訓練集finetune之後,分數直接從0.413飆升到0.42978,可謂真是用單模型探索數據的極限了。

這種方法的優勢在於,一般只要不斷加深訓練層數,效果就會提升,但缺點卻在於它抹平了模型的差異性,對於模型融合效果不友好。

3.3 模型融合

模型融合依靠差異性,而我們模型的差異性在前面已經近乎被抹平,所以又另尋他路,用了另外兩個方法:

  • 改變輸入,從word改成char,雖然char的單模型效果不好,但總體融合卻能提升很多
  • 人為定義不同的偏差計算方式

最終模型主要是5個10層模型的概率加權融合,分數在0.43506。

4. 結束語

這次比賽收穫很大,總結起來就是:

  • 數據預處理很重要
  • 模型不一定是最主要的,要多嘗試其他方法,更不能無腦訓模型,尤其是對於深度學習這種「黑盒子」
  • 比賽心態要放平,要抱著學習的心態

最後,還是要感謝知乎等組織舉辦的這次比賽,也感謝北郵模式識別實驗室的大力支持!


推薦閱讀:

大型RPG遊戲的巨量文本是如何寫作並整合的?

TAG:深度学习DeepLearning | 知乎算法大赛 | 文本 |