Machine Learning: MLOpsとMLflow入門 — 実験トラッキングと再現性
最終更新:2026-08-26
実験管理のないMLは、Gitのないコードのようなものです。どのバージョンがベストなのか、誰にもわかりません。
1. この章で学ぶこと
- MLOpsの概念:DevOpsをMLに拡張し、MLライフサイクル全体を管理する
- MLflowの4つのコアコンポーネント:Tracking / Projects / Models / Model Registry
- 実践的な実験トラッキング:パラメータ、メトリクス、モデル、チャートの記録とモデルバージョンの比較
- モデルレジストリ:モデルステージの管理(Staging → Production)、バージョンのロールバック
- Bobの実験管理:SalesPredictの50回以上の実験を体系的に管理する方法
2. MLチームリーダーの実体験
(1) 苦しみ:50回の実験の末、どのモデルがベストかわからない
Bobは3週間で50回以上の実験を行いました。アルゴリズムも、特徴量も、ハイパーパラメータもすべて異なります。各実験のパラメータと結果は、Jupyter Notebook、Slackのメッセージ、付箋にあちこちに散らばっていました。プロダクトマネージャーから「今、どのモデルが一番いいの?」と聞かれたとき、Bobは記録を2時間かけて掘り起こしましたが、それでも確信が持てませんでした。実験の混乱は、MLプロジェクトでは日常茶飯事です。
(2) MLflowによる解決策
MLflowは、すべての実験のパラメータ、メトリクス、モデル、チャートを自動的に記録します。すべての実験が一箇所に集約され、比較・追跡が可能になります。
PYTHON
import mlflow
mlflow.set_experiment("SalesPredict-Revenue")
with mlflow.start_run(run_name="xgboost_v1"):
mlflow.log_params({"n_estimators": 300, "max_depth": 6, "learning_rate": 0.1})
mlflow.log_metrics({"r2": 0.89, "mae": 8.5})
mlflow.sklearn.log_model(model, "model")
(3) 効果:ベストな実験を2秒で見つけ、実験効率が3倍に
MLflowを導入したことで、Bobは過去のベストモデルを2秒で見つけられるようになりました。新しい実験は過去の実行結果と自動的に比較され、チームの協業効率は3倍になりました。
3. MLOpsの概念
(1) MLライフサイクル管理
MLOpsとは、DevOpsをML領域に拡張したものです。コードのバージョンだけでなく、データのバージョン、実験のバージョン、モデルのバージョンも管理します。
graph TB
DATA[Data Engineering<br/>Version & Pipeline] --> EXP[Experiment<br/>Track & Compare]
EXP --> REG[Model Registry<br/>Version & Stage]
REG --> DEPLOY[Deployment<br/>Serve & Scale]
DEPLOY --> MON[Monitoring<br/>Drift & Performance]
MON -->|Retrain Trigger| DATA
(2) MLと従来のソフトウェアエンジニアリングの違い
| 観点 | ソフトウェアエンジニアリング | MLエンジニアリング |
|---|---|---|
| バージョン管理 | コード | コード + データ + モデル |
| テスト | 単体テスト | データテスト + モデルテスト |
| デプロイ | 一度デプロイ | 継続的な再学習 |
| 劣化の原因 | バグ | データドリフト / コンセプトドリフト |
| 再現性 | コード = 結果 | コード + データ + パラメータ = 結果 |
4. MLflowの4つのコアコンポーネント
(1) MLflow Tracking
▶ サンプル:実験パラメータとメトリクスの記録
PYTHON
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score, mean_absolute_error
from sklearn.model_selection import train_test_split
import numpy as np
mlflow.set_tracking_uri("sqlite:///mlflow.db")
mlflow.set_experiment("SalesPredict-Revenue")
rng = np.random.default_rng(42)
n = 1000
X = rng.uniform(0, 100, (n, 5))
y = 50 + 0.8 * X[:, 0] + 1.2 * X[:, 1] + rng.normal(0, 5, n)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Experiment 1: Random Forest
with mlflow.start_run(run_name="rf_baseline"):
params = {"n_estimators": 100, "max_depth": 10}
mlflow.log_params(params)
model = RandomForestRegressor(**params, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
mlflow.log_metrics({"r2": r2, "mae": mae})
mlflow.sklearn.log_model(model, "model")
print(f"RF: R²={r2:.4f}, MAE={mae:.2f}")
# Experiment 2: XGBoost
import xgboost as xgb
with mlflow.start_run(run_name="xgboost_v1"):
params = {"n_estimators": 300, "max_depth": 6, "learning_rate": 0.1}
mlflow.log_params(params)
model = xgb.XGBRegressor(**params, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
mlflow.log_metrics({"r2": r2, "mae": mae})
mlflow.xgboost.log_model(model, "model")
print(f"XGB: R²={r2:.4f}, MAE={mae:.2f}")
出力:
TEXT
📖 参照専用
# Execution successful
▶ サンプル:実験の検索と比較
PYTHON
import mlflow
# Query experiments
experiment = mlflow.get_experiment_by_name("SalesPredict-Revenue")
runs = mlflow.search_runs(experiment_ids=[experiment.experiment_id])
# Sort by R² (best first)
best_runs = runs.sort_values("metrics.r2", ascending=False)
print("Top 3 runs by R²:")
print(best_runs[["run_name", "metrics.r2", "metrics.mae",
"params.n_estimators", "params.max_depth"]].head(3))
出力:
TEXT
📖 参照専用
Top 3 runs by R²:
(2) MLflow ModelsとRegistry
▶ サンプル:モデルの登録とステージ管理
PYTHON
import mlflow
# Register a model
model_uri = f"runs:/{run_id}/model"
mlflow.register_model(model_uri, "SalesPredict-Revenue-Model")
# Transition model stage
client = mlflow.tracking.MlflowClient()
client.transition_model_version_stage(
name="SalesPredict-Revenue-Model",
version=1,
stage="Staging",
)
# Promote to Production
client.transition_model_version_stage(
name="SalesPredict-Revenue-Model",
version=1,
stage="Production",
)
# Load production model
model = mlflow.sklearn.load_model("models:/SalesPredict-Revenue-Model/Production")
出力:
TEXT
📖 参照専用
# Execution successful
| レジストリステージ | 意味 | 典型的なアクション |
|---|---|---|
| None | 登録直後 | 自動テスト |
| Staging | 検証待ち | A/Bテスト |
| Production | 本番環境で稼働中 | オンラインサービング |
| Archived | 引退済み | 記録の保管 |
5. MLflow Projectsと自動ロギング
▶ サンプル:autologによる自動ロギング
PYTHON
import mlflow
import mlflow.sklearn
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split
import numpy as np
# Auto-log: automatically record all parameters, metrics, and model
mlflow.sklearn.autolog()
rng = np.random.default_rng(42)
X = rng.uniform(0, 100, (1000, 5))
y = 50 + 0.8 * X[:, 0] + rng.normal(0, 5, n)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
with mlflow.start_run(run_name="gb_autolog"):
model = GradientBoostingRegressor(n_estimators=100, max_depth=5, learning_rate=0.1, random_state=42)
model.fit(X_train, y_train)
# autolog captures everything automatically!
出力:
TEXT
📖 参照専用
# Execution successful
| autologフレームワーク | 自動的に記録される内容 |
|---|---|
| sklearn | パラメータ、メトリクス、モデル、混同行列 |
| xgboost | パラメータ、メトリクス、特徴量重要度 |
| lightgbm | パラメータ、メトリクス、特徴量重要度 |
| pytorch | パラメータ、メトリクス、モデル |
▶ サンプル:カスタムチャートの記録
PYTHON
import mlflow
import matplotlib.pyplot as plt
import numpy as np
with mlflow.start_run(run_name="feature_analysis"):
# Create and log a plot
fig, ax = plt.subplots()
ax.barh(["feat_1", "feat_2", "feat_3", "feat_4", "feat_5"],
[0.35, 0.25, 0.15, 0.10, 0.05])
ax.set_xlabel("Importance")
ax.set_title("Feature Importance")
plt.tight_layout()
mlflow.log_figure(fig, "feature_importance.png")
plt.close()
# Log artifacts (any file)
# mlflow.log_artifact("local_file.csv")
出力:
TEXT
📖 参照専用
# Execution successful
6. Bobの50回以上の実験管理の実践
▶ サンプル:バッチ実験トラッキングフレームワーク
PYTHON
import mlflow
import mlflow.sklearn
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.model_selection import cross_val_score
from sklearn.metrics import r2_score, mean_absolute_error
import numpy as np
mlflow.set_experiment("SalesPredict-Benchmark")
# Simulated data
rng = np.random.default_rng(42)
X = rng.uniform(0, 100, (2000, 10))
y = 50 + X[:, :5] @ [0.8, 1.2, -0.5, 0.3, 0.1] + rng.normal(0, 5, 2000)
# Systematic experiment tracking
experiments = [
{"name": "linear_baseline", "model": LinearRegression(), "params": {}},
{"name": "ridge_alpha1", "model": Ridge(alpha=1), "params": {"alpha": 1}},
{"name": "rf_100", "model": RandomForestRegressor(n_estimators=100, random_state=42),
"params": {"n_estimators": 100}},
{"name": "rf_300", "model": RandomForestRegressor(n_estimators=300, random_state=42),
"params": {"n_estimators": 300}},
{"name": "xgb_d6_lr01", "model": xgb.XGBRegressor(max_depth=6, learning_rate=0.1, random_state=42),
"params": {"max_depth": 6, "learning_rate": 0.1}},
]
for exp in experiments:
with mlflow.start_run(run_name=exp["name"]):
mlflow.log_params(exp["params"])
cv_scores = cross_val_score(exp["model"], X, y, cv=5, scoring="r2")
mlflow.log_metrics({
"cv_r2_mean": cv_scores.mean(),
"cv_r2_std": cv_scores.std(),
})
# Find best experiment
runs = mlflow.search_runs(
experiment_ids=[mlflow.get_experiment_by_name("SalesPredict-Benchmark").experiment_id],
order_by=["metrics.cv_r2_mean DESC"],
)
print("Best experiments:")
print(runs[["run_name", "metrics.cv_r2_mean", "metrics.cv_r2_std"]].head(5))
出力:
TEXT
📖 参照専用
Best experiments:
❓ よくある質問
Q MLflowとWeights & Biases(W&B)のどちらを使うべきですか?
A MLflowはオープンソースで無料で、セルフホスティングが可能であり、機能も充実しています。W&Bはより優れた可視化と簡単なチーム協業を提供しますが、商用ライセンスです。個人や小規模チームにはMLflowを、大規模チームにはW&Bをおすすめします。
Q MLflow Tracking Serverはどうやってデプロイしますか?
A ローカル開発では
mlflow server --backend-store-uri sqlite:///mlflow.dbを使用します。本番環境では、PostgreSQL + オブジェクトストレージ(S3/GCS)+ リバースプロキシを使用します。Q autologと手動ロギングを併用できますか?
A はい、可能です。autologが標準的な情報を取得し、手動ロギングでカスタムコンテンツ(ビジネスメトリクス、チャートなど)を補完します。推奨アプローチ:autologをベースラインとして活用し、追加情報は手動で記録することです。
Q モデルレジストリは本当に必要ですか?
A 絶対に必要です。レジストリがなければ、モデルファイルがあちこちに散らばり、どれが本番環境で使われているのか、どれが古いのかもわかりません。レジストリはバージョン管理、ステージ管理、ロールバック機能を提供します。
Q 大量の実験をどう整理すればよいですか?
A グループ化にはexperiment(例:SalesPredict-Revenue / SalesPredict-Churn)、ラベル付けにはタグ(例:team=bob, priority=high)、区別にはrun_name(例:xgboost_v3_tuned)を使用します。
Q 実験の再現性をどう確保すればよいですか?
A MLflowはパラメータ + コードバージョン + データバージョン + 乱数シードを記録します。
mlflow.sklearn.load_model(run_id)でモデルを完全に復元できます。データバージョン管理にはDVCを併用しましょう。📖 まとめ
- MLOps = MLのためのDevOps:データバージョン、実験バージョン、モデルバージョンのライフサイクル全体を管理する
- MLflowの4つのコアコンポーネント:Tracking(記録)+ Projects(パッケージ化)+ Models(フォーマット)+ Registry(登録)
- トラッキングの基本:log_params + log_metrics + log_model — すべての実験を自動で記録
- モデルレジストリでモデルステージを管理:None → Staging → Production → Archived
- autologがパラメータ、メトリクス、モデルを自動取得し、手動ロギングの負担を軽減
- 再現性 = パラメータ + データ + 乱数シード + コードバージョンの完全な記録
📝 練習問題
- 基礎(難易度 ⭐):MLflowをインストールし、ローカルのTracking Serverを起動して、パラメータ(lr=0.01)とメトリクス(r2=0.85)を含む実験を1件記録してください。ヒント:
pip install mlflow+mlflow.start_run()。 - 中級(難易度 ⭐⭐):autologを使ってsklearnのRandomForestRegressorの学習過程を記録し、すべての実行結果を検索してR²でソートしてください。ヒント:
mlflow.sklearn.autolog()+search_runs()。 - チャレンジ(難易度 ⭐⭐⭐):Bobの実験管理フレームワークを実装してください。SalesPredictデータで5つのモデルを実行し、各実行のパラメータ/メトリクス/モデルをMLflowに自動記録し、ベストモデルをレジストリに登録して、Productionモデルを読み込んで予測を行ってください。ヒント:第6章のバッチ実験サンプルを参照してください。