본문으로 건너뛰기

090 실험 로깅 (MLflow)

키워드: MLflow, 실험 관리

개요

MLflow는 머신러닝 실험을 추적하고 관리하는 오픈소스 플랫폼입니다. PyCaret은 MLflow와 자동 통합되어 모델 학습, 파라미터, 메트릭을 자동으로 기록합니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0, mlflow

MLflow의 핵심 개념

MLflow 구성 요소:

1. Tracking
- 실험 기록
- 파라미터, 메트릭, 아티팩트

2. Projects
- 재현 가능한 코드 패키징

3. Models
- 모델 패키징 및 배포

4. Registry
- 모델 버전 관리

PyCaret과의 통합:
- setup()에서 자동 활성화
- 모든 모델 학습 자동 기록
- 비교, 튜닝 결과 추적

PyCaret에서 MLflow 활성화

from pycaret.classification import *
from pycaret.datasets import get_data

# 090 데이터 로드
data = get_data('diabetes')

# 090 MLflow 활성화
clf = setup(
data,
target='Class variable',
log_experiment=True, # MLflow 활성화
experiment_name='diabetes', # 실험 이름
session_id=42,
verbose=False
)

# 090 모델 생성 (자동 로깅)
rf = create_model('rf')

MLflow UI 실행

# 090 터미널에서 실행
# 090 mlflow ui

# 090 또는 Python에서
import subprocess
subprocess.Popen(['mlflow', 'ui', '--port', '5000'])

# 090 브라우저에서 http://localhost:5000 접속

자동 로깅 내용

from pycaret.classification import *

clf = setup(data, target='Class variable', log_experiment=True,
experiment_name='auto_logging', session_id=42, verbose=False)

# 090 모델 생성 시 자동 기록되는 내용
rf = create_model('rf')

# 090 기록되는 항목:
# 090 - 파라미터: n_estimators, max_depth, ...
# 090 - 메트릭: Accuracy, AUC, Recall, Precision, F1
# 090 - 모델 아티팩트
# 090 - 태그: 모델 유형, 라이브러리 버전

여러 모델 비교 로깅

from pycaret.classification import *

clf = setup(data, target='Class variable', log_experiment=True,
experiment_name='model_comparison', session_id=42, verbose=False)

# 090 모든 모델 비교 (각각 로깅됨)
best = compare_models()

# 090 MLflow UI에서 비교 가능
# 090 - 메트릭 비교 차트
# 090 - 파라미터 비교

튜닝 실험 로깅

from pycaret.classification import *

clf = setup(data, target='Class variable', log_experiment=True,
experiment_name='tuning_experiment', session_id=42, verbose=False)

# 090 기본 모델
rf = create_model('rf')

# 090 튜닝 (각 시도 로깅)
tuned_rf = tune_model(rf, n_iter=20)

# 090 n_iter번의 실행이 모두 기록됨
# 090 최적 파라미터 확인 용이

MLflow 직접 사용

import mlflow
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score
from pycaret.datasets import get_data

# 090 데이터 준비
data = get_data('diabetes')
X = data.drop('Class variable', axis=1)
y = data['Class variable']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 090 실험 설정
mlflow.set_experiment('manual_experiment')

# 090 실행 시작
with mlflow.start_run(run_name='rf_baseline'):
# 파라미터 로깅
params = {
'n_estimators': 100,
'max_depth': 10,
'random_state': 42
}
mlflow.log_params(params)

# 모델 학습
rf = RandomForestClassifier(**params)
rf.fit(X_train, y_train)

# 예측 및 평가
y_pred = rf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

# 메트릭 로깅
mlflow.log_metrics({
'accuracy': accuracy,
'f1_score': f1
})

# 모델 로깅
mlflow.sklearn.log_model(rf, 'model')

print(f"Accuracy: {accuracy:.4f}, F1: {f1:.4f}")

아티팩트 로깅

import mlflow
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

with mlflow.start_run(run_name='with_artifacts'):
# 모델 학습
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)

# 혼동 행렬 저장
fig, ax = plt.subplots(figsize=(8, 6))
cm = confusion_matrix(y_test, y_pred)
ConfusionMatrixDisplay(cm).plot(ax=ax)
plt.savefig('confusion_matrix.png', dpi=150)
plt.close()

# 아티팩트로 로깅
mlflow.log_artifact('confusion_matrix.png')

# 특성 중요도 저장
import pandas as pd
importance = pd.DataFrame({
'feature': X.columns,
'importance': rf.feature_importances_
}).sort_values('importance', ascending=False)
importance.to_csv('feature_importance.csv', index=False)
mlflow.log_artifact('feature_importance.csv')

실험 조회

import mlflow
from mlflow.tracking import MlflowClient

# 090 클라이언트 생성
client = MlflowClient()

# 090 실험 목록
experiments = client.search_experiments()
for exp in experiments:
print(f"{exp.name}: {exp.experiment_id}")

# 090 특정 실험의 실행 조회
runs = client.search_runs(
experiment_ids=['1'], # 실험 ID
order_by=['metrics.accuracy DESC']
)

for run in runs:
print(f"Run: {run.info.run_id}")
print(f" Accuracy: {run.data.metrics.get('accuracy', 'N/A')}")
print(f" Params: {run.data.params}")

최적 모델 로드

import mlflow

# 090 실행 ID로 모델 로드
run_id = "abc123..." # MLflow UI에서 확인
model_uri = f"runs:/{run_id}/model"
loaded_model = mlflow.sklearn.load_model(model_uri)

# 090 예측
predictions = loaded_model.predict(X_test)

모델 레지스트리

import mlflow
from mlflow.tracking import MlflowClient

# 090 모델 등록
with mlflow.start_run() as run:
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# 모델 로깅 및 등록
mlflow.sklearn.log_model(
rf,
'model',
registered_model_name='diabetes_classifier'
)

# 090 모델 버전 관리
client = MlflowClient()

# 090 버전 목록
versions = client.search_model_versions("name='diabetes_classifier'")
for v in versions:
print(f"Version {v.version}: {v.current_stage}")

# 090 프로덕션으로 전환
client.transition_model_version_stage(
name='diabetes_classifier',
version=1,
stage='Production'
)

# 090 프로덕션 모델 로드
prod_model = mlflow.sklearn.load_model(
'models:/diabetes_classifier/Production'
)

PyCaret 모델 레지스트리 등록

from pycaret.classification import *
import mlflow

clf = setup(data, target='Class variable', log_experiment=True,
experiment_name='registry_demo', session_id=42, verbose=False)

# 090 모델 생성 및 튜닝
rf = create_model('rf')
tuned = tune_model(rf)
final = finalize_model(tuned)

# 090 마지막 실행 ID 가져오기
runs = mlflow.search_runs(experiment_names=['registry_demo'])
last_run_id = runs.iloc[0]['run_id']

# 090 모델 등록
mlflow.register_model(
f"runs:/{last_run_id}/model",
'pycaret_diabetes_model'
)

원격 서버 설정

import mlflow

# 090 원격 추적 서버 설정
mlflow.set_tracking_uri('http://mlflow-server:5000')

# 090 S3 아티팩트 저장소
# 090 환경 변수 설정 필요:
# 090 AWS_ACCESS_KEY_ID
# 090 AWS_SECRET_ACCESS_KEY

# 090 또는 설정 파일 사용
mlflow.set_tracking_uri('databricks') # Databricks 사용 시

실험 비교 자동화

from pycaret.classification import *
import mlflow
import pandas as pd

def run_experiment(data, model_id, experiment_name):
"""실험 실행 및 로깅"""

clf = setup(
data,
target='Class variable',
log_experiment=True,
experiment_name=experiment_name,
session_id=42,
verbose=False
)

# 모델 생성
model = create_model(model_id)

# 튜닝
tuned = tune_model(model, n_iter=10)

# 메트릭 반환
metrics = pull()
return metrics

# 090 여러 모델 실험
models = ['rf', 'xgboost', 'lightgbm', 'catboost']
results = []

for model_id in models:
metrics = run_experiment(data, model_id, 'model_comparison')
results.append({
'model': model_id,
'metrics': metrics
})

# 090 MLflow UI에서 모든 실험 비교 가능

태그와 메모

import mlflow

with mlflow.start_run() as run:
# 태그 설정
mlflow.set_tags({
'team': 'data_science',
'project': 'diabetes_prediction',
'version': 'v1.0',
'environment': 'development'
})

# 설명 추가
mlflow.set_tag('mlflow.note.content', '''
이 실험은 당뇨병 예측 모델의 기준선입니다.
- 데이터: Pima Indians Diabetes
- 목표: 정확도 80% 이상
''')

# 모델 학습
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
mlflow.sklearn.log_model(rf, 'model')

정리

  • MLflow: ML 실험 추적 플랫폼
  • PyCaret: log_experiment=True로 자동 통합
  • 기록 항목: 파라미터, 메트릭, 아티팩트
  • 모델 레지스트리: 버전 관리, 스테이지 전환
  • 실험 비교: UI에서 시각적 비교

다음 글 예고

다음 글에서는 모델 비교와 분석을 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #090