1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
| # ========== 实验追踪系统 ==========
import mlflow
import mlflow.sklearn
from datetime import datetime
from typing import Any, Dict, Optional
class ExperimentTracker:
"""实验追踪器"""
def __init__(self, tracking_uri: str, experiment_name: str):
mlflow.set_tracking_uri(tracking_uri)
mlflow.set_experiment(experiment_name)
self.experiment_name = experiment_name
def start_run(self, run_name: Optional[str] = None):
"""开始一次运行"""
self.run = mlflow.start_run(run_name=run_name)
return self.run
def log_params(self, params: Dict[str, Any]):
"""记录参数"""
mlflow.log_params(params)
def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None):
"""记录指标"""
mlflow.log_metrics(metrics, step=step)
def log_model(self, model: Any, artifact_path: str = "model"):
"""记录模型"""
mlflow.sklearn.log_model(model, artifact_path)
def log_artifact(self, file_path: str):
"""记录文件"""
mlflow.log_artifact(file_path)
def log_figure(self, figure, artifact_file: str):
"""记录图表"""
mlflow.log_figure(figure, artifact_file)
def end_run(self, status: str = "FINISHED"):
"""结束运行"""
mlflow.end_run(status=status)
# 使用示例
def train_model_with_tracking(X_train, y_train, X_test, y_test, params):
"""训练模型并追踪实验"""
tracker = ExperimentTracker(
tracking_uri="http://mlflow-server:5000",
experiment_name="fraud-detection"
)
tracker.start_run(run_name=f"experiment-{datetime.now().strftime('%Y%m%d-%H%M%S')}")
try:
# 记录参数
tracker.log_params(params)
# 训练模型
model = train_model(X_train, y_train, params)
# 评估模型
metrics = evaluate_model(model, X_test, y_test)
tracker.log_metrics(metrics)
# 记录模型
tracker.log_model(model)
# 记录学习曲线
fig = plot_learning_curve(model, X_train, y_train)
tracker.log_figure(fig, "learning_curve.png")
# 记录特征重要性
fig = plot_feature_importance(model)
tracker.log_figure(fig, "feature_importance.png")
tracker.end_run(status="FINISHED")
return model, metrics
except Exception as e:
tracker.end_run(status="FAILED")
raise e
# ========== 超参数优化 ==========
import optuna
from optuna.integration.mlflow import MLflowCallback
class HyperparameterOptimizer:
"""超参数优化器"""
def __init__(self, n_trials: int = 100, timeout: Optional[int] = None):
self.n_trials = n_trials
self.timeout = timeout
self.study = None
def objective(self, trial, X_train, y_train, X_val, y_val):
"""优化目标函数"""
# 定义搜索空间
params = {
'n_estimators': trial.suggest_int('n_estimators', 50, 500),
'max_depth': trial.suggest_int('max_depth', 3, 20),
'learning_rate': trial.suggest_float('learning_rate', 0.001, 0.3, log=True),
'subsample': trial.suggest_float('subsample', 0.5, 1.0),
'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0),
'min_child_weight': trial.suggest_int('min_child_weight', 1, 10),
}
# 训练模型
model = train_model(X_train, y_train, params)
# 评估
predictions = model.predict(X_val)
score = calculate_metric(y_val, predictions)
return score
def optimize(self, X_train, y_train, X_val, y_val):
"""执行超参数优化"""
# 创建研究对象
self.study = optuna.create_study(
direction="maximize",
study_name="hyperparameter-optimization"
)
# 添加MLflow回调
mlflc = MLflowCallback(
tracking_uri="http://mlflow-server:5000",
metric_name="validation_score"
)
# 执行优化
self.study.optimize(
lambda trial: self.objective(trial, X_train, y_train, X_val, y_val),
n_trials=self.n_trials,
timeout=self.timeout,
callbacks=[mlflc]
)
return self.study.best_params, self.study.best_value
def get_importance(self):
"""获取超参数重要性"""
return optuna.importance.get_param_importances(self.study)
|