Tak's Notebook

Kaggle, Machine Learning, Engineering

Rust で Kaggle の Titanic コンペにサブミットする

概要

Rust の勉強がてら Kaggle の Titanic コンペにサブミットするコードを書いたのでブログにまとめた。

実装方針

  • loader クレートで csv ファイルをロードし、独自のデータクラスに変換する
    • 明示的に型定義を行う
  • Runner トレイトが以下のトレイトをメンバーに持って cross validation を実行する
    • FeatureTransformer
    • KFold
    • Model
  • main 内で cross validation の実行の返り値から、よしなにスコア計算したり、submission を作ったりする

実装

実装の詳細は GitHub で公開している。

github.com

詳細はここでは割愛する。以下、工夫点や雑感など。

  • consts
    • 定数などを定義する
  • loader
    • csv データを独自のデータクラスに変換する
    • csv データを読み込み時には型情報が欠落するので、カラムごとに型を明示的にパースする必要がある
      • Option にして、エラーハンドリングをする必要がある
    • train, test で列が同一でないのでスライスするインデックスがハードコードになってしまう
    • Pandas のありがたみ(気をつけないと Null に気づかない場合や、 int が勝手に float に cast されたり)
  • feature
    • fit, transform のメソッドを持ったトレイトを用意
    • 実装クラスで具体的な特徴量生成を行うクラスを実装
  • kfold
    • new, split のメソッドを持ったトレイトを用意
    • 実装クラスとして StratifiedKFold クラスを実装
  • model
    • train, predict, save_model のメソッドを持ったトレイトを用意
    • 実装クラスとして LightGBMModel クラスを実装
  • runner
    • FeatureTransformer トレイト, KFold トレイト, Model トレイト をメンバーに持ち run_cv メソッドを持ったトレイトを用意
  • main
    • データをロードし、ランナーのインスタンス後に、run_cv に train, test を渡す
    • result をよしなに変換してスコアを計算したり、Submission を作ったり

ディレクトリ構造

Workspace モードを使って実験ごと(crates ディレクトリ以下の expXXX ディレクトリごと)に Cargol.toml を共通化することもできるが、Kaggle においては外部クレート間の依存で衝突が起こる可能性もあるので、あえて実験ごとに Cargo.toml を分けるディレクトリ構造にした。

$ exa -T
.
├── crates
│  ├── exp001
│  │  ├── Cargo.lock
│  │  ├── Cargo.toml
│  │  └── src
│  │     ├── config.rs
│  │     ├── consts.rs
│  │     ├── feature.rs
│  │     ├── kfold.rs
│  │     ├── lib.rs
│  │     ├── loader.rs
│  │     ├── main.rs
│  │     ├── metrics.rs
│  │     ├── model.rs
│  │     ├── runner.rs
│  │     └── submission.rs
│  └── exp002
│     ├── Cargo.lock
│     ├── Cargo.toml
│     └── src
│        ├── config.rs
│        ├── consts.rs
│        ├── feature.rs
│        ├── kfold.rs
│        ├── lib.rs
│        ├── loader.rs
│        ├── main.rs
│        ├── metrics.rs
│        ├── model.rs
│        ├── runner.rs
│        └── submission.rs
├── input
├── Makefile.toml
├── output
│  ├── exp001
│  │  ├── models
│  │  └── submissions
│  └── exp002
│     ├── models
│     └── submissions
└── README.md

スコア

当然スコアは高くないが、ひとまずそれなりの値が出た。

Fold 1
Accuracy: 0.8435754189944135
Fold 2
Accuracy: 0.8324022346368715
Fold 3
Accuracy: 0.8426966292134831
Fold 4
Accuracy: 0.8539325842696629
Fold 5
Accuracy: 0.751412429378531
CV Accuracy: 0.8249158249158249
Public Score: 0.75119

便利ツール

cargo-make

Rust 製のタスクランナー。cargo install でインストールできる。 特に Cargo 周りのサポートが手厚いが、 Rust コードの実行や Shellscript の実行などもサポートしている。

github.com

ToDo

まとめ

Python の便利さを再確認しつつ、Rust で書くことで抽象化の程度や型の厳密性がもたらす再利用性の高さや安全性を考慮した実装のアイデアPython でも活かせるのではないかと感じた。