比赛链接:https://tianchi.aliyun.com/forum/#raceId=531810
以下资料整理自比赛论坛,感谢这些无私开源的选手们,以下是整理TOP5方案的主要思路和模型,以便大家学习
代码:https://github.com/kangyishuai/NEWS-TEXT-CLASSIFICATION?spm=5176.12282029.0.0.36fa49f5Gm3dpr
主要思路:
- 由于文本长度较大,而Bert输入文本长度不能超过512(如果是自己预训练的Bert,长度可以不局限于512),所以需要进行文本截断。
- 文本截断后,输入大小为[batch_size, max_segment, maxlen],其中batch_size是批大小,max_segment是截断后的最大句子数量,maxlen是每个句子的最大长度。
- 将输入reshape后输入Bert,得到大小为[batch_size*max_segment, maxlen]的句向量。
- 将句向量reshape后输入注意力层。
- 最后接全连接层进行分类。
- 融合:预测就是将多个模型预测结果计算算术平均即可。
代码:https://github.com/ZhouNLP/tcnlp
主要思路:
尝试了NLP文本分类任务中常用的思路,并且给出了实验中的一些总结,给我比较大的启发的地方是:
RNN网络,最大的亮点就是seq_len使用了2000个字符。令人震惊的原因有2点:一是长文本分类不通过HAN网络,而是单纯增加截取字符的长度是有用的;我们被bert等预训练模型限制了思维方式,对RNN来说,将seq_len增加到2000甚至更长是比较轻松的,但这对预训练模型来说是不可想象的。因为预训练模型的参数太多了,占用了太多内存。相比Bert模型的资源消耗,这种方法还是值的尝试的。
- TFIDF:TfIdfVectorizer+LGB模型
- FastTEXT
- Text-CNN
- Text-RNN
- Bert
- LSTM
主要模型:
- CNN:用textcnn做了baseline,文本截断长度为3000。并在此基础上稍作修改进行了尝试。如在池化层后拼接上LSTM或者GRU,效果略有提升,但在选择LSTM或者GRU的问题上,两者差别不大。同时,卷积核的窗口大小以及数量,提升较为有限。在此,我最终取得是窗口大小从2到6,数量分别为128。在我的实验中大概分数是0.87-0.90之间浮动。
- RNN:文本的截断长度依然为3000。模型则是双向的GRU。在固定数据切分,学习率,batchsize之后,效果比LSTM略好。并在此基础上尝试提取更多的特性。如在双向GRU后接上最大池化和平均池化,并拼接上word-embedding层的池化等等。总体在0.95-0.96。尝试了利用比赛数据进行词向量的预训练比如skipgram和fasttext,尝试分别使用,也尝试加上权重相加,但是效果都相比加入前差。
- Bert:由于比赛数据是匿名数据,因此bert需要自己进行预训练;bert模型微调
代码:https://github.com/Warrenheww/rank6_NLP_newstextclassification
所用模型及总体效果:
- 基于tfidf的特征化,lgb做到了单模型0.950,K-fold交叉预测stacking 0.953+。MLP模型相对较差,只能做到0.949左右,但有进步空间,后期转战Bert,没有继续深究。代码在GitHub已发布。
- 基于Bert的预测总体趋势是预训练步数越多,效果越好,最后采用60万步的预训练模型。B榜最终能达到单模型0.9667的效果。粗略分析,最终排名6很大原因是模型多样性不足,对预测结果进行最终投票时各output之间差异性不够,提升有限
- 基于不同模型,对预测结果进行stacking投票,可以对预测准确率有显著提高。
- 对数据处理伪标签处理在此类型分类任务中帮助很大,但是单纯基于训练集的伪标签容易导致模型泛化能力大幅下降。
- LightGBM:刚开始入手用的lgbm在跑,baseline 是93.3+。当时第一次跑完就进入了前100。 之后又用了模型集成,5折验证,来到了94.96左右。进一步调参,去干扰项,优化模型集成等方法,最后LightBGM可以到95.53%,第一次进了第一页排行榜。不过也发现这个模型基本到尽头了,于是放弃转向了其他复杂的模型。
- Bert:天池z正好提供了一个bert baseline的模型,正好可以用来跑一下。默认的参数和配置并不太好。第一次跑完也就是普通的LightGBM差不多。于是先调参。改了学习率和衰减率,之后原始模型到了接近96%就停滞不前了。于是意识到可能需要自己重新训练bert,天池给的bert词汇不足只有5300多个。所以自己重新按照google bert小组给的预训练办法开始搞。刚开始贪大,想搞个base的。后来发现搞出来后,机子跑不动,一个epoch 好几个小时。退而求其次,选了个6层的加强版mini bert来跑。于是经过调参优化,之后单模型到了96.6+。
- Ensemble:最后单模型做完就做模型集成了。由于没有太多时间搞其他模型,如果stacking的话,要训练20个不同的bert在数据集上。我就偷了个懒,把bert达到一定精度之后的模型都保存下来,做了一个snapshot ensemble。这样一次我就能得到很多个bert。大致在第三个epoch之后,精度就上去了,都能到96%以上。
另外我还把lgbm也拿来集成了,把每次bert对训练集的预测作为输入传给lgbm,真实值作为lgbm标签。这样测试的时候,把bert最测试集的输入作为lgbm的输入,lgbm基于bert的预测再给一个结果。这样lgbm也能有96.5+%。
通过几次集成测试,最后在A榜有96.9%, B榜出来时候也97%左右。