How to Evaluate Models Using MLflow - The Databricks Blogの翻訳です。
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
現在の多くのデータサイエンティストやMLエンジニアは、モデルを管理するためにMLflowを活用しています。MLflowはMLライフサイクの全ての側面の管理を可能にするオープンソースのプラットフォームであり、実験、再現性確保、デプロイメント、モデルレジストリの様な機能を提供しています。MLモデルの開発における重要なステップは、新しいデータセットに対するパフォーマンスの評価です。
モチベーション
なぜモデルを評価するのでしょうか?
モデルの評価はMLライフサイクルの重要なパートです。これによって、データサイエンティストは自身のモデルのパフォーマンスの計測、解釈、説明が可能となります。モデルがなぜそのように動作しているのかに関して洞察を提供することで、モデル開発のタイムフレームを加速します。特にMLモデルの複雑性が増加するにつれて、MLモデルのパフォーマンスを迅速に観測、理解できる能力は、ML開発ジャーニーを成功させるためには重要となってきます。
MLflowにおけるモデル評価の状態
これまでは、ユーザーは分類モデルと回帰モデルの両方の評価をサポートするmlflow.evaluate APIを通じてpython_function (pyfunc)モデルフレーバーのMLflowモデルのパフォーマンスを評価することができました。これは、ビルトインのタスク固有のパフォーマンスメトリクス、パフォーマンスのプロット、モデルの説明を計算してMLflowトラッキングサーバーに記録します。
ビルトインの評価メトリックのセットに含まれないカスタムメトリクスを用いてMLflowモデルを評価するには、カスタムモデル評価器のプラフインを定義する必要がありました。これには、ModelEvaluatorインタフェースを実装するカスタム評価器クラスの作成、MLflowプラフインの一部として、評価器エントリーポイントの登録が含まれます。この厳密性と複雑性はユーザにとっては受け入れ難いものです。
内部の顧客サーベイによると、回答者の75%が精度やロスの様な基本的なメトリクスに加えて、頻繁あるいは常に特殊なビジネスフォーカスのメトリクスを使用していると回答しました。データサイエンティストはビジネスゴール(例:コンバージョン率)をより説明し、モデルの予測結果自身によって捕捉されない追加の経験則を含めるために、多くの場合これらのメトリクスを活用しています。
この記事では、ユーザー定義のカスタムメトリクスを用いてMLflowモデルを評価するための簡単かつ便利な方法をご紹介します。この機能によって、データサイエンティストはモデル評価ステージで容易にこのロジックを組み込むことができ、追加の後段の分析なしに、最もパフォーマンスの良いモデルをクイックに特定することができます。
使い方
ビルトインのメトリクス
MLflowでは、分類、回帰モデルの両方に対して一般的に使われるパフォーマンスやモデル説明可能性に関するメトリクスのセットを同梱していまうs。これらのメトリクスによるモデルの評価はわかりやすいものです。必要なのは、テストデータとターゲットを含む評価データセットを作成し、mlflow.evaluateを呼び出すことです。
モデルのタイプによって、異なるメトリクスが計算されます。ビルトインメトリクスに関する最新の情報については、mlflow.evaluateのAPIドキュメントのDefault Evaluator behavior sectionをご覧下さい。
サンプル
ビルトインメトリクスによる分類MLflowモデルの評価方法を示すシンプルなサンプルです。
最初に必要なライブラリをインポートします。
import xgboost
import shap
import mlflow
from sklearn.model_selection import train_test_split
次にデータセットを分割し、モデルをフィッティングさせ、評価データセットを作成します。
# load UCI Adult Data Set; segment it into training and test sets
X, y = shap.datasets.adult()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
# train XGBoost model
model = xgboost.XGBClassifier().fit(X_train, y_train)
# construct an evaluation dataset from the test set
eval_data = X_test
eval_data["target"] = y_test
最後にMLflowランをスタートし、mlflow.evaluateを呼び出します。
with mlflow.start_run() as run:
model_info = mlflow.sklearn.log_model(model, "model")
result = mlflow.evaluate(
model_info.model_uri,
eval_data,
targets="target",
model_type="classifier",
dataset_name="adult",
evaluators=["default"],
)
MLflowのUIで、記録されたメトリクスとアーティファクトを確認することができます。
カスタムメトリクス
カスタムメトリクスでモデルを評価するには、シンプルにカスタムメトリックの関数のリストをmlflow.evaluate APIに渡します。
関数定義の要件
カスタムメトリックの関数は、以下の順序で2つの必須のパラメーター、1つのオプションのパラメーターを受け取る必要があります:
-
eval_df
:prediction
とtarget
カラムを持つPandasあるいはSparkデータフレーム。 -
builtin_metrics
: ビルトインメトリクスを含むディクショナリー。例:回帰モデルにおいては、
builtin_metrics
は以下の様になります。JSON{ "example_count": 4128, "max_error": 3.815, "mean_absolute_error": 0.526, "mean_absolute_percentage_error": 0.311, "mean": 2.064, "mean_squared_error": 0.518, "r2_score": 0.61, "root_mean_squared_error": 0.72, "sum_on_label": 8520.4 }
-
(オプション)
artifacts_dir
: カスタムメトリック関数が生成されたアーティファクトをMLflowに記録する前に一時的に保存するために使用する一時ディレクトリのパス。例:環境に応じて見え方が異なることに注意してください。例えば、MacOSの場合は以下の様に見えます。
/var/folders/5d/lcq9fgm918l8mg8vlbcq4d0c0000gp/T/tmpizijtnvo
artifacts_dir
以外の場所にファイルアーティファクトが保存される際、mlflow.evaluateの実行が完了するまで、これらが永続化される様にしてください。
戻り値の要件
関数は生成されたメトリクスを表現するディクショナリーを返却し、オプションとして生成されたアーティファクトを表現する二つ目のディクショナリーを返却しなくてはなりません。両方のディクショナリーにおいては、それぞれのエントリーのキーは、対応するメトリックやアーティファクトの名前を表します。
それぞれのメトリックはスカラーでなくてはいけませんが、アーティファクトを定義する方法は複数あります。
- アーティファクトファイルへのパス
- JSONオブジェクトの文字列表現
- pandasデータフレーム
- numpyのarray
- matplotlibの図
- デフォルトのプロトコルによってpickleされるその他のオブジェクト
より詳細については、mlflow.evaluateのドキュメントを参照ください。
サンプル
カスタムメトリクスを使う実際のサンプルを見ていきましょう。このために、California Housingデータセットからトイモデルを作成します。
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import mlflow
import os
次にデータセットとモデルをセットアップします。
# loading the California housing dataset
cali_housing = fetch_california_housing(as_frame=True)
# split the dataset into train and test partitions
X_train, X_test, y_train, y_test = train_test_split(
cali_housing.data, cali_housing.target, test_size=0.2, random_state=123
)
# train the model
lin_reg = LinearRegression().fit(X_train, y_train)
# creating the evaluation dataframe
eval_data = X_test.copy()
eval_data["target"] = y_test
ここがエキサイティングな部分です。カスタムメトリクス関数の定義です!
def example_custom_metric_fn(eval_df, builtin_metrics, artifacts_dir):
"""
This example custom metric function creates a metric based on the ``prediction`` and
``target`` columns in ``eval_df`` and a metric derived from existing metrics in
``builtin_metrics``. It also generates and saves a scatter plot to ``artifacts_dir`` that
visualizes the relationship between the predictions and targets for the given model to a
file as an image artifact.
"""
metrics = {
"squared_diff_plus_one": np.sum(np.abs(eval_df["prediction"] - eval_df["target"] + 1) ** 2),
"sum_on_label_divided_by_two": builtin_metrics["sum_on_label"] / 2,
}
plt.scatter(eval_df["prediction"], eval_df["target"])
plt.xlabel("Targets")
plt.ylabel("Predictions")
plt.title("Targets vs. Predictions")
plot_path = os.path.join(artifacts_dir, "example_scatter_plot.png")
plt.savefig(plot_path)
artifacts = {"example_scatter_plot_artifact": plot_path}
return metrics, artifacts
最後に、これら全てをつなぎ合わせて、MLflowランをスタートしてmlflow.evaluateを呼び出します。
with mlflow.start_run() as run:
mlflow.sklearn.log_model(lin_reg, "model")
model_uri = mlflow.get_artifact_uri("model")
result = mlflow.evaluate(
model=model_uri,
data=eval_data,
targets="target",
model_type="regressor",
dataset_name="cali_housing",
custom_metrics=[example_custom_metric_fn],
)
デフォルトのメトリクス、アーティファクトと共に記録されたカスタムメトリクスやカスタムアーティファクトを確認することができます。ランのページの赤枠の領域が、記録されたカスタムメトリクスとカスタムアーティファクトを示しています。
プログラムから評価結果にアクセスする
ここまでは、MLflow UIでビルトインとカスタムメトリクスの評価結果を見てきました。しかし、mlflow.evaluateによって返却されるEvaluationResultオブジェクトを通じてプログラムからアクセスすることもできます。上述のカスタムメトリクスの例を続けて、プログラムからどの様に評価結果にアクセスできるのかを見ていきましょう。(ここでは、EvaluationResultのインスタンスがresult
であると仮定します。)
メトリクスの名前とスカラー値の両方を含むresult.metrics
ディクショナリーを通じて計算されたメトリクスすセットにアクセスすることができます。result.metrics
の中身は以下の様なものとなります。
{
'example_count': 4128,
'max_error': 3.8147801844098375,
'mean_absolute_error': 0.5255457157103748,
'mean_absolute_percentage_error': 0.3109520331276797,
'mean_on_label': 2.064041664244185,
'mean_squared_error': 0.5180228655178677,
'r2_score': 0.6104546894797874,
'root_mean_squared_error': 0.7197380534040615,
'squared_diff_plus_one': 6291.3320597821585,
'sum_on_label': 8520.363989999996,
'sum_on_label_divided_by_two': 4260.181994999998
}
同様に、result.artifacts
ディクショナリーを通じて一連のアーティファクトにアクセスすることができます。それぞれのエントリーの値はEvaluationArtifactオブジェクトとなります。result.artifacts
は以下の様になります。
{
'example_scatter_plot_artifact': ImageEvaluationArtifact(uri='some_uri/example_scatter_plot_artifact_on_data_cali_housing.png'),
'shap_beeswarm_plot': ImageEvaluationArtifact(uri='some_uri/shap_beeswarm_plot_on_data_cali_housing.png'),
'shap_feature_importance_plot': ImageEvaluationArtifact(uri='some_uri/shap_feature_importance_plot_on_data_cali_housing.png'),
'shap_summary_plot': ImageEvaluationArtifact(uri='some_uri/shap_summary_plot_on_data_cali_housing.png')
}
サンプルノートブック
内部動作
以下の図では、すべてが内部でどの様に動作しているのかを説明しています。
まとめ
この記事では以下をカバーしました。
- モデル評価の重要性と現在MLflowで何がサポートされているのか。
- MLflowユーザーがカスタムメトリクスを自分のMLflowモデルに組み込むことがなぜ重要なのか。
- デフォルトメトリクスによるモデル評価方法。
- カスタムメトリクスによるモデル評価方法。
- 背後でMLflowがどのようにモデル評価を行なっているのか。