Kedro を用いた分析コンペ向けのデータパイプライン構築
Kaggle Advent Calendar 2019 の9日目の記事です。
一応自己紹介を書いておくと、 Kaggle は mhiro2 という名前でここ1年くらい趣味としてやっています。
本業では、 MLOps の一環として、 GKE や BigQuery, Cloud Composer, MLflow などを活用した自社向けの機械学習基盤開発をやっています。 ML やデータ分析の理論や技術そのものよりは、 ML のサイクルを円滑に回すためのシステムデザインやアーキテクチャなどの仕組み化に関心があります。
はじめに
Kaggle をはじめとした分析コンペに取り組んでいる方の中には、自前のパイプラインを構築されている方も多くいらっしゃるかと思います。そもそもパイプラインとは何ぞや、という話ですが、EDA や特徴量のエンコードなどの前処理はもちろん、複数のモデルやパラメータでの学習やアンサンブル、 submit ファイル作成といった、どのコンペでも必要となる定型的な一連の処理を簡単に実行できるようにしたものというのが私の認識です。
本記事では、主にテーブルデータ形式のコンペに焦点を当てて、パイプライン構築について簡単に書いていきたいと思います。
分析コンペにおけるパイプライン構築の意義
そもそも何故パイプラインを構築するのか、何をパイプラインに求めるのか、については人によって意識の差があるかもしれませんが、私の認識では以下のようなものが理由として挙げられます。
- 汎用的な処理をテンプレートとしてまとめておくことで、同じようなコードをコンペの度に書かずに済むようにする
- コンペが変わってもモデルの学習に使うデータ形式は一定なので、データ整形や特徴量作成以降の処理を自動化して簡単に結果を出せるようにする
- yaml や json などのテキスト形式(半構造化データ)でモデルのパラメータや使用する特徴量の指定、学習のトラッキングを行う
例えばテーブルデータ形式のコンペだと、とりあえず pandas-profiling や TFDV でデータの傾向をざっくり掴んでから初期モデルの構築、CV 確認までを1ループ回して最初のベースラインを作るのが割とありがちな流れかと思います。
このような処理を実装する際、コピペを駆使すればもちろん簡単に実現可能ではありますが、一連の処理をモジュール化して簡単に再利用可能にしたものが、いわゆる(分析コンペ界隈で言われる)パイプラインに当たると思います。(@nyker_goto さんの vivid などが分かりやすい例)
前置きが長くなりましたが、本記事では Kedro というデータパイプラインを構築できる OSS を紹介するとともに、 Kaggle のようなコンペへの活用法について簡単に紹介したいと思います。
※私はプライベート (Kaggle) でも仕事でも Kedro を使っているわけではなく、本記事は便利そうなので調べてみたというスタンスです(ツッコミ歓迎)
Kedro とは
Kedro は QuantumBlack というロンドンのデータ分析企業(マッキンゼー傘下) が公開している、プロダクションレディなデータ分析用ワークフロー構築ツールです。公式の紹介ブログや動画を一応以下に貼っておきます。
特徴
Kedro の主な特徴としては、以下が挙げられます。
- Python で全てのワークフローを記述できる
- DAG のような形式でパイプラインを定義することができるので、 Sequential な実行と Parallel な実行を切り替えたり、パイプラインの途中から実行したりといった柔軟な処理が実現できる
- yaml でデータカタログを定義することによって csv, pickle, feather, parquet, DB上のテーブル など様々なデータ形式に対応でき、データのロード処理(ソースコード)は改変することなく複数のデータ形式や Pandas/Spark の切り替えなどに対応できる
- データセットや学習モデルをバージョン管理し、指定のバージョンでいつでも実行できるよう再現性を担保する
- Cookiecutter によるプロジェクトテンプレート(デフォルトテンプレートも提供しているが改変可)を利用することで、複数人での分析作業を統合的に管理できる
- Jupyter Notebook, Jupyter Lab とのインテグレーション
- 独自の拡張が比較的容易
ワークフローをコードベースで定義して実行できる類似の OSS としては、最近話題の Metaflow を始め、 d6tflow , Steppy, Sacred などなどたくさんありそうですが、私は比較記事を書けるほど詳しくないので本記事では触れません。(詳しい方、お待ちしております)
Kedro のアーキテクチャ
Kedro は高機能なので、公式のアーキテクチャ図を見てみると、一見使うのがかなり難しそうに見えるかと思います。
とは言え実際はこれらの機能全てを使う必要はなく、モジュール間も比較的疎結合な構造になっているため、フレームワーク的に一部の機能を呼び出して使うことも可能です。
Kedro を使う上で最低限抑えておいたほうがよい概念(プロジェクトの構成要素)について、以下に簡単に記載しておきます。
- Data Catalog
パイプラインで使用するデータセットを yaml 形式で定義するカタログ
データセット名、形式(csv, parquet など)、データセットのパス(local, S3 など)、ロードやセーブ時のオプションなどを指定 - Node
パイプラインで実行される処理の1単位
入力データセット、出力データセット、データ処理や機械学習のコードなどを Node 1つ1つに定義 - Pipeline
Node 間の依存関係や実行順序をパイプラインとして定義する(Pipeline 同士の結合なども可能)
decorator 機能 (Python のデコレータのようなもの)によって、パイプライン全体に機能を付加することも可能(実行時間のログ出力など) - Runner
オプションを受け取ってパイプラインを実行する
現在は直列実行と並列実行の2つの Runner を公式で提供 - Context
実験の設定(runner, catalog, pipeline, version など)をもとにパイプラインを実行する
上記は全てクラスとして定義されているため、継承することで自作の Pipeline や Runner を簡単に作成できる仕組みになっています。そのため、例えば Vaex や cuDF を使って一部の処理を高速化したい、という場合でも比較的簡単に導入が可能なはずです。また、 Context を自作することによって、 Kaggler 界隈でありがち?な yaml ベースの実験管理なども可能になりますし、 MLflow や Hyperdash を利用した GUI ベースの実験管理機能の付加も比較的簡単にできるはずです。(どれも実際に試したわけではないですが)
プロジェクトテンプレート
Kedro には公式のプロジェクトテンプレートがありますが、プロダクションを意識した構成になっているため、分析コンペのような高速なプロトタイピングの繰り返しにはあまり適していないと思われます。そこで、今回はテンプレートを使わずに機能を紹介するに留めたいと思います。(いい感じのテンプレート作ったよ、という方がいたらぜひ教えて下さい)
パイプライン構築例
文章ばかりダラダラと書いてしまいましたが、正直よく分からないと思うので、簡単なパイプライン処理の例を公式から引用して載せておきます。
実用的な例を示せず申し訳ないところですが、公式ドキュメントが非常に充実しているので、実際に使ってみる場合は最初に色々眺めてみると何となく感覚が掴めるかと思います。
まとめ
Kaggle Advent Calendar なのに Kedro の紹介記事になってしまいましたが、パイプライン構築に必要そうな一通りの機能を備えていて、開発も活発に行われているようなので、興味を持たれた方は是非使ってみてください。私自身も今後コンペで使っていければと思っているので、機会があれば、実際のコンペで使用したソースコードとして公開できればと思います。
—
※追記
@Minyus86 さんが Kedro を使用したパイプラインのパッケージを自作されており、アメフトコンペで使用した例も公開されているそうです。ぜひ参考にしてみてください。