はじめに
機械学習プロジェクトには様々なライブラリの依存関係があり、実行にはビルドされた環境が必要になる。MLflow Projectsを使うことで、他のデータサイエンティストとの共有や本番環境への移行のために、MLコードを再利用可能で再現性のある形でパッケージ化することができる。今回はMLflow Projectsについてまとめる。
環境情報
Databricks RunTime: 10.2 ML (includes Apache Spark 3.2.0, Scala 2.12)
MLflowとは
前回の記事でまとめたので、そちらをご参照ください。
MLflow Projectsとは
他のデータサイエンティスト(または自動化ツール)がコードを実行できるように、コードを整理して記述するためのフォーマット。パッケージングすることで、コードを管理するだけでなく、それが実行された環境も含めて管理できる。MLflow Projectsの実態はコードを含むファイルのディレクトリ、またはGitリポジトリになる。
MLflow Projectsの構成要素
- MLflow Projectsの構成例
MLflow_Projects ├── MLProject ├── conda.yaml └── main.py
YAML を使ってプロジェクトの構成要素を指定し、環境ファイルには、実行環境に関する詳細を記載する。コード自体は、モデルを作成したり、データを処理するためのステップを含めることができる。任意のコードを異なる言語で実行することができ、リモートVM、Sparkクラスタ、Databricksジョブなど、ローカルでもリモートでも実行可能である。
エントリーポイントとは:
プロジェクト内で実行可能なコマンドと、そのパラメータに関する情報。プロジェクト内の任意の .py や .sh ファイルをエントリーポイントとして呼び出すことができる。
環境ファイルとは:
プロジェクトのエントリポイントを実行するために使用されるべきソフトウェア環境が記載されたファイル。プロジェクト・コードで必要とされるすべてのライブラリの依存関係を含める必要がある。
基本的な操作
MLflow Projectsを作成する
MLflow Projectsの例として、MLproject ファイル、conda環境ファイル、train.pyファイルを作成する。
conda環境はconda.yamlで指定し、もしconda.yamlがない場合はMLflowはPython(特にCondaで利用可能な最新のPython)だけを含むConda環境を使用してプロジェクトを実行する。またプロジェクト内の任意の.pyまたは.shファイルは、明示的にパラメータを宣言することなく、エントリーポイントにすることができる。コマンドをパラメータ付きで実行する場合は、 --key <value> シンタックス
を使ってコマンドライン上の各パラメータを渡す。
MLProject ファイル
name: MLProject_example conda_env: conda.yaml entry_points: main: parameters: data_path: {type: str, default: "/dbfs/mnt/training/airbnb/sf-listings/airbnb-cleaned-mlflow.csv"} n_estimators: {type: int, default: 10} max_depth: {type: int, default: 20} max_features: {type: str, default: "auto"} command: "python train.py --data_path {data_path} --n_estimators {n_estimators} --max_depth {max_depth} --max_features {max_features}"
conda.yaml
name: conda_yaml_example channels: - defaults dependencies: - cloudpickle={cloudpickle.__version__} - numpy={numpy.__version__} - pandas={pandas.__version__} - scikit-learn={sklearn.__version__} - pip: - mlflow=={mlflow.__version__}
train.py
import click import mlflow.sklearn import pandas as pd from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score from sklearn.model_selection import train_test_split @click.command() @click.option("--data_path", default="/dbfs/mnt/training/airbnb/sf-listings/airbnb-cleaned-mlflow.csv", type=str) @click.option("--n_estimators", default=10, type=int) @click.option("--max_depth", default=20, type=int) @click.option("--max_features", default="auto", type=str) def mlflow_rf(data_path, n_estimators, max_depth, max_features): with mlflow.start_run() as run: # Import the data df = pd.read_csv(data_path) X_train, X_test, y_train, y_test = train_test_split(df.drop(["price"], axis=1), df[["price"]].values.ravel(), random_state=42) # Create model, train it, and create predictions rf = RandomForestRegressor(n_estimators=n_estimators, max_depth=max_depth, max_features=max_features) rf.fit(X_train, y_train) predictions = rf.predict(X_test) # Log model mlflow.sklearn.log_model(rf, "random-forest-model") # Log params mlflow.log_param("n_estimators", n_estimators) mlflow.log_param("max_depth", max_depth) mlflow.log_param("max_features", max_features) # Log metrics mlflow.log_metric("mse", mean_squared_error(y_test, predictions)) mlflow.log_metric("mae", mean_absolute_error(y_test, predictions)) mlflow.log_metric("r2", r2_score(y_test, predictions)) if __name__ == "__main__": mlflow_rf() # Note that this does not need arguments thanks to click
プロジェクトを実行する
mlflow.projects.run()
コマンドを使ってMLflow Projectを実行する
import mlflow mlflow.projects.run(uri=working_path, parameters={ "data_path": "/dbfs/mnt/training/airbnb/sf-listings/airbnb-cleaned-mlflow.csv", "n_estimators": 10, "max_depth": 20, "max_features": "auto" })
mlflow.projects.run()
コマンドを使って実行した場合は、UIに実行したコマンド内容が記載される。
まとめ
今回はMLflow Projectsについてまとめた。次回はMLflow Modelsについてまとめる。