文本分类实战技巧(tricks)汇总
目錄
?
前言
關(guān)于分詞器
關(guān)于中文字向量
如果數(shù)據(jù)集噪聲很嚴(yán)重
baseline選用CNN還是RNN?路線沿著CNN還是RNN走?
Dropout加在哪里
關(guān)于二分類
關(guān)于多標(biāo)簽分類
類別不均衡怎么辦
別太糾結(jié)系列
還是不會(huì)用tricks但是就是想跑出個(gè)好結(jié)果怎么辦
前言
一年前小夕在知乎上提問過這么一個(gè)問題
文本分類有哪些論文中很少提及卻對(duì)性能有重要影響的tricks?
鏈接:https://www.zhihu.com/question/265357659/answer/578944550
當(dāng)時(shí)正好在刷一個(gè)比較有趣的task,結(jié)果發(fā)現(xiàn)奇奇怪怪的tricks可以帶來不少的性能收益。再加上后來為了驗(yàn)證一個(gè)小idea跑了一堆公開的文本分類數(shù)據(jù)集,雖然idea沒有多亮,倒是積累和摸索了不少刷性能的tricks╮( ̄▽ ̄””)╭然后呢,小夕后續(xù)又用這些tricks刷了不少相關(guān)的比賽(哪怕是文本匹配這種特殊的文本分類問題),發(fā)現(xiàn)baseline+一堆tricks+簡(jiǎn)單集成就可以隨隨便便刷到一個(gè)文本分類的水比賽的top10甚至top3,甚感調(diào)參和tricks的重要性。然鵝,最近好一段時(shí)間都沒有文本分類這個(gè)基礎(chǔ)問題了,感覺都快忘了,趁著還有點(diǎn)模糊的記憶就整理下來分享給大家叭~希望能在大家刷論文實(shí)驗(yàn)、比賽或?qū)嶋H項(xiàng)目的時(shí)候提供點(diǎn)幫助或者啟發(fā)。首先來一個(gè)結(jié)論,tricks用的好,調(diào)參調(diào)的妙,TextCNN也能吊打絕大多數(shù)花里胡哨的深度模型。tricks沒用好,SOTA模型也會(huì)性能差的讓你懷疑人生。下面就不分重點(diǎn),沒有邏輯的開始本文辣。
關(guān)于分詞器
中文也好,英文也好,拿過來數(shù)據(jù)集無(wú)可避免的就是要看看要不要做分詞(有的小伙伴以為英文數(shù)據(jù)集就完全不用分詞真的讓人很無(wú)奈鴨),如果要做,就要糾結(jié)分詞器的選擇了。
路人丙:我廠有全方位吊打各種開源分詞工具的分詞器了
小夕:好了你可以往下劃了
首先就有一個(gè)問題,**真的是算法越“先進(jìn)”的分詞器就會(huì)給下游任務(wù)帶來越好的性能嗎?**很多人走到這一步的時(shí)候會(huì)忽略一個(gè)東西,**詞向量!!!**其實(shí)比起分詞算法本身的先進(jìn)程度,在神經(jīng)網(wǎng)絡(luò)使用預(yù)訓(xùn)練詞向量的大背景下,**確保分詞器與詞向量表中的token粒度match其實(shí)是更更重要的事情!**畢竟哪怕你詞分的再好,一旦詞向量表里沒有的話,那么就變成OOV了,分的再好也木用了╮( ̄▽ ̄””)╭(除非你不嫌麻煩多寫點(diǎn)代碼去對(duì)相對(duì)于詞向量表的OOV進(jìn)行特殊處理,反正我一般嫌麻煩╮(╯▽╰)╭)于是這里就有了兩種情況。1.?****已知預(yù)訓(xùn)練詞向量的分詞器一般像word2vec、glove、fasttext這些官方release的預(yù)訓(xùn)練詞向量都會(huì)公布相應(yīng)訓(xùn)練語(yǔ)料的信息,包括預(yù)處理策略如分詞等,這種情況真是再好不過了,不用糾結(jié),如果你決定了使用某一份詞向量,那么直接使用訓(xùn)練該詞向量所使用的分詞器叭!此分詞器在下游任務(wù)的表現(xiàn)十之八九會(huì)比其他花里胡哨的分詞器好用。2.?****不知道預(yù)訓(xùn)練詞向量的分詞器這時(shí)就需要去“猜”一下分詞器了。怎么猜呢?首先,拿到預(yù)訓(xùn)練詞向量表后,去里面search一些特定詞匯比如一些網(wǎng)站、郵箱、成語(yǔ)、人名等,英文里還有n't等,看看訓(xùn)練詞向量使用的分詞器是把它們分成什么粒度,然后跑幾個(gè)分詞器,看看哪個(gè)分詞器的粒度跟他最接近就用哪個(gè),如果不放心,就放到下游任務(wù)里跑跑看啦。當(dāng)然,最理想的情況當(dāng)然是先確定最適合當(dāng)前任務(wù)數(shù)據(jù)集的分詞器,再使用同分詞器產(chǎn)出的預(yù)訓(xùn)練詞向量啦。可惜互聯(lián)網(wǎng)上不可能有那么多版本的公開詞向量供選擇,因此自己在下游任務(wù)訓(xùn)練集或者大量同分布無(wú)監(jiān)督語(yǔ)料上訓(xùn)練詞向量顯然更有利于進(jìn)一步壓榨模型的性能。不過,怎么為當(dāng)前的任務(wù)去預(yù)訓(xùn)練一份兒好用的詞向量又夠?qū)懸黄恼碌摹!_@里就不展開講啦,小夕以后再寫~(沒關(guān)注小夕的趕緊關(guān)注!)當(dāng)然,除了分詞器跟詞向量表要match上,另外還要保證大小寫、OOV的定義等跟詞向量表match上。如果使用了一個(gè)區(qū)分了大小寫的詞向量表,但是你還將下游任務(wù)的單詞全都小寫,那么不用想了,絕對(duì)性能丟N多個(gè)百分點(diǎn)。
關(guān)于中文字向量
路人丁:好麻煩,我不分詞了,我要用字向量了哼
小夕:別逃( ̄? ̄)
如果你真的將char-level作為主力,那么別忘了中文的字向量也要預(yù)訓(xùn)練!并且預(yù)訓(xùn)練的時(shí)候記得把窗口開大一些,不要直接使用word-level的窗口大小哦,其他預(yù)訓(xùn)練超參數(shù)也隨手調(diào)一調(diào)更好了,絕對(duì)比隨機(jī)初始化的字向量明顯的好。
如果數(shù)據(jù)集噪聲很嚴(yán)重
這里噪聲嚴(yán)重有兩種情況。對(duì)于數(shù)據(jù)集D(X, Y),一種是X內(nèi)部噪聲很大(比如文本為口語(yǔ)化表述或由廣大互聯(lián)網(wǎng)用戶生成),一種是Y的噪聲很大(一些樣本被明顯的錯(cuò)誤標(biāo)注,一些樣本人也很難定義是屬于哪一類,甚至具備類別二義性)。對(duì)于前一種噪聲,一個(gè)很自然的想法是去使用語(yǔ)言模型或者基于編輯距離去做文本糾錯(cuò),然鵝實(shí)際中由于專有名詞和超出想象的“假噪聲”存在,在實(shí)際場(chǎng)景中往往效果并不是很好。這里小夕一般有兩種思路,一種是直接將模型的輸入變成char-level(中文中就是字的粒度),然后train from scratch(不使用預(yù)訓(xùn)練詞向量)去跟word-level的對(duì)比一下,如果char-level的明顯的效果好,那么短時(shí)間之內(nèi)就直接基于char-level去做模型叭~如果性能差不太多,或者char的已經(jīng)做到頭了,想做一下word-level呢?不要急,先幫小夕買根棒棒糖唄( ̄? ̄)一個(gè)很work但是貌似沒有太多人發(fā)現(xiàn)的trick就是使用特殊超參的FastText去訓(xùn)練一份詞向量啦。為什么說特殊呢?一般來說fasttext在英文中的char ngram的窗口大小一般取值3~6,但是在處理中文時(shí),如果我們的目的是為了去除輸入中的噪聲,那么我們可以把這個(gè)窗口限制為1~2,這種小窗口有利于模型去捕獲錯(cuò)別字(想象一下,我們打一個(gè)錯(cuò)誤詞的時(shí)候,一般都是將其中的一個(gè)字達(dá)成同音異形的另一個(gè)字),比如word2vec學(xué)出來的“似乎”的最近詞可能是“好像”,然而小ngram窗口fasttext學(xué)出來的“似乎”最近詞則很有可能是“是乎”等內(nèi)部包含錯(cuò)別字的詞,這樣就一下子讓不太過分的錯(cuò)別字構(gòu)成的詞們又重新回到了一起,甚至可以一定程度上對(duì)抗分詞器產(chǎn)生的噪聲(把一個(gè)詞切分成多個(gè)字)。當(dāng)然,如果數(shù)據(jù)集很干凈的話,這樣訓(xùn)練詞向量的話可能就gg了。而對(duì)于后一種噪聲的情況(即Y中的噪聲),一種很直接的想法是做標(biāo)簽平滑,然而小夕在實(shí)戰(zhàn)中使用多次發(fā)現(xiàn)效果并不是太明顯。最后總結(jié)的trick是,首先忽略這個(gè)噪聲,強(qiáng)行的把模型盡可能好的訓(xùn)出來,然后讓訓(xùn)練好的模型去跑訓(xùn)練集和開發(fā)集,取出訓(xùn)練集中的錯(cuò)誤樣本和開發(fā)集中那些以很高的置信度做出錯(cuò)誤決策的樣本(比如以99%的把握把一個(gè)標(biāo)簽為0的樣本預(yù)測(cè)為1),然后去做這些bad cases的分析,如果發(fā)現(xiàn)錯(cuò)誤標(biāo)注有很強(qiáng)的規(guī)律性,則直接擼一個(gè)腳本批量糾正一下(只要確保糾正后的標(biāo)注正確率比糾正前明顯高就行)。如果沒有什么規(guī)律,但是發(fā)現(xiàn)模型高置信度做錯(cuò)的這些樣本大部分都是標(biāo)注錯(cuò)誤的話,就直接把這些樣本都刪掉吧~常常也可以換來性能的小幅提升,畢竟測(cè)試集都是人工標(biāo)注的,困難樣本和錯(cuò)標(biāo)樣本不會(huì)太多。
baseline選用CNN還是RNN?路線沿著CNN還是RNN走?
在文本分類中真的不要太糾結(jié)這個(gè)問題,個(gè)人傾向于CNN,主要是因?yàn)榕艿每煅健!!?梢远嗯軒捉M實(shí)驗(yàn),多好。而且實(shí)際經(jīng)驗(yàn)感覺TextCNN這種基礎(chǔ)款CNN模型不僅實(shí)現(xiàn)特別容易,而且很容易成為一個(gè)數(shù)據(jù)集上的很強(qiáng)的baseline(除非這個(gè)分類任務(wù)很難),花一兩個(gè)小時(shí)把這個(gè)baseline做出來后再去做其他模型一點(diǎn)也不遲~也有助于早期就能糾正大方向。而如果要談到客觀的思路決策上,那就去花一個(gè)小時(shí)好好看一下數(shù)據(jù)集吧~如果你感覺數(shù)據(jù)集里很多很強(qiáng)的ngram可以直接幫助生成正確決策,那就CNN起步吧。如果感覺很多case都是那種需要把一個(gè)句子看完甚至看兩三遍才容易得出正確tag,那就RNN起步吧。當(dāng)然,如果數(shù)據(jù)大,又有顯卡,還可以嘗試Transformer。時(shí)間多的話,還可以CNN、RNN的模型都跑出來簡(jiǎn)單集成一下。
Dropout加在哪里
word embedding層后、pooling層后、FC層**(全聯(lián)接層)**后,哦了。起步階段dropout概率保持統(tǒng)一,有時(shí)間再單獨(dú)微調(diào)就好(從來沒有這個(gè)時(shí)間過)。至于偶爾有人吹捧的word dropout策略(將一些token隨機(jī)mask成[PAD],或者說0。注意這個(gè)操作跟dropout加在embedding層后不等價(jià)哈),最后有時(shí)間的話試一下就好,親測(cè)在dropout調(diào)好的情況下一般并不會(huì)發(fā)揮多大作用。
關(guān)于二分類
二分類問題一定要用sigmoid作為輸出層的激活函數(shù)?當(dāng)然不是,嘗試一下包含倆類別的softmax吧。可能多一條分支就多一點(diǎn)信息叭,雖然后者在數(shù)學(xué)形式上更丑一點(diǎn),但是實(shí)踐中常常帶來零點(diǎn)幾個(gè)點(diǎn)的提升也是比較玄學(xué)了。
關(guān)于多標(biāo)簽分類
如果一個(gè)樣本同時(shí)擁有多個(gè)標(biāo)簽,甚至標(biāo)簽同時(shí)還構(gòu)成了DAG(有向無(wú)環(huán)圖),不要著急,先用binary-cross-entropy訓(xùn)出個(gè)baseline來(即把每個(gè)類別變成一個(gè)二分類問題,這樣N個(gè)類別的多標(biāo)簽分類問題就變成了N個(gè)二分類問題),畢竟這個(gè)都在tensorflow里有現(xiàn)成API了,即tf.nn.sigmoid_cross_entropy_with_logits。因此實(shí)現(xiàn)代價(jià)很小。然后你還可能驚喜的發(fā)現(xiàn),這個(gè)baseline做好后好像多標(biāo)簽問題不大了,DAG問題自己也基本解決了(雖然模型層并沒有專門針對(duì)這個(gè)問題作處理),然后就可以安心做模型辣。什么?問題木有解決?去查論文吧╮( ̄▽ ̄””)╭小夕還沒有接觸過這方面太難的數(shù)據(jù)集。
類別不均衡怎么辦
像網(wǎng)上說的那樣趕緊各種上采樣下采樣boosting策略用起來?nono,正負(fù)樣本比才9:1的話,繼續(xù)做你的深度模型調(diào)你的超參吧,模型做好后你會(huì)發(fā)現(xiàn)這點(diǎn)不均衡對(duì)模型來說不值一提,決策閾值也完全不用手調(diào)。但!是!如果你發(fā)現(xiàn)經(jīng)常一個(gè)batch中完全就是同一個(gè)類別的樣本,或者一些類別的樣本經(jīng)過好多batch都難遇到一個(gè)的話,均衡就非常非常有必要了。類別不均衡問題傳送門->【小夕精選】如何優(yōu)雅而時(shí)髦的解決不均衡分類問題
別太糾結(jié)系列
別太糾結(jié)文本截?cái)嚅L(zhǎng)度使用120還是150
別太糾結(jié)對(duì)性能不敏感的超參數(shù)帶來的開發(fā)集性能的微小提升
別太糾結(jié)未登陸詞的embedding是初始化成全0還是隨機(jī)初始化,別跟PAD共享embedding就行
別太糾結(jié)優(yōu)化器用Adam還是MomentumSGD,如果跟SGD的感情還不深,就無(wú)腦Adam,最后再用MomentumSGD跑幾遍
還是不會(huì)用tricks但是就是想跑出個(gè)好結(jié)果怎么辦
BERT了解一下。Over。暫時(shí)想起來的就是這些啦,剩下有想起來的tricks小夕會(huì)更新到知乎上,傳送門:
https://www.zhihu.com/question/265357659/answer/578944550
話說,小夕跟大家分享了這么多tricks,親愛的們有沒有秘藏tricks在評(píng)論區(qū)分享給小夕呢( ̄? ̄)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的文本分类实战技巧(tricks)汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中科院博士整理的机器学习算法知识手册,完
- 下一篇: ICML2021 | Self-Tuni