第三届数据应用大赛Rank11–网格事件智能分类赛题复盘
成绩:11名 / 258名 得分:0.774688
前言
第二次参加文本分类赛题比赛,一个多月的时间,想着把一些学习到的方法trick用到竞赛中,看一下实际的效果,不断完善自己形成的代码框架,虽然最后的成绩一般,也确实跟队友学习到了一些上分技巧,下文对个人对赛题的理解以及思路进行分享。
赛题任务
出题方目的是实现城市的网格化管理:基于网格事件数据,对网格中的事件内容进行提取分析,对事件的类别进行划分,具体为根据提供的事件描述,对事件所属政务类型进行划分,是一个典型的NLP文本分类任务。
赛题方提供了2.8W条数据,包含训练集和测试集,数据集有严重的类别不均衡问题,多的类别7000+条数据,少的类别仅仅有几十条数据
接下来我们将从模型预训练,模型结构、提分技巧复盘整个竞赛过程。
一、模型预训练(尝试过预训练3Epochs程度不够,效果不如预训练200Epochs)
有很多预训练策略的花式操作,由于算力并不算充足,所以我们的精力主要放在了微调模型上,预训练策略为常规的mlm,更换恰当的预训练策略效果可能会更好。
我们尝试过的预训练模型有:
1、bert-base继续预训练200Epochs
2、chinese-bert-wwm-ext:哈工大开源版本继续预训练200Epochs
3、nezha-base继续预训练200Epochs
4、chinese-roberta-wwm-ext:继续预训练200Epochs
最终预训练的bert-base效果最好
二、模型结构
我尝试的模型结构为Bert + BiGRU + bert_pooler + MultiSample Dropout预测输出
加入BiGRU后模型效果可以得到0.5个点的提升,加入MultiSample Dropout后轻微提升
还尝试过 用 max_pooling + avg_pooling + 胶囊网络 + bert_pooling等组合,效果不如直接使用bert_pooler
三、提分技巧
1、面对数据类别样本不均衡问题,尝试Weighted CrossEntropy & Focal Loss & Dice Loss
样本不均衡会带来什么问题呢?
模型训练的本质是最小化损失函数,当某个类别的样本数量非常庞大,损失函数的值大部分被样本数量较大的类别所影响,导致的结果就是模型分类会倾向于样本量较大的类别。
通过类别加权Loss解决, 下图截自香侬科技的论文《Dice Loss for Data-imbalanced NLP Tasks》,分别列举了加权loss,Focal loss(FL)和他们提出的dice loss。我们的实验效果是: dice loss < FL < Weigth CE 。所以主要采用了weight ce。
Weight CE通过基于类别的加权的方式可以从不同类别的样本数量角度来控制Loss值,从而一定程度上解决了样本不均衡的问题,类别权重计算方式为类别词频的倒数。
"""
(1)因为数据集可能存在数据不均衡问题,通过给损失函数添加权重(要进行词频的统计,取词频的倒数,或者导数再开根号)
(2)weightCE损失函数主要关注的是正确的样本,不关注错误的样本;
"""
def calcClassWeightsByFrequence ( class_labels, labels) :
class_weights = list ( )
for class_label in class_labels:
class_frequence = 0
for label in labels:
if label == class_label:
class_frequence += 1
class_weights. append( 1 * 1.0 / class_frequence * 1.0 )
class_weights = F