Python先日MLOpsの勉強会に出てました。www.nogawanogawa.comその場では、「ワークフローライブラリ使ってるとなんかイケてるんだなあ」くらいにしか思ってなかったんですが、機械学習の実験をしていて必要性を感じる場面があったので、試しに使ってみることにしました。勉強会ではgokartを推してたんですけど、今回はgokartでラップされる元になってるluigiを使ってみたのでそのメモです。ワークフローluigiについて考える前に、「そもそも機械学習のワークフローとは?」ってところから確認します。あることが一般的です。機械学習では、このような処理の流れを定義する必要があり、luigiを始めとする多くのワークフローライブラリではこのワークフローの記述・管理を簡単にします。具体的に何が嬉しいの?実務での機械学習アプリケーションは、データ量・計算量も多く、モデルは複雑になりがちで、その上データの傾向に合わせてモデルをメンテナンスし続ける必要があります。そんな状況下で起こるシチュエーションとしては、コードが複雑になりすぎて何がどうなってるか解読しにくいモデルを作ったはいいが、再現性が取れない処理に非常に長時間を要し、トライアンドエラーになりがちな機械学習プロジェクトの開発速度低下などなど、機械学習ならではの難しさが出てしまいます。再実行の時間の削減などを(他にもきっとメリットはあるとは思いますが)実現するのが、この手のライブラリを使用するメリットのようです。luigiluigiはSpotifyがOSSとして開発している、バッチジョブのパイプラインを構築するワークフローライブラリです。github.com公式のドキュメントはこちら。luigi.readthedocs.io名前の由来は、機械学習のワークフローを配管にたとえて、それを管理する「配管工」のキャラクターである某ゲームキャラクターが由来になっているようです。赤い方じゃないのは、単純にコーポレートカラー的に緑だったからでしょうか。なんにせよ、洒落てますね!説明資料Spotifyの中の方の説明資料があるので、基本的なところはこちらをご参照ください。Freider書き方luigiでは、処理の最小単位をTaskと呼ばれるClassで扱い、このTaskの中身を記述していくことでパイプライン全体を記述します。各Taskには何を書くかというと、requiresoutputrunの3種類のメソッドを記述します。requiresでは依存Taskを戻り値として記述します。前の処理がある場合には、依存関係のあるTaskのクラスを戻り値に指定します。複数のTaskに処理に依存している場合には、戻り値を複数にします。outputではTaskの出力オブジェクトを記述します。出力オブジェクトは複数取ることもできますが、ドキュメントによればoutputオブジェクトは単一にするのが望ましいとのことです。runではoutputを作るまでの処理を記述します。requiresで記述したTaskのoutputオブジェクトを使用したい場合には、inputメソッドによって使用することができます。以上のように記述することが強制されるので、誰が書いても同じようなコードになります。これは、コードの保守性の観点から考えても非常に良いことだと思います。一点注意すべきは、Task間のデータ受け渡しがファイル形式になりがちという点です。大きな処理を作る際には、ファイルIOにかかる時間を考慮して設計する必要がありそうです。pageタスクの進行状況についてブラウザで可視化する機能もついています。各タスクの依存関係のグラフも可視化できるようになっています。タスクの関係や進行状況が直感的に確認できるのは良さそうです。使ってみるそんなこんなで使ってみます。luigi簡単ですね。Titanicでやってみるkaggleのチュートリアルでおなじみのタイタニックの問題をluigiを使ってやってみます。普通はnotebookで実験していくのは百も承知ですが、あえてluigiで書くとどんな感じになるかやってみます。もとの実装こんな感じでしょうか。流れとしては以下のようにシンプルな形になっています。欠損値の補完モデルの学習gist.github.comたまたま手元にあったコードなんでちょっとアレですが、まあ動いてました。luigiを使って書いてみるそれではluigiを使ってワークフローを作ってみます。素直に前処理と学習と推論に分けてみました。動かしてみるブラウザで管理画面を使用する場合には、先にデーモンを起動しておきます。luigid実行するときにはこんな感じになります。--local-schedulerブラウザで処理状況の確認をする場合に"--local-scheduler"を外して実行します。Predictワークフローを可視化するhttp://localhost:8082にアクセスすると、上のような画面でフローの進捗や依存関係を可視化する事ができます。その他の特徴として、なにかの原因で処理が途中で中断してしまっても、実行をやり直せばluigiが自動的に未完了の箇所から処理を再開してくれます。これは、すでに前のTaskのoutputが指定のディレクトリに存在するかを判断しているようで、それらが存在していれば処理をスキップするようです。参考にさせていただいた記事こちらの記事を参考にさせていただきました。今回はluigiを使ってみました。実感としては、notebookなどでプロトタイピングが終わった後、プロダクションに乗せて実運用する際には、たしかに使えると思いました。処理が止まった際もどこまで完了しているか途中経過を確認できますし、途中から再実行することもできるので運用としても助かりそうです。使えてない機能もたくさんありますので、そのへんは使いながら慣れていきたいと思います。(CD4ML)Twitter見てたら、こちらを見かけました。ニュースコーパスで遊んでみる(3回目)この前はこんな感じにやってました。(1)月別アーカイブはてなブログをはじめよう!nogawanogawaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。