見出し画像

Kaggle 2023 Predict Student Performance from Game Play (PSP) コンペ解法の傾向まとめ


初めに

初めまして。ギリアで機械学習エンジニアをやっている野谷と申します。
ギリアにはKagglerが何人かおり、自分もそのうちの一人です。今回は2023/02から2023/07の間にKaggleで開催されていたPredict Student Performance from Game *1 の解法についてまとめようと思います。

コンペティションの概要

期間について

2023/02/07 〜 2023/06/29の間に開催されていました。Kaggleのコンペティションは通常3ヶ月間程度の期間が多く、このコンペも当初は同様の期間でした。ただ、事情(後述)により終了期間が度々延長され、長めの開催となりました。

目的や課題、類似事例など

コンペティションの目的
このコンペティションの目的は、教育ゲームにおける生徒の成績をリアルタイムで予測したい、というものでした。もし予測に成功すれば、ゲーム開発者が教育ゲームを改善し、生徒をダッシュボードや分析ツールにより支援できる、というメリットが挙げられています。

分野における課題
分野としては、いわゆる教育のGamificationにおけるユーザーの能力推定で、"Knowledge tracing"と呼ばれるそうです。
ただし、ほとんどの教育ゲームは個々の生徒をサポートするための"Knowledge tracing"を行えておらず、また、教育ゲームにおける研究もあまりない、ということが課題として挙げられていました。

類似した事例
過去の類似したコンペティションとしては2021年に開催されていたRiiid Answer Correctness Prediction *2 などが挙げられます。ただし、ユーザーあたりの系列長の短さやカテゴリ変数への依存度の小ささからか、Riiidと比べTransformerのみの解法はあまり見られませんでした。
ビジネスの事例としては、ギリアでは株式会社トライグループ様の事例 *3 などがあり、比較的需要のある分野かと思います。

コンペティションについて

データ

訓練データは42万件、CSV形式により提供される、いわゆるテーブルデータのコンペティションでした。
テストデータは訓練データとほぼ同じ大きさと言及されていました。ただし、Kaggle time series APIにより提供されるため、詳細については不明でした。なお、Kaggle Series APIに不具合があったため、順位表が幾度か変更され、期間が延長されました。*4

また、コンペティション開催中にテストデータの一部が意図せず公開されていたことがわかりました。*5 この後、データは更新され、コンペティションデータの元となった生データについてもDiscussion上で共有されました。この影響により、期間が一度延長されました。

ターゲット

今回は各セッションの各質問番号に対し、ユーザーが正解したか否かの0か1の値を予測するタスクでした。質問は1つのセッションに対し、0〜4、5〜12、13〜22の3つのセグメントからなり、合計18個存在します。
18個の質問内容や出題順はユーザー・セッション間において全く同じで、前後や抜け漏れはありませんでした。

評価指標

指標はF1 scoreでした。
AUCと異なり予測した確率値を0か1に2値化する必要があります。そのため、2値化する際の閾値の決め方などにも性能が左右される、やや不安定な指標です。

制約

提出時はCPUのみ利用可能で、実行時間は9時間以下でした。また、小型で軽量なモデルの作成を目的としているため、提出時は2 CPUs、RAM 8GBの環境で計算されることが言及されていました。
Efficiency Prize(後述)含め、計算コストを強く意識したやや珍しい条件でした。

その他

Efficiency Prize
最近多くなった印象ですが、計算時間も考慮した賞であるEfficiency Prizeが設定されていました。以下のスコアに基づいてefficiency scoreが計算されます。左の項はスコアが良いほどより負の方向に大きくなり、右の項は実行時間が短いほど正の方向に小さくなります。
小さい値ほど良い評価として扱われます。

  • 式中のF1は前述の評価指標と同様です

  • 式中のmaxF1は全Submission中の最大のPrivate LBのスコアです

  • 式中のBenchmarkはsample_submission.csvのスコアです

  • 式中のRuntimeSecondsは実行にかかった秒数です

(図1. Efficencyスコアについて)

解法について

解法やモデルが色々あり、良いコンペ設計とデータでした。Kaggleではよく使われるGBDT系のアンサンブルを取っても、解法によって効いた・効かなかったとの報告に分かれていました。

データ

外部で公開されていたデータですが、Public LB(以下、LBと表記)と傾向が異なり、Private LB(以下、PBと表記)と傾向が似ていたため一概には活用しにくかったようです。

  • 生のログデータからほぼ完ぺきに再現したtrain.csvを作成した。(train setと同じ条件の)完全なセッションとしては1万件、(train setとは異なる条件の)不完全なセッションとしては20万件のデータが追加された。 *10 (3位解法)

  • 公開されていたオープンデータの前処理を行い、類似性についてラベルでは99.9%、特徴量では99.5%を得た。ここから(train setと同じ条件の)すべての質問を完了していた1.1万件を利用した。ただし、LBではスコアが悪化したためこのデータは使用しなかった。LBとPBの分布が異なっており、追加したデータはPBに近かったことが後に判明した。*16 (8位解法)

    • 追加データは効かなかった。 *18 (10位解法)

特徴量

基本的な統計的特徴量
基本的な統計的特徴量はやはり強い印象です。ただし、何を集計するかは熟慮が必要で、今回は問題への理解度を反映した、時間やカウント数の集計が肝でした。

  • 期間とカウントに対する様々な集計

    • 1つのレベル・部屋・イベントの種類などの単位に対する経過時間など *8 *10 *12 *15 *17 *18 *19 *20 *21(1位解法、3位解法、4位解法、8位解法、9位解法、10位解法、10位解法、13位解法、14位解法)

    • 1つのレベル・部屋・イベントの種類などの単位に対するイベント数・カウントなど *8 *15 *20 (1位解法、3位解法、8位解法)

メタ特徴量、過去の特徴量
メタ特徴量が上位解法ではほぼ採用されていました。ぱっと見では開催期間中のNotebookにはなかったため、上位とその他ではここで差が出ていた可能性があります。
メタ特徴量が初めて出てきたのは2019年の2019 Data Science Bowlの2位解法 *6 と思われますが、2022年のAmerican Express - Default Prediction *7あたりでかなりポピュラーになってきた印象です。

  • 過去の質問に対する予測確率

    • 過去の質問の予測確率 *10 *11 *15 *17 *18 *20 * 21 (3位解法、3位解法、8位解法、9位解法、10位解法、10位解法、14位解法)

    • 最新のM(M=1、2、...)個の予測確率の合計 *10 *11 (3位解法、3位解法)

    • 各レベルグループの予測確率の平均 *21 (14位解法)

  • 過去の特徴量

    • 各セッションについてゲーム/セッションの最初からの全てのインタラクション情報  *8 *21 (1位解法、14位解法)

    • 過去のレベルグループの特徴量 *18 (10位解法)

理解度、行動性の効率に関わる特徴量
問題に正解するために必要な行動を取っているか、取っているとしてどのくらい効率的か、など質問の正誤に強く結びつく特徴量が効いたようです。

  • 効率的な動きをしているか、不必要な動きが少ないか

    • 必須のイベント間の経過時間 *11 *17(3位解法、9位解法)

    • 周回プレイをしている人も多いと推測し、無駄な動きをしているか否かにより、初見プレイか周回プレイかを識別する *10 (3位解法)

    • イベント名が特定の値のものであるレコード間での時間差。 *14 (7位解法)

    • 全て、あるいは各レベルでの部屋の変更(移動)回数など。これらは理解力と推理力を特徴づける。 *21 (14位解法)

  • マウスの動作

    • ホバー可能なオブジェクトにマウスホバーした時間に基づく集計 *15 *18 *19 (8位解法、10位解法、10位解法)

    • 最初にクリックしたオブジェクト、部屋の座標 *15 (8位解法)

  • テキストの長さ

    • ゲームはプレイヤーの読解スキル向上のために作られているため *8 (1位解法)

カテゴリカルな特徴量の連結
複数のカテゴリ変数をつなげて1つのカテゴリ変数にする解法もありました。
カテゴリ変数の組合せはGBDTやTransformerでは暗に学習できることから、あまり用いられない印象でした。今回は連結する変数を吟味することで効果があったようです。

  • 変数の組合せ・連結

    • データ内のイベント名、レベル、名前などを連結した文字列によって、ゲーム内の様々なポイントを識別する。複数回発生する場合は列挙して区別する。*12 (4位解法)

    • 6つの変数を連結して1つの値とした変数に対する連続した2つ変数の時間差、出現回数。ただし、レアな組合せは除外した。 *14 (7位解法)

他に
クリックした座標が特徴量としてありました。ただし、座標の最大値が、ユーザーが設定していた画面サイズにより変わってしまう問題がありました。このため、座標を特徴量として使用することが難しかった印象です。


特徴量選択

統計的特徴量では、特徴量同士を組合せるために大量に特徴量が作成されます。特徴量選択を行う場合、Leakを起こさないように注意する必要がありました。
また、同じGBDTモデルで高い学習率で学習・特徴量選択を行い、低い学習率で最終的に学習している解法が多かった印象です。

選択時の基準・方法について

  • 安定した戦略を構築できず、無駄な削減するトップダウンアプローチではなく各特徴量グループについて選択するボトムアップアプローチを採用した *8 (1位解法)

  • 訓練データ全体を使用したCatBoostの特徴量の重要度を、ラベルをシャッフルして学習した場合の特徴量の重要度の平均で割った値を用いた *10 (3位解法)

    • ただし、同チームの別メンバーは、特徴量選択によりCVスコアは変わらなかったがLBスコアが悪化したため行わない方針に切り替えていた *11 (3位解法)

  • 学習率を0.1と大きくしてLightGBMを学習し、特徴量の重要度から選択を行った。特徴量選択後は学習率を0.02まで小さくして再度学習した。 *14 (7位解法)

  • GainとShapelyの重要度が0の特徴量は除外した。特徴量選択を行った後、学習率を0.05から0.03まで下げてさらに特徴量を追加する調整を行った。さらに、重複した特徴量や95%以上が欠損値の特徴量は削除した。 *15 (8位解法)

  • 重要度の高い上位500個の特徴量を使用した。 *17 (9位解法)

  • それぞれのレベルグループにて上位300/600/900個の重要度と各質問の差から特徴量をフィルタリングした。*19 (10位解法)

リークへの注意・対応について

  • OOFで特徴量選択を行わないとリークが発生するため注意が必要 *10 (3位解法)

  • リークを防ぐために各foldに選択と再トレーニングを行った。 *17 (9位解法)

モデル

GBDT、 NNどちらも解法で使用されていました。
GBDTでは複数の質問について質問のIndexを特徴量とすることで、複数の質問(ターゲット)を1つのモデル内で学習させる解法が多かった印象です。異なるGBDT同士のアンサンブルについてはモデルの組合せは同じでも、解法によって効いた場合と効かなかった場合があったようです。
また、Transformer単体では学習が難しいものの、Encoderの前にGRUやLSTMを加えると改善したことが報告されていました。

XGBoost

  • 質問のIndexを特徴量として与えることで質問を区別した

    • 全体として1つのモデルで学習・予測した *10 (3位解法)

      • 単一のモデルも試したがPublic LBは良かったがPrivate LBでは良く使用しなかった *15 (8位解法)

    • レベルグループごとに作成し、全体として3つのモデルで学習・予測した *12 *18 *22 (4位解法、10位解法、14位解法)

  • LightGBM、CatBoostとのアンサンブルは成果が出なかった *8 (1位解法) *15 (8位解法)

  • 学習済みのNN(後述のTransformer)でEmbeddingを作成し、集約した特徴量と結合して学習した*15 (8位解法)

    • ただし、NN EmbeddingをGBDTの入力として試したが性能が出なかった *18 (10位解法)との報告があった

CatBoost

  • 質問のIndexを特徴量として与えることで質問を区別した

    • 全体として1つのモデルで学習・予測した *10 (3位解法)

    • レベルグループごとに作成し、全体として3つのモデルで学習・予測した *12 *22 (4位解法、14位解法)

  • 各質問に10foldでモデルを作成した *17 (9位解法)

LightGBM

  • 質問のIndexを特徴量として与えることで質問を区別した

    • レベルグループごとに作成し、全体として3つのモデルで学習・予測した *14 *22(7位解法、14位解法)

    • レベルグループ0〜4と5〜12ではそれぞれ1つずつモデルを訓練した。レベルグループ13〜22ではそれぞれの質問に対してモデルを訓練した。*20 (13位解法)

  • 各質問に10foldでモデルを作成した。"lleaves"というライブラリを用いてコンパイルし高速化した。特徴量が非常に多く過学習しやすかったため、`min_data_in_leaf`を十分に大きくし、`feature_fraction`を十分に小さくすることでCVが向上した。*17 (9位解法)

  • 追加データを学習する際は正答率の傾向の差異を学習するため、各セッションの最大のレベルを特徴量として追加した。また、最後のレベルグループのモデルを学習する際、2番目のレベルグループのラベルを水増しした。 *14 (7位解法)

NN

  • Conv1D

    • Transformerを最初に試したが性能が出ず、計算量も必要だった。Conv1DはTransformerと同等の性能で10倍高速だった。*8 (1位解法)

  • Transformer + LSTM

    • 3つのレベルそれぞれについてレベルグループ内の全ての値を予測するマルチラベルモデルと、セッション内の18個の値を予測するマルチラベルモデル *10 (3位解法) 

  • Transformer

    • 過学習しやすかったため、SN比を改善しようとした。時間、インデックス、距離、部屋の座標、独自に作成したカテゴリカルなチェックポイントの埋め込みを特徴量として使用した。*12 (4位解法)

  • Transformer + GRU

    • レベルグループごとにモデルを学習した。GRUを3層通した後、EncoderのみのTransformerでマルチラベル分類を学習する。同時に補助タスクとしてすべての質問への予測も行う。*15 (8位解法)

    • レベルグループごとに少数の特徴量で学習した。Transformer単体では良い性能が出ず、GRUにより改善した。*20 (13位解法)

Stacking

  • XGBoost、 CatBoost、 Transformerの予測確率に対し線形モデルを使用し最終的な予測を作成した。同一のレベルグループ内の最後の質問までの予測確率を入力とする。*12 (4位解法)

  • 各質問についてMLPとLogistic Regressionを作成した。 過学習しやすいため軽量な構造にした。*18 (10位解法)

Validation

メジャーなバリデーションとしては、Userを単位としたGroupKFoldがメインでした。
ただし、スコアの上下を、Validationを切って確認した後、最終的な提出には全データで学習したモデルを使用していた解法も散見されました。

  • セッションIDの最初の4桁が2200以下のものを訓練データに、2201以上のものを検証データとしてCVを構築した。最終的な提出にはすべてのデータセットを使用してモデルを訓練した。今回は閾値によりスコアが変化すること、CVとLBの傾向が一致しないことから採用した。 *20 (13位解法)

予測

18個の質問に対してそれぞれ0か1かを予測するタスクでしたが、各質問の閾値の最適化はあまり行われていませんでした。

閾値の最適化

  • 最終的なモデル出力の平均をとった後、各質問の閾値をscipyにより最適化した *18 (10位解法)

最後に

今回はメダルを獲得できず残念でしたが、解法に色々なバリエーションがあり面白いコンペティションだったと思います。詳細は不明ですが、今回の開催元の方が数ヶ月後に新しいコンペティションを開始することについて言及しています。*23 そこで今回の知見が役立つなり、LB上でお会いするなりできればと良いな思います。


*1: Kaggle “Predict Student Performance from Game” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/overview
*2: Kaggle “Riiid Answer Correctness Prediction” https://www.kaggle.com/competitions/riiid-test-answer-prediction/overview
*3: ギリア株式会社 “ギリアのAI 導入事例 » 学力診断システムの開発” https://ghelia.com/service/case/c11/
*4: Kaggle “Explanation for Competition Extension” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/415737
*5: Kaggle “Update on Leaked Competition Data” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/396202
*6: Kaggle “2nd place solution” https://www.kaggle.com/c/data-science-bowl-2019/discussion/127388
*7: Kaggle “American Express - Default Prediction” https://www.kaggle.com/competitions/amex-default-prediction
*8: Kaggle “1st Place Solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420217
*9: Kaggle “1st Place Code” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420332
*10: Kaggle “3rd Place Solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420235
*11: Kaggle “3rd place solution(yyykrk part)”  https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420274
*12: Kaggle “4th Place Solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420349
*13: Kaggle “4th Place Inference” https://www.kaggle.com/code/erijoel/4th-place-inference/notebook
*14: Kaggle “7th Place Solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420119
*15: Kaggle “8th Place Solution and Code”  https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420528
*16: Kaggle “8th Position: (External Dataset) Good Preprocessing = +0.002 for Single Model” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420315
*17: Kaggle “9th Place Solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420046
*18: Kaggle “10th Place Solution“ https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420132
*19: Kaggle “10th place solution(tereka part)” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420190
*20: Kaggle “13th place solution” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420077
*21: Kaggle “14th Place Solution Joseph Part” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420041
*22: Kaggle “Game-Play-LGBDart[INFER]” https://www.kaggle.com/code/takanashihumbert/game-play-lgbdart-infer/notebook
*23: Kaggle “Thanks for participating!” https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/420153

この記事が気に入ったらサポートをしてみませんか?