はじめに
2021年4月にデータスペシャリストとして新卒入社しました中間康文と申します。業務では主にレコメンドシステムの改善に取り組んでいます。
今回は、11月初旬に終了したkaggleのGoogle Brain - Ventilator Pressure Predictionという時系列データを扱うコンペにチームで参加して2605チーム中15位金メダルを獲得することができたので、取り組みなどを紹介しようと思います。
順位の右に表示されている数値が、参加中に確認できる順位と最終順位がどれくらい異なるかを表しています。見ての通り、順位の変動は少ないコンペで、なんとか金メダルを獲得することができました。
コンペについて
参加しようと思ったきっかけ
私は、過去に時系列データを扱うコンペに何度か参加したことがあり、このコンペにも興味を持ちました。 ベースライン を組んで、他の参加者にその内容を共有するというところからスタートしましたが、このコンペは開催期間が約1ヶ月しかないという特徴がありました(kaggleのコンペの開催期間は約3ヶ月のものがほとんどです)。
開催期間が他のコンペと比べて短いということもあり、チームでの参加を考えていたところ、twitterでチームメイトを募集している他の参加者がいたため、その方とチームを組むことにし、最終的には5人チームでこのコンペに参加することになりました。チーム名は、チームで楽しくやりたいという意味が込められた「waiwai」となりました。
タスク
今回のコンペは、機械式人工呼吸器を制御する新しい方法を開発して臨床医の負担を減らしたいという目的から開催されたものでした。というのも、現在の制御方法は患者ごとの肺の違いを考慮できていないとのことで、深層学習で患者ごとの肺の違いを考慮した汎化なモデルの構築が求められていました。
提供されたデータ
今回のコンペで提供されたデータは、オープンソースの人工呼吸器(部分的な変更あり)を人工肺に接続して採取されたものでした。
以下が実際に提供されたデータの一例です。
時間を表すカラムがtime_step
で、目的変数は、一番右側にある pressure
です。なお、u_out
という機器の制御変数が0となっているレコードが、評価の対象になっています。
LSTM
といったモデルがよく使われるような時系列データとなっていました。
評価指標
評価指標には、 MAE が用いられました。
解法の紹介
こちらが私のチームの解法の概要になります。 精度向上に大きく寄与した以下の4つのアプローチについて紹介します。
- Multi-task learning
- Loss switching
- Stacking
- Pseudo labeling
Multi-task learning
ここでの Multi-task learning は、複数の異なるタスクを同時に学習することで、あるタスクの精度を向上させることを目的としています。なぜ精度が向上するかについては、 こちら をご覧ください。 実際に、Multi-task learningによる精度向上は過去のkaggleコンペでも報告されています1。 今回提供されたデータは時系列データであったため、t時点における目的変数とt+1時点における目的変数の差を取ることで別の目的変数を作成し、それを用いてMulti-task learningを行うことで、精度の向上が確認できました。上位のほとんどのチームがMulti-task learningに取り組んでいました。
1 例:https://www.kaggle.com/c/trends-assessment-prediction/discussion/162799
Loss switching
こちらの名称はあくまでチーム内で使われていた名称で、学習途中でLossを計算する対象を切り替えることを指しています。このコンペでは、u_out
という機器の制御変数が0となっているレコードが評価の対象になっていました。そのため、学習時もu_out
という機器の制御変数が0となっているレコードのみを最適化するというアプローチが主流でした。しかし、u_out
という機器の制御変数が1となっているレコードも最適化の対象に含めて事前学習させ、学習途中で最適化の対象をu_out
という機器の制御変数が0となっているレコードに絞ることで、精度の向上が確認できました。
Stacking
Stackingとは、複数のモデルの予測値を特徴量として扱うモデルを学習することで、モデルの数が多ければ多いほど、加重平均といった手法よりも高い精度で最終的な予測値を得ることが期待できる手法です。今回はXGBoostを用いてStackingを行いました。また、モデルの予測値の他に、既存の特徴量も同時に用いることで精度の向上が確認できました。
Pseudo labeling
Pseudo labelingとは、学習時に用いてないデータに対する予測値を疑似的に目的変数として扱い、学習に利用する手法です。今回は予測精度が十分に高く、Pseudo labelingをすることで、精度の向上が確認できました。
さらに上位に行くために何が足りなかったのか
Data Hack
今回のコンペで提供されたデータは、オープンソースの人工呼吸器(部分的な変更あり)を人工肺に接続して採取されたものでした。細かい説明は省きますが、いくつかのチームは、このデータの生成過程を利用して、精度を向上させていました。私のチームでもこのような試みはありましたが、取り組み始めた時期が遅く、解法に組み込むことができませんでした。
Data Augmentation
3位のチームのData Augmentationがとても賢く、ここで大きな差を付けられていました。
-
masking augmentation
R
とC
というカテゴリ変数に対して、これらの変数は目的変数であるpressure
と強く相関していたため、どちらかの値をR
とC
に存在しない0で置き換えるといったmaskingを行い学習データの水増しを行うことで、精度を向上させていました。画像データに対して使われる学習データの水増し手法であるCutoutに似たようなものと紹介されていました。 -
shuffling augmentation
例えば、[0,1,2,3,4,5,6,7,8,9]
のようなindexがあった時に、window sizeを5としてshuffling augmentationを行うと、前半の[0,1,2,3,4]
が[3,2,4,1,0]
のようにshuffeされ、後半の[5,6,7,8,9]
が[7,5,6,9,8]
のようにshuffeされ、最終的に[3,2,4,1,0,7,5,6,9,8]
のようなindexとなる。時系列データに対してこのようなshufflingを行い学習データの水増しを行うことで、精度を向上させていました。 -
mixup augmentation
mixupは、2つのサンプルを任意の比率で混ぜて、新たなサンプルを作成することで、学習データの水増しを行う手法です。主に画像データに対してよく使われています。カテゴリ変数はone-hotで扱い、各変数と目的変数を1:1の比率で混ぜて学習データの水増しを行うことで、精度を向上させていました。
これらのData Augmentationが図解された3位のチームの解法は こちら です。
Model
Modelを工夫していたのは5位のチームです。CNNとTransformerを組み合わせたモデルである
Conformer(Convolution-augmented Transformer)
に影響を受け、Input_Encoder(N) = Output_Encoder(N-1)
としていたところをInput_Encoder(N) = Concat([Output_Encoder(N-1), 1D_Conv(Ouputut_Encoder(N-1)])
のようにCNNをTransformerに組み合わせることで、精度を向上させていました。
5位のチームの解法は こちら です。
Loss function
今回の評価指標が
MAE
なので、Pytorchであればnn.L1Loss
、Kerasであればtf.keras.losses.mean_absolute_error
をLoss functionとして用いるのが基本的なアプローチでした。その中で
ラプラス分布
を用いて最適化を行うというLoss functionの工夫で精度を向上させていたのが9位のチームです。学習は不安定らしく、
Gradient norm clipping
も必要だったとのことです。
9位のチームの解法は こちら です。
おわりに
最後まで読んでいただきありがとうございました。
結果としては、ギリギリながらも金メダルを獲得することができ、また多種多様な解法があり学びも多くて良かったです。チームでの参加もわいわい楽しむことができたので、また機会があれば色々な人と組んでみたいと思いました。
一緒に働きませんか?
リクルートというと、あまりkaggleのイメージはないかもしれませんが、多くのkagglerが在籍しています。2021年からkaggle部という部活も立ち上がり、kaggle部では月に一度LT会を開催し、知見を共有し合っています。自分が参加していないコンペの話など聞くことができ、非常に勉強になる場だと感じています。
弊社では、様々な職種のエンジニアを新卒・中途ともに募集しております。ご興味のある方は、以下の採用ページをご覧ください。