©作者 | 一峰
现在kaggle学生写作评估赛举办得如火如荼,下面我们来试试如何3行代码上榜kaggle。
01 比赛题目背景
写作是成功的关键技能。但是,根据国家教育进步评估,只有 不到三分之一的高中生是熟练的作家。
在这次kaggle比赛中,将识别学生写作中的元素 。其中,需要自动分割文本并对6至12年级学生的议论文中的议论和修辞元素进行分类 。
在该kaggle句子分类baseline中,我们可以提出2个想法,一个是对句子进行分类,另一个是对句子中的文字进行序列化标注,本文是使用文本分类的方式来快速验证,使用ernie和bert模型进行文本分类。
02 数据探索性分析
比赛一共有7个类别,348053条训练数据
对文本字数统计分析
通过上图可见字数长度范围为0< 字符串长度 < 3500,字数统计量最多的集中在0到500之间,对此我们要开始注意一个点,bert分类模型支持最大的字符串长度是512,一旦超过该长度,后面的字符就会被截断。
对文本存在空值进行分析
TRAIN_PATH ="../input/feedback-prize-2021/train"train_df=pd.read_csv(TRAIN_CSV, dtype={'discourse_id': int,'discourse_start': int,'discourse_end': int,'discourse_type':str})train_df.isnull().sum()
id 0discourse_id 0discourse_start 0discourse_end 0discourse_text 0discourse_type 0discourse_type_num 0predictionstring 0dtype: int64
可见数据不存在空值
● 标签的平均开始和结束的绝对位置
data = train_df.groupby("discourse_type")[['discourse_end', 'discourse_start']].mean().reset_index().sort_values(by = 'discourse_start', ascending = False)data.plot(x='discourse_type', kind='barh', stacked=False, title='Average start and end position absolute', figsize=(12,4))plt.show()
由此可知Lead位置排第一,concluding statement结语排在最后的位置,evidence的字符数最长
● 所有论文中的话语类型频率和标签类型的平均字数
fig = plt.figure(figsize=(12,8))ax1 = fig.add_subplot(211)ax1 = train.groupby('discourse_type')['discourse_len'].mean().sort_values().plot(kind="barh")ax1.set_title("Average number of words versus Discourse Type", fontsize=14, fontweight = 'bold')ax1.set_xlabel("Average number of words", fontsize = 10)ax1.set_ylabel("")ax2 = fig.add_subplot(212)ax2 = train.groupby('discourse_type')['discourse_type'].count().sort_values().plot(kind="barh")ax2.get_xaxis().set_major_formatter(FuncFormatter(lambda x, p: format(int(x), ','))) #add thousands separatorax2.set_title("Frequency of Discourse Type in all essays", fontsize=14, fontweight = 'bold')ax2.set_xlabel("Frequency", fontsize = 10)ax2.set_ylabel("")plt.tight_layout(pad=2)plt.show()
由上图可知,evidence的平均字数最长,接近80个字,claim出现频率最高,接近5万条
03 Ernie模型简单介绍
进行上面的数据分析之后,我们开始进行模型选型,既然是文本分类,肯定是无脑bert来一波。
作者无意中发现baidu的ernie号称吊打bert,bert是使用字级别的mask,而ernie使用了短语级别的mask。
在5测试任务中,都比bert取得了较好的成绩,特别是ChnSentiCorp情感分类,训练集高0.6%准确率,测试集高1.1%准确率。
04 Ernie模型训练
我们开始3行代码训练erine模型,上榜kaggle!
# 优化器的选择和参数配置optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters()) # fine-tune任务的执行者trainer = hub.Trainer(model=hub.Module(name='ernie_v2_eng_base', task='seq-cls', num_classes=num_class), optimizer, checkpoint_dir='/kaggle/working/ckpt', use_gpu=True) # 配置训练参数,启动训练,并指定验证集trainer.train(train_dataset, epochs=num_epochs, batch_size=batch_size, eval_dataset=dev_dataset, save_interval=1)
然后,我们开始了漫长的等待。
[2021-12-24 15:33:34,154] [ TRAIN] - Epoch=3/3, Step=10620/10625 loss=0.8742 acc=0.7000 lr=0.000050 step/sec=1.40 | ETA 06:22:27
最后,训练了3个epoch,没想到准确率才70%,损失高达0.8。怀着怀疑的态度进行了提交。
终于上榜了,分数才0.008,排名564/581,还好不是倒数。对此我们使用kaggle上大佬的transformer的bert进行测试。
#定义bert分类模型model = AutoModelForSequenceClassification.from_pretrained(MODEL_CHK, num_labels=NUM_LABELS)#定义参数training_args = TrainingArguments( output_dir='feeeback-classifier', learning_rate=2e-5, per_device_train_batch_size=32, per_device_eval_batch_size=32, num_train_epochs=NUM_EPOCHS, weight_decay=0.01, report_to="none", evaluation_strategy="epoch", save_strategy="epoch",)#定义训练器trainer = Trainer( model=model, args=training_args, train_dataset=ds_train_tokenized, eval_dataset=ds_val_tokenized, tokenizer=tokenizer, #data_collator=data_collator,)#模型训练trainer.train()
又等了不是很久,输出结果,也是出现特别高的损失,训练损失0.9,验证损失0.95。并将预测结果直接提交。
Epoch Training Loss Validation Loss1 1.036200 0.9658962 0.937500 0.954762
竟然0.223?排名519/581。
05 Baseline总结分析和后续工作
经过2个模型的测试和耗时的训练,最后最好的成绩是BERT文本分类的0.223。
对此,我们开始分析原因,尝试其他trick。
字符串长度和数量分布不均衡,某个分类(如evidence)字符串太长和数量多;
文本分类的字符串太长,因为分类任务最多只支持512长度字符串,如果使用超长字符运行,则会出现gpu显存不够的问题,所以我们测试时使用的都是256的字符串,导致训练数据的后面字符特征都被丢弃;
比赛成绩提交只能使用离线环境,预训练模型都得提前准备安装包,特别耗时费力。
总结下来,对于长文本(超过512)的文本分类,bert和erine的总体效果都不佳。
后续需要优化提升的地方:
使用文本增强提高训练数据多样性,如将英文先翻译为其他语言,再翻译回中文,使用近义词替换;
使用支持长文本的预训练模型,如longformer(长文本的bert)和erine-doc;
修改解题思路,将文本分类修改成文本序列化标注(NER)的方式,将数据特征改成序列化标注的形式,使用longformer或者erine-doc进行训练。
参考
[1] https://www.kaggle.com/stephenlu0422/nlp-on-student-writing-eda/edit
[2] https://www.kaggle.com/stephenlu0422/ernie?scriptVersionId=83170296
[3] https://www.kaggle.com/stephenlu0422/feedback-baseline-sentence-classifier-0-226?scriptVersionId=82417881
[4] Yu Sun, Shuohuan Wang, Yukun Li, Shikun Feng,Xuyi Chen, Han Zhang, Xin Tian, Danxiang Zhu, Hao Tian, Hua Wu:ERNIE Enhanced Representation through Knowledge Integration,2019,Apir,19
私信我领取目标检测与R-CNN/数据分析的应用/电商数据分析/数据分析在医疗领域的应用/NLP学员项目展示/中文NLP的介绍与实际应用/NLP系列直播课/NLP前沿模型训练营等干货学习资源。