088 MLflow로 실험 추적하기
키워드: MLflow, 실험 추적, experiment tracking
개요
MLflow는 머신러닝 실험을 추적하고 관리하는 오픈소스 플랫폼입니다. FLAML AutoML 실험을 MLflow로 추적하면 모델 비교, 재현성 확보, 협업이 용이해집니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
flaml[automl], mlflow
pip install flaml[automl] mlflow pandas numpy
MLflow 기초
import mlflow
import numpy as np
import pandas as pd
# 088 MLflow 개념
concepts = {
'개념': ['Experiment', 'Run', 'Parameter', 'Metric', 'Artifact'],
'설명': [
'관련 실험들의 컨테이너',
'개별 실험 실행',
'모델 설정값',
'성능 지표',
'모델 파일, 그래프 등'
],
'예시': [
'churn_prediction',
'lgbm_trial_01',
'n_estimators=100',
'accuracy=0.85',
'model.pkl, feature_importance.png'
]
}
print("MLflow 핵심 개념:")
print(pd.DataFrame(concepts).to_string(index=False))
MLflow 설정
# 088 로컬 MLflow 설정
mlflow.set_tracking_uri("sqlite:///mlflow.db") # 로컬 DB
mlflow.set_experiment("flaml_automl_experiment")
print(f"추적 URI: {mlflow.get_tracking_uri()}")
print(f"실험: flaml_automl_experiment")
데이터 준비
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# 088 데이터 생성
np.random.seed(42)
X, y = make_classification(n_samples=2000, n_features=20,
n_informative=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
print(f"학습 데이터: {X_train.shape}")
print(f"테스트 데이터: {X_test.shape}")
FLAML + MLflow 기본 연동
from flaml import AutoML
from sklearn.metrics import accuracy_score, roc_auc_score, f1_score
# 088 MLflow run으로 FLAML 실험 추적
with mlflow.start_run(run_name="flaml_basic"):
# 파라미터 로깅
params = {
"time_budget": 60,
"metric": "accuracy",
"estimator_list": "lgbm,xgboost,rf",
"seed": 42
}
mlflow.log_params(params)
# FLAML 학습
automl = AutoML()
automl.fit(
X_train, y_train,
task="classification",
metric="accuracy",
time_budget=60,
estimator_list=['lgbm', 'xgboost', 'rf'],
seed=42,
verbose=1
)
# 예측 및 평가
y_pred = automl.predict(X_test)
y_proba = automl.predict_proba(X_test)[:, 1]
# 메트릭 로깅
metrics = {
"test_accuracy": accuracy_score(y_test, y_pred),
"test_roc_auc": roc_auc_score(y_test, y_proba),
"test_f1": f1_score(y_test, y_pred),
"best_loss": automl.best_loss,
"n_trials": len(automl.config_history)
}
mlflow.log_metrics(metrics)
# 결과 로깅
mlflow.log_param("best_estimator", automl.best_estimator)
mlflow.log_param("best_config", str(automl.best_config))
# 모델 저장
mlflow.sklearn.log_model(automl, "model")
print(f"\n=== MLflow 로깅 완료 ===")
print(f"Run ID: {mlflow.active_run().info.run_id}")
for name, value in metrics.items():
print(f" {name}: {value:.4f}")
자동 로깅 활성화
# 088 MLflow 자동 로깅 (scikit-learn 호환 모델)
mlflow.autolog()
with mlflow.start_run(run_name="flaml_autolog"):
automl_auto = AutoML()
automl_auto.fit(
X_train, y_train,
task="classification",
time_budget=30,
verbose=0
)
print("자동 로깅으로 실험 추적됨")
# 088 자동 로깅 비활성화 (필요시)
mlflow.autolog(disable=True)
여러 실험 비교
# 088 다양한 설정으로 실험
experiments = [
{"time_budget": 30, "estimator_list": ['lgbm'], "name": "lgbm_only"},
{"time_budget": 30, "estimator_list": ['xgboost'], "name": "xgb_only"},
{"time_budget": 30, "estimator_list": ['rf'], "name": "rf_only"},
{"time_budget": 60, "estimator_list": ['lgbm', 'xgboost', 'rf'], "name": "ensemble"},
]
for exp_config in experiments:
with mlflow.start_run(run_name=exp_config["name"]):
# 파라미터 로깅
mlflow.log_params({
"time_budget": exp_config["time_budget"],
"estimator_list": str(exp_config["estimator_list"])
})
# 학습
automl_exp = AutoML()
automl_exp.fit(
X_train, y_train,
task="classification",
time_budget=exp_config["time_budget"],
estimator_list=exp_config["estimator_list"],
verbose=0
)
# 평가
y_pred = automl_exp.predict(X_test)
y_proba = automl_exp.predict_proba(X_test)[:, 1]
mlflow.log_metrics({
"accuracy": accuracy_score(y_test, y_pred),
"roc_auc": roc_auc_score(y_test, y_proba)
})
mlflow.log_param("best_estimator", automl_exp.best_estimator)
print(f"{exp_config['name']}: {automl_exp.best_estimator}, "
f"AUC={roc_auc_score(y_test, y_proba):.4f}")
아티팩트 저장
import matplotlib.pyplot as plt
import json
with mlflow.start_run(run_name="with_artifacts"):
# FLAML 학습
automl_art = AutoML()
automl_art.fit(X_train, y_train, task="classification",
time_budget=30, verbose=0)
y_pred = automl_art.predict(X_test)
y_proba = automl_art.predict_proba(X_test)[:, 1]
# 메트릭 로깅
mlflow.log_metrics({
"accuracy": accuracy_score(y_test, y_pred),
"roc_auc": roc_auc_score(y_test, y_proba)
})
# 1. 특성 중요도 그래프
if hasattr(automl_art.model.estimator, 'feature_importances_'):
importance = automl_art.model.estimator.feature_importances_
plt.figure(figsize=(10, 6))
plt.barh(range(len(importance)), importance)
plt.xlabel('Importance')
plt.title('Feature Importance')
plt.savefig('feature_importance.png', dpi=100, bbox_inches='tight')
mlflow.log_artifact('feature_importance.png')
plt.close()
# 2. 학습 이력 저장
history = {str(k): str(v) for k, v in automl_art.config_history.items()}
with open('training_history.json', 'w') as f:
json.dump(history, f, indent=2)
mlflow.log_artifact('training_history.json')
# 3. 최적 설정 저장
best_config = {
'best_estimator': automl_art.best_estimator,
'best_config': str(automl_art.best_config),
'best_loss': automl_art.best_loss
}
with open('best_config.json', 'w') as f:
json.dump(best_config, f, indent=2)
mlflow.log_artifact('best_config.json')
print("아티팩트 저장 완료")
모델 레지스트리
# 088 모델 등록 (프로덕션 배포용)
from mlflow.tracking import MlflowClient
client = MlflowClient()
# 088 최신 run에서 모델 등록
with mlflow.start_run(run_name="model_registry_demo"):
automl_reg = AutoML()
automl_reg.fit(X_train, y_train, task="classification",
time_budget=30, verbose=0)
y_pred = automl_reg.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
mlflow.log_metric("accuracy", accuracy)
# 모델 로깅 및 등록
model_uri = mlflow.sklearn.log_model(
automl_reg,
"model",
registered_model_name="flaml_classifier"
)
print(f"모델 등록됨: flaml_classifier")
print(f"모델 URI: {model_uri.model_uri}")
실험 결과 조회
# 088 실험 결과 조회
experiment = mlflow.get_experiment_by_name("flaml_automl_experiment")
if experiment:
runs = mlflow.search_runs(
experiment_ids=[experiment.experiment_id],
order_by=["metrics.accuracy DESC"]
)
print("\n=== 실험 결과 (정확도 순) ===")
if len(runs) > 0:
display_cols = ['run_id', 'metrics.accuracy', 'params.best_estimator']
available_cols = [c for c in display_cols if c in runs.columns]
print(runs[available_cols].head(10).to_string())
MLflow UI 실행 방법
ui_instructions = """
=== MLflow UI 실행 방법 ===
1. 터미널에서 실행:
mlflow ui --backend-store-uri sqlite:///mlflow.db
2. 브라우저에서 접속:
http://127.0.0.1:5000
3. UI에서 가능한 작업:
- 실험 비교 (차트, 테이블)
- 파라미터/메트릭 필터링
- 아티팩트 다운로드
- 모델 버전 관리
4. 원격 서버 설정 (팀 협업용):
mlflow server \\
--backend-store-uri postgresql://user:pass@host/db \\
--default-artifact-root s3://bucket/mlflow
"""
print(ui_instructions)
커스텀 MLflow 래퍼
class FLAMLMLflowTracker:
"""FLAML + MLflow 통합 래퍼"""
def __init__(self, experiment_name="flaml_experiment"):
mlflow.set_experiment(experiment_name)
self.automl = None
def train_and_log(self, X_train, y_train, X_test, y_test,
run_name="flaml_run", **flaml_params):
"""학습 및 MLflow 로깅"""
with mlflow.start_run(run_name=run_name):
# 파라미터 로깅
mlflow.log_params(flaml_params)
# FLAML 학습
self.automl = AutoML()
self.automl.fit(X_train, y_train, **flaml_params)
# 평가
y_pred = self.automl.predict(X_test)
y_proba = self.automl.predict_proba(X_test)[:, 1]
# 메트릭 로깅
metrics = {
"accuracy": accuracy_score(y_test, y_pred),
"roc_auc": roc_auc_score(y_test, y_proba),
"f1": f1_score(y_test, y_pred)
}
mlflow.log_metrics(metrics)
# 결과 로깅
mlflow.log_param("best_estimator", self.automl.best_estimator)
# 모델 저장
mlflow.sklearn.log_model(self.automl, "model")
print(f"Run 완료: {run_name}")
return metrics
# 088 래퍼 사용
tracker = FLAMLMLflowTracker("flaml_wrapper_demo")
results = tracker.train_and_log(
X_train, y_train, X_test, y_test,
run_name="wrapper_test",
task="classification",
time_budget=30,
verbose=0
)
print(f"결과: {results}")
정리
- MLflow: 실험 추적, 모델 관리 플랫폼
- 연동: mlflow.start_run()으로 FLAML 실험 추적
- 로깅: 파라미터, 메트릭, 아티팩트 저장
- UI: 웹 인터페이스로 실험 비교
- 레지스트리: 모델 버전 관리 및 배포
다음 글 예고
다음 글에서는 모델 저장과 불러오기를 알아봅니다. FLAML 모델을 다양한 방식으로 저장하고 로드하는 방법을 다룹니다.
FLAML AutoML 마스터 시리즈 #088