?作者 |?一峰
現(xiàn)在kaggle學(xué)生寫作評估賽舉辦得如火如荼镀赌,下面我們來試試如何3行代碼上榜kaggle些楣。
01 比賽題目背景
寫作是成功的關(guān)鍵技能续崖。但是另伍,根據(jù)國家教育進(jìn)步評估鼻百,只有 不到三分之一的高中生是熟練的作家。
在這次kaggle比賽中摆尝,將識別學(xué)生寫作中的元素 温艇。其中,需要自動(dòng)分割文本并對6至12年級學(xué)生的議論文中的議論和修辭元素進(jìn)行分類 堕汞。
在該kaggle句子分類baseline中中贝,我們可以提出2個(gè)想法,一個(gè)是對句子進(jìn)行分類臼朗,另一個(gè)是對句子中的文字進(jìn)行序列化標(biāo)注,本文是使用文本分類的方式來快速驗(yàn)證蝎土,使用ernie和bert模型進(jìn)行文本分類视哑。
02 數(shù)據(jù)探索性分析
比賽一共有7個(gè)類別,348053條訓(xùn)練數(shù)據(jù)
對文本字?jǐn)?shù)統(tǒng)計(jì)分析
通過上圖可見字?jǐn)?shù)長度范圍為0< 字符串長度 < 3500誊涯,字?jǐn)?shù)統(tǒng)計(jì)量最多的集中在0到500之間挡毅,對此我們要開始注意一個(gè)點(diǎn),bert分類模型支持最大的字符串長度是512暴构,一旦超過該長度跪呈,后面的字符就會被截?cái)唷?/p>
對文本存在空值進(jìn)行分析
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
可見數(shù)據(jù)不存在空值
●?標(biāo)簽的平均開始和結(jié)束的絕對位置
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結(jié)語排在最后的位置,evidence的字符數(shù)最長
●?所有論文中的話語類型頻率和標(biāo)簽類型的平均字?jǐn)?shù)
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的平均字?jǐn)?shù)最長耗绿,接近80個(gè)字,claim出現(xiàn)頻率最高砾隅,接近5萬條
03 Ernie模型簡單介紹
進(jìn)行上面的數(shù)據(jù)分析之后误阻,我們開始進(jìn)行模型選型,既然是文本分類,肯定是無腦bert來一波究反。
作者無意中發(fā)現(xiàn)baidu的ernie號稱吊打bert寻定,bert是使用字級別的mask,而ernie使用了短語級別的mask精耐。
在5測試任務(wù)中狼速,都比bert取得了較好的成績,特別是ChnSentiCorp情感分類卦停,訓(xùn)練集高0.6%準(zhǔn)確率向胡,測試集高1.1%準(zhǔn)確率。
04 Ernie模型訓(xùn)練
我們開始3行代碼訓(xùn)練erine模型沫浆,上榜kaggle!
# 優(yōu)化器的選擇和參數(shù)配置optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters()) ?# fine-tune任務(wù)的執(zhí)行者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) ?# 配置訓(xùn)練參數(shù)捷枯,啟動(dòng)訓(xùn)練,并指定驗(yàn)證集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
最后,訓(xùn)練了3個(gè)epoch本股,沒想到準(zhǔn)確率才70%攀痊,損失高達(dá)0.8。懷著懷疑的態(tài)度進(jìn)行了提交拄显。
終于上榜了苟径,分?jǐn)?shù)才0.008,排名564/581躬审,還好不是倒數(shù)棘街。對此我們使用kaggle上大佬的transformer的bert進(jìn)行測試。
#定義bert分類模型model = AutoModelForSequenceClassification.from_pretrained(MODEL_CHK, num_labels=NUM_LABELS)#定義參數(shù)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",)#定義訓(xùn)練器trainer = Trainer( ? ?model=model, ? ?args=training_args, ? ?train_dataset=ds_train_tokenized, ? ?eval_dataset=ds_val_tokenized, ? ?tokenizer=tokenizer, ? ?#data_collator=data_collator,)#模型訓(xùn)練trainer.train()
又等了不是很久承边,輸出結(jié)果遭殉,也是出現(xiàn)特別高的損失,訓(xùn)練損失0.9博助,驗(yàn)證損失0.95。并將預(yù)測結(jié)果直接提交富岳。
Epoch Training Loss Validation Loss1 ? ?1.036200 ? ? ? 0.9658962 ? ?0.937500 ? ? ?0.954762
竟然0.223蛔糯?排名519/581。
05 Baseline總結(jié)分析和后續(xù)工作
經(jīng)過2個(gè)模型的測試和耗時(shí)的訓(xùn)練窖式,最后最好的成績是BERT文本分類的0.223蚁飒。
對此,我們開始分析原因脖镀,嘗試其他trick飒箭。
字符串長度和數(shù)量分布不均衡狼电,某個(gè)分類(如evidence)字符串太長和數(shù)量多;
文本分類的字符串太長弦蹂,因?yàn)榉诸惾蝿?wù)最多只支持512長度字符串肩碟,如果使用超長字符運(yùn)行,則會出現(xiàn)gpu顯存不夠的問題凸椿,所以我們測試時(shí)使用的都是256的字符串削祈,導(dǎo)致訓(xùn)練數(shù)據(jù)的后面字符特征都被丟棄;
比賽成績提交只能使用離線環(huán)境脑漫,預(yù)訓(xùn)練模型都得提前準(zhǔn)備安裝包髓抑,特別耗時(shí)費(fèi)力。
總結(jié)下來优幸,對于長文本(超過512)的文本分類吨拍,bert和erine的總體效果都不佳。
后續(xù)需要優(yōu)化提升的地方:
使用文本增強(qiáng)提高訓(xùn)練數(shù)據(jù)多樣性网杆,如將英文先翻譯為其他語言羹饰,再翻譯回中文,使用近義詞替換碳却;
使用支持長文本的預(yù)訓(xùn)練模型队秩,如longformer(長文本的bert)和erine-doc;
修改解題思路昼浦,將文本分類修改成文本序列化標(biāo)注(NER)的方式馍资,將數(shù)據(jù)特征改成序列化標(biāo)注的形式,使用longformer或者erine-doc進(jìn)行訓(xùn)練关噪。
參考
[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
私信我領(lǐng)取目標(biāo)檢測與R-CNN/數(shù)據(jù)分析的應(yīng)用/電商數(shù)據(jù)分析/數(shù)據(jù)分析在醫(yī)療領(lǐng)域的應(yīng)用/NLP學(xué)員項(xiàng)目展示/中文NLP的介紹與實(shí)際應(yīng)用/NLP系列直播課/NLP前沿模型訓(xùn)練營等干貨學(xué)習(xí)資源鸟蟹。