サポートベクター回顧

プログラミングとか機械学習とか画像処理などに興味がある人のブログというかメモというか。アウトプット苦手なので頑張ります。

Kaggle振り返り:Open Problems - Multimodal Single-Cell Integration

public 47th → private 826thで超大幅shakedownしてました😭

一応、Tabular Playgroundを除いて初めて完走したコンペなので、ざっくり体験記を書きます。

コンペの詳細

細胞のコンペ。一つのコンペに以下の二つの部門がある

  • DNA情報からRNA発現を予測する(citeseq)
  • RNA発現からタンパク質発現を予測する(multiome)

4人のドナーの遺伝子情報を使う。日を変えながら測定しており、10日間にわたって5日ほどの時点のデータがある。

テーブルデータのコンペに挑戦したく参加したのですが、テーブルデータのわりにデータがかなり重くちょっと大変でした。

データ量の多さも難しいところですが、public test setとprivate test setの分布が全然違うところも曲者で、ドメインシフト対策が大事なコンペでした。(public test dataはtrainに無いdonorに対する予測、private test setはtrainに無い日付に対する予測みたいな感じ)

やったこと

モデル

基本的には、BatchNormalization有、dropout無のmlpや1dcnnといったDNNをメインにしていました。 cite、multiomeともに1dcnnが強かったです。 DNNには精度は劣りましたが、アンサンブル用としてridge回帰やGBDT(Light GBM、XGBoost、CatBoost)も使用しました。 また、multiomeに関しては目的変数が多すぎてGBDTやridgeで学習が終わらなかったので、DNN onlyで頑張っていました。

特徴選択

基本的にはSVD(n = 64)で次元削減したものを使っていました。 あとは公開ノートブックを参考に、他の人が特徴量選択をした特徴を使ったり、目的変数と相関が高い特徴上位〇%を使ったり、umapなどで次元削減した特徴を使ったり、生データを使ったりしていました。 citeに関してはSVD + 公開ノートの特徴、multiomeに関してはSVD + umap (n = 10)が強かったです。 いろんな特徴量で学習したモデルをblendingしていました。

メタデータは特徴量には追加しませんでした。日付を特徴量にするとCV、public LBともに向上したのですが、privateで外挿が発生するので怖くて使えず。cell typeの特徴量は実験したところ追加してもあんまり効果なさそうでした。

前処理

batch effect対策やドメインシフト対策で日付ごとに特徴量を標準化していたのですが、これが逆にpublicとprivateの乖離を引き起こしてしまっていたっぽいです。 これは、日付を考慮してCV切ってれば気づけるところだったので、反省点、、、

アンサンブル

seed averagingやblendingといったアンサンブルが強力で、いろいろな特徴量で学習させたモデルやいろいろな種類のモデルをひたすらNeldermead法でアンサンブルしていました。 アンサンブルするほどCVやLBが上昇する傾向が見られました。 特に生データで学習させた過学習気味のモデルがアンサンブルに有効だったり、DNNとGBDT系のモデルを組み合わせるのが有効だったりしました。

Cross Validation戦略

公開ノートの多くはdonorを使用したgroup k-foldを使用していたので私もそれを使いました。 ただ、上述の前処理の失敗を考えると日付でgroup k-foldしていれば良かったのかなと思いました。ミスやoverfittingに気づけるので。 一応、CVのスコアとpublic LBのスコアは概ね相関していました。

考察

まずモデルの話。テーブルデータに関してはGBDTが主流ですが今回のコンペに関しましてはDNNが強かったです。この件に関する考察は、DNNだと自然にmulti outputができるので目的変数間の相互作用は考慮できるからだと考えました。GBDTだと、目的変数一つ一つに対してしか最適化できないので(私の認識では)、こういった多出力のタスクではDNNが強かったのかなと思います。 あとは、単にデータ数と特徴量の数が莫大だったり、特徴量が解釈しづらいよくわかんないものだったりするのもDNNが強かった理由だと思います。

また、アンサンブルにGBDTモデルが効いたのは、目的変数間の相互作用を考慮できていない代わりに個々の目的変数に対して高い精度を出せていたからだと考えています。単に多様性が出たからなだけかもしれませんが。

反省点

謎の前処理をしてしまったのが大戦犯だと思います。上位のソリューションもざっくり見ましたが、ほかの戦略はおそらく間違っていないはず、、、 日付ごとに標準化していない、初期に構築したシンプルなモデル選べてたらprivateで銀メダルや銅メダルが取れてたので、もう少しprivateの分布を考慮して実験しておけばよかったです。

一つのミスで残念な結果になってしまいましたが、いろいろ学んだ点も多いですし、コード資産も得られたので良かったと思います。萎えましたが😭