Kaggle Feedback Prize冠軍(jun) 方案分享
本文將介紹最近剛結束的Kaggle Feedback Prize - English Language Learning的賽題任務和冠軍(jun) 解決(jue) 方案。
賽題介紹
本次比賽的目標是評估8-12年級英語學習(xi) 者(English Language Learners, ELLs)的語言能力。利用ELL撰寫(xie) 的作文數據集,開發有助於(yu) 支持學生的模型。你的工作將幫助ELL獲得更準確的語言發展反饋,並加快教師的評分周期。這些結果可以使ELL接受更合適的學習(xi) 任務,幫助他們(men) 提高英語水平。
具體(ti) 來說,你需要訓練模型,對每篇議論文的六個(ge) 指標進行評分:銜接、語法、詞匯、短語、語法和慣例。每項指標都代表論文寫(xie) 作熟練程度的一個(ge) 組成部分,得分越高,該指標的熟練程度越高。分數範圍從(cong) 1.0到5.0,以0.5為(wei) 增量。你的任務是預測測試集中給出的六項測試中每一項的分數。
數據集介紹
數據集每條樣本包含一篇議論文,訓練集有對應的六個(ge) 指標的評分,測試集隻有議論文的文本信息,沒有標簽。
評價(jia) 指標
評價(jia) 指標為(wei) MCRMSE,對六個(ge) 標簽列分別計算RMSEh後取平均。
冠軍(jun) 方案
第一名的整體(ti) 方案如下圖所示,包括數據增強,模型訓練,構造穩定的線下驗證策略,以及模型集成。
總的策略是訓練很多具有多樣性的方案進行融合。其中多樣性包括數據的多樣性和模型的多樣性。
線下驗證策略
使用了MultilabelStratifiedKFold策略,由於(yu) CV和LB的趨勢較為(wei) 一致,在集成的時候隻會(hui) 將同時在CV和LB上都有提升的方案加入到最終的集成方案中。
def create_folds(cfg): df = pd.read_csv(cfg.dataset.comp_train_dataframe) mskf = MultilabelStratifiedKFold(n_splits=cfg.dataset.num_folds, shuffle=True, random_state=cfg.environment.seed) for fold, ( _, val_) in enumerate(mskf.split(X=df, y=df[cfg.dataset.target_cols])): df.loc[val_ , "fold"] = int(fold) df["fold"] = df["fold"].astype(int) df.to_csv(f"{cfg.dataset.base_dir}/train_{cfg.dataset.num_folds}folds.csv", index=False)
數據增強
數據增強模塊包括以下三個(ge) 策略:
1) 用模型的預測結果作為(wei) 偽(wei) 標簽加入到訓練集中;
2) 用1)中的預測結果和真實值求均值後,作為(wei) 偽(wei) 標簽加入到訓練集中;
3) Meta Pseudo Labels
其中,1)和3)除了使用訓練集的的數據,還使用了feedback1的數據
模型
3.1 Bert
Bert的模型方案細節:
1) 使用不同Max_len獲得不同的方案
768/1462 for deberta models, 512 for others
2) 不同的backbone
- microsoft-deberta-v3-base
- deberta-v3-large
- deberta-v2-xlarge
- roberta-large
- distilbert-base-uncased
3) 不同的pooling層
- MeanPooling
- ConcatPooling
- WeightedLayerPooling
- GemPooling
- LSTMPooling
4) 不同的reinit策略
設置是否reinit_top layer weights的開關(guan) ,獲得不同的方案
5) 不同的學習(xi) 率
使用不同的學習(xi) 率獲得不同的方案
6) 凍結top_n層參數
if 'deberta-v3-base' in cfg.architecture.model_name or 'mdeberta-v3-base' in cfg.architecture.model_name: self.model.embeddings.requires_grad_(False) self.model.encoder.layer[:9].requires_grad_(False)
7) 使用了Adversarial Weight Perturbation(AWP)
3.2 SVR
采用多個(ge) bert作為(wei) 特征提取器,提取後的特征進行拚接,輸入到SVR模型中。
其中,特征提取器包括:
- bart-large
- all_datasets_v3_roberta-large
- bart-large-mnli
這部分可以參考下麵的鏈接:
https://www.kaggle.com/code/cdeotte/rapids-svr-cv-0-450-lb-0-44x#Make-25-Stratified-Folds!
集成學習(xi)
集成學習(xi) 部分使用optuna進行搜索,對不同的方案賦予不同的權重.
參考代碼:
target_cols = ["cohesion", "syntax", "vocabulary", "phraseology", "grammar", "conventions"] csvs = ["model1.csv",'model2.csv','model3.csv', ...] def MCRMSE(y_trues, y_preds): scores = [] idxes = y_trues.shape[1]for i in range(idxes): y_true = y_trues[:,i] y_pred = y_preds[:,i] score = mean_squared_error(y_true, y_pred, squared=False) # RMSE scores.append(score) mcrmse_score = np.mean(scores)return mcrmse_score, scores def MCRMSE_SINGLE(y_trues, y_preds): scores = [] mcrmse_score = mean_squared_error(y_trues, y_preds, squared=False) # RMSEreturn mcrmse_score, scores def get_score(y_trues, y_preds, single=False):if single: mcrmse_score, scores = MCRMSE_SINGLE(y_trues, y_preds)else: mcrmse_score, scores = MCRMSE(y_trues, y_preds)return mcrmse_score, scores all_preds = []target_cols = ["cohesion", "syntax", "vocabulary", "phraseology", "grammar", "conventions"] labels = Nonefor index, csv in enumerate(csvs): oof_df = pd.read_csv(csv) oof_df = oof_df.sort_values('text_id').reset_index(drop=True)if index==0: print(oof_df.shape) df = pd.read_csv(csvs[0]) df = df.sort_values('text_id').reset_index(drop=True) labels = df[target_cols].values if f"pred_{target_cols[0]}" in oof_df.columns: preds = oof_df[[f"pred_{c}" for c in target_cols]].valueselse: preds = oof_df[target_cols].values all_preds.append(preds) single=False scores = []if single: score = get_score(labels, preds, single=True)else: score, scores = get_score(labels, preds) print(score, scores) def minimize_rmse(params): preds = Nonefor index, val in enumerate(params.keys()):if index == 0: preds = params[val]*all_preds[0]else: preds += params[val]*all_preds[index] param_sum = 0for key, val in params.items(): param_sum += val preds = preds/param_sum score, scores = get_score(labels, preds) return score def objective(trial): params = {}for i in range(num_of_csv): params[f"w{i+1}"] = trial.suggest_float(f'w{i+1}', 0, 1) score = minimize_rmse(params)return score study = optuna.create_study(direction='minimize')study.optimize(objective, n_trials=2000)study.best_params
參考鏈接
https://www.kaggle.com/competitions/feedback-prize-english-language-learning/discussion/369457
評論已經被關(guan) 閉。