Skip to content

FadedCosine/Chinese-Advertising-Text-MultiClass-Classification

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

腾讯游戏安全技术竞赛自然语言处理决赛 作品

模型基于BERT实现,已经训练好的模型在“model/”文件夹下。

数据预处理

由于训练集的标签数据分布十分不均衡,因此我对文本数据进行了增强,包括分词的随机dropout、shuffle增强和反向翻译数据增强。 具体的代码实现在data_processing/文件夹下,其中反向翻译数据增强需要用到腾讯AI开放平台提供的文本翻译(翻译君)API,需要注册账号,得到api key和密钥之后修改retranslate_constant.py中的

app_key_tencent = "自己注册的key id"
app_secret_tencent = "对应的密码"

而后直接通过

python augment.py

即可进行数据增强存在,因为腾讯AI开放平台的文本翻译API调用有并行量现在,所以如果数据量较大的话,反向翻译的数据增强会耗费大量的时间。

训练

训练代码在trainer.py当中,由于训练代码在google的colab上实现,所以该python文件有强烈的notebook的风格。

#默认的超参数
MAX_LEN = 180 #句子最大长度
batch_size = 32
num_labels = 5 #多分类标签数
lr = 2e-5 #学习率
epochs = 5
seed_val = 10 #随机数种子

#默认参数设定好后可以直接通过一下命令行操作进行训练
python trainer.py

测试

main_test.py代码中已经默认输入验证文件名为“validation_data.txt”,输出结果文件名为“result.txt”

#可以直接通过以下代码进行测试
python main_test.py
#也可以指定测试数据集名称和输出预测文件名称
python main_test.py --data_file="validation_data.txt" --out_put="result.txt"

由于上传的代码存在bug,最终比赛只拿到了优胜奖十分可惜,以下是我关于这次比赛的记录和反思。

腾讯游戏安全技术竞赛自然语言处理决赛 反思

四月初的天气时常阴晴未定。

由于好兄弟去年参加了这个比赛的缘故(见他的博客),我今年也尝试报名参赛,并也进入决赛,不过可惜只拿到优秀奖。我自己甚是失望,故属文于此,记录下整个答题过程和反思。

1. 数据分析

赛事方提供的游戏部分公开言语数据(中文),每条记录包括了言语内容本身和对应的细分类标签(正常和4种广告细分类,共5个分类)。首先我对数据进行初步分析,得到数据的数量分布以及对应的标签含义如下表:

数据标签 0 1 2 3 4
数量/条 73034 25466 500 1000 2000
标签含义 普通非广告文本 出资源广告 退款广告 社交广告 代练广告

​ 由此可见,各类标签的数据十分不均衡,因此我做了以下两种数据增强操作。

  1. 分词数据增强:我首先设定均衡的数据分布比例为4:1:1:1:1,而后我使用jieba分词将文本进行分词操作。分词之后,对于文本的分词进行两种操作,一是随机地进行删除,二是 shuffle, 即打乱词序,得到通过分词进行数据增强之后的训练集;

  2. 反向翻译数据增强:反向翻译的主要思想是先将机器翻译成另一种语言,再从另一种语言的文本翻译回原先语言,从而进行数据增强。我按照设定的数据分布比例,使用腾讯AI开放平台提供的文本翻译(翻译君)API进行反向翻译数据增强。

经过数据增强,各标签数据的比例大约在4:1:1:1:1,总的数据量到达了293490条。

2. 模型建立

我实际上实现了两个模型,BERT与TextCNN。

因为Pytorch和Transformers的框架下,就已经有了文本分类的API,用BERT的中文分词器处理完数据之后就可以很简单的直接训练,具体可以参考我滴好兄弟的另一篇博客

而TextCNN则十分常规的embedding+convd+maxpooling+output的网络结构,实现起来也轻而易举,分词则是用jieba这个分词库。

以上就是就是我模型的建立,由于本文重点在反思部分,故此处便不再叨唠。

3. 测试效果

BERT的多分类模型,在我9:1划分的测试集上的结果如下:

Accuracy Precision Recall F1
97.5926% 97.76% 97.80% 97.71%

看着这么高的表现只不过是镜花水月。实际上我得知自己只有优秀奖之后向赛事方寻求了测试集的部分数据,其数据的数量分布如下:

数据标签 0 1 2 3 4
数量/条 12110 2447 287 620 1269

可以发现,测试集的数据分布其实和训练集是十分接近的,而我训练的BERT模型在测试集上的测试效果则不堪入目:

Accuracy Precision Recall F1
87.0805% 27.85% 17.23% 21.78%

而TextCNN的模型在测试集上却有不错的效果:

Accuracy Precision Recall F1
86.85% 88.87% 60.31% 79.46%

认真debug一晚上之后,发现是在BERT模型中做预测时,调用forward的时候少传了一个参数,预测部分的代码如下:

..........

for step, batch in enumerate(test_dataloader):
        if step % 40 == 0 and not step == 0:
            print('  Batch {:>5,}  of  {:>5,}.'.format(step, len(test_dataloader)))
        batch = tuple(t.to(device) for t in batch)
        # b_input_ids, b_input_mask = batch
        b_input_ids, b_input_mask, b_labels = batch
        with torch.no_grad():
            outputs = model(b_input_ids,
                    token_type_ids=None,
                    attention_mask=b_input_mask #在提交答卷时少传了这个attention_mask
                    )

        logits = outputs[0]
        logits = logits.detach().cpu().numpy()
        label_ids = b_labels.to('cpu').numpy()

.............

attention_mask的作用是用于指示输入的文本,如果是PAD符号则是0,否则就是1。无论在训练还是预测,这都是一个十分重要的参数,我竟然漏了这个参数,实属nt。还有一个很重要的原因是,由于本地GPU不够跑BERT,而我又暂时没有服务器,只能在colab上跑程序,当时做预测时,只用了非常小(10行)的一个测试集,发现都正确之后便没有再检查了。出现如此低级错误,实在是不能接受。

不过现在的懊恼都已经弃我去者,昨日之日不可留了。希望以此为戒,乞求拜托今日之日的烦忧。

debug之后,BERT模型正确的测试代码的测试结果如下:

Accuracy Precision Recall F1
87.08% 88.20% 61.57% 79.60%

相比于TextCNN只有一点点的提升。考虑到测试文本中存在很多的非中文噪声,如:(该例子为我手动杜撰的)

4t把恩dsaiuhf223daf2元十万钻

实际上这个广告文本的内容就是

2元十万钻

所以我清洗了文本中的非中文字符。注意,可能存在其他正常的文本中本就出现非中文字符,所以这种清洗方式可能并不是最合适的。清洗之后BERT模型的表现略有上升:

Accuracy Precision Recall F1
87.33% 88.61% 62.35% 80.17%

以上,这次大赛的工作就告一段落了。之后,我向主办方了解到广告文本多分类第一名的F1达到了89.3%,确实存在比较大的差距。总结来说我觉得自己的工作可以改进的部分如下:

  1. 对于文本多分类问题,还只是用了最基础的BERT预训练模型加上一层decoder,可能忽略了其他一些重要的信息,decoder可能过于简单,也许可以参考最近的论文做更多设计。
  2. 可能数据的预处理部分存在问题,数据增强部分设定的数据分布比例可能必不合理,相反强行拉成4:1:1:1:1可能造成模型从这个数据分布获取了一些其他并不准确的特征信息。另外,数据清洗部分的做法也有待考虑。
  3. 我以后一定要换一台本地可以跑BERT的代码,或者自己有一张卡,不愿上colab薅资本主义恶臭的的羊毛(其实是因为colab老是断开连接,GPU用久了还给我限额)。

Releases

No releases published

Packages

No packages published

Languages