🔬 MLOps实战训练营
学习进度
阶段 4: 模型对比实验(MLflow进阶)
目标: 从50%到70%信心值 🎯
📅 第4阶段:模型对比实验(MLflow进阶)
🚀 系统性模型对比 = 从"能跑模型"到"工程师"的关键跃升!
🎯 为什么要做模型对比?
在实际项目中,你永远不知道哪个算法最适合你的数据。系统性的模型对比能让你向客户证明:"我们测试了6种算法,随机森林在你的数据上效果最好,准确率提升了15%"。
职场意义:系统性对比是高级工程师的标志性技能
🏆 6大算法擂台赛
📈 Linear Regression
🔗 Ridge Regression
🎯 Lasso Regression
⚖️ ElasticNet
🌳 Random Forest
🚀 Gradient Boosting
模型训练常见陷阱与解决方案
❌ 问题1: 不同模型结果无法对比
正确做法
统一的训练框架,确保数据处理一致
职场意义:系统性对比是高级工程师的标志
错误做法
每次手动调整代码训练不同模型
❌ 问题2: 超参数调优混乱
解决方案
使用MLflow记录每次实验的参数和结果
进阶技巧:用Optuna等工具做自动超参数优化
常见错误
随意调参,没有记录调参过程
❌ 问题3: 模型过拟合没发现
解决方法
始终关注验证集表现,设置早停机制
实战经验:过拟合是新手最容易犯的错误,但也最好解决
危险信号
训练集准确率95%,验证集准确率60%
❌ 问题4: 内存不足训练中断
应急方案
减小batch_size,使用数据采样
根本解决:监控内存使用,优化数据加载
举一反三:资源限制在生产环境中很常见,要学会优化
上午:多模型训练脚本
💡 所有代码块默认收起,点击标题栏可展开查看完整代码,支持一键复制
🐍 src/day3_model_comparison.py
"""
Day 3: 模型对比实验
目标:训练多个模型并在MLflow中对比效果
"""
import mlflow
import mlflow.sklearn
import pandas as pd
import numpy as np
import joblib
import click
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from datetime import datetime
import yaml
import warnings
warnings.filterwarnings('ignore')
def load_processed_data():
"""加载处理后的数据"""
print("📊 加载处理后的数据...")
X_train = pd.read_csv('data/processed/X_train.csv')
X_val = pd.read_csv('data/processed/X_val.csv')
X_test = pd.read_csv('data/processed/X_test.csv')
y_train = pd.read_csv('data/processed/y_train.csv').values.ravel()
y_val = pd.read_csv('data/processed/y_val.csv').values.ravel()
y_test = pd.read_csv('data/processed/y_test.csv').values.ravel()
print(f"训练集: {X_train.shape}")
print(f"验证集: {X_val.shape}")
print(f"测试集: {X_test.shape}")
return X_train, X_val, X_test, y_train, y_val, y_test
def get_model_configs():
"""获取所有模型配置"""
return {
'linear': {
'model': LinearRegression(),
'params': {}
},
'ridge': {
'model': Ridge(alpha=1.0, random_state=42),
'params': {'alpha': 1.0}
},
'lasso': {
'model': Lasso(alpha=1.0, random_state=42),
'params': {'alpha': 1.0}
},
'elastic_net': {
'model': ElasticNet(alpha=1.0, l1_ratio=0.5, random_state=42),
'params': {'alpha': 1.0, 'l1_ratio': 0.5}
},
'random_forest': {
'model': RandomForestRegressor(
n_estimators=100,
max_depth=10,
random_state=42,
n_jobs=-1
),
'params': {
'n_estimators': 100,
'max_depth': 10,
'random_state': 42
}
},
'gradient_boosting': {
'model': GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42
),
'params': {
'n_estimators': 100,
'learning_rate': 0.1,
'max_depth': 3,
'random_state': 42
}
}
}
def evaluate_model(model, X_train, X_val, X_test, y_train, y_val, y_test):
"""评估模型性能"""
# 预测
train_pred = model.predict(X_train)
val_pred = model.predict(X_val)
test_pred = model.predict(X_test)
# 计算指标
metrics = {
'train_mse': mean_squared_error(y_train, train_pred),
'train_rmse': np.sqrt(mean_squared_error(y_train, train_pred)),
'train_mae': mean_absolute_error(y_train, train_pred),
'train_r2': r2_score(y_train, train_pred),
'val_mse': mean_squared_error(y_val, val_pred),
'val_rmse': np.sqrt(mean_squared_error(y_val, val_pred)),
'val_mae': mean_absolute_error(y_val, val_pred),
'val_r2': r2_score(y_val, val_pred),
'test_mse': mean_squared_error(y_test, test_pred),
'test_rmse': np.sqrt(mean_squared_error(y_test, test_pred)),
'test_mae': mean_absolute_error(y_test, test_pred),
'test_r2': r2_score(y_test, test_pred)
}
return metrics
@click.command
@click.option('--model-type', default='all', help='模型类型: linear/ridge/lasso/elastic_net/random_forest/gradient_boosting/all')
@click.option('--experiment-name', default='day3-model-comparison', help='MLflow实验名称')
def train_models(model_type, experiment_name):
"""训练和对比模型"""
# 加载数据
X_train, X_val, X_test, y_train, y_val, y_test = load_processed_data()
# 设置MLflow实验
mlflow.set_experiment(experiment_name)
# 获取模型配置
model_configs = get_model_configs()
# 确定要训练的模型
if model_type == 'all':
models_to_train = model_configs.keys()
else:
models_to_train = [model_type] if model_type in model_configs else []
results = []
for name in models_to_train:
print(f"\n🚀 训练 {name} 模型...")
config = model_configs[name]
model = config['model']
params = config['params']
with mlflow.start_run(run_name=f"{name}-{datetime.now().strftime('%H%M%S')}"):
# 训练模型
model.fit(X_train, y_train)
# 评估模型
metrics = evaluate_model(model, X_train, X_val, X_test, y_train, y_val, y_test)
# 记录参数
mlflow.log_param("model_type", name)
for param_name, param_value in params.items():
mlflow.log_param(param_name, param_value)
# 记录指标
for metric_name, metric_value in metrics.items():
mlflow.log_metric(metric_name, metric_value)
# 保存模型
mlflow.sklearn.log_model(
model,
"model",
registered_model_name=f"{name}_house_price_model"
)
# 保存模型到本地
model_dir = f'models/{name}'
os.makedirs(model_dir, exist_ok=True)
joblib.dump(model, f'{model_dir}/model.pkl')
# 记录结果
result = {
'model_name': name,
'val_r2': metrics['val_r2'],
'test_r2': metrics['test_r2'],
'val_rmse': metrics['val_rmse'],
'test_rmse': metrics['test_rmse']
}
results.append(result)
print(f"✅ {name} 完成 - 验证R²: {metrics['val_r2']:.4f}, 测试R²: {metrics['test_r2']:.4f}")
# 打印对比结果
print("\n📊 模型对比结果:")
print("=" * 80)
results_df = pd.DataFrame(results)
results_df = results_df.sort_values('val_r2', ascending=False)
print(results_df.to_string(index=False))
# 保存对比结果
results_df.to_csv('models/comparison_results.csv', index=False)
# 找出最佳模型
best_model = results_df.iloc[0]
print(f"\n🏆 最佳模型: {best_model['model_name']}")
print(f"验证R²: {best_model['val_r2']:.4f}")
print(f"测试R²: {best_model['test_r2']:.4f}")
return results_df
if __name__ == "__main__":
import os
train_models()
晚上:运行对比并分析
🔧 模型训练和结果分析
# 训练所有模型
python src/day3_model_comparison.py --model-type all
# 查看结果
cat models/comparison_results.csv
# 启动MLflow UI查看对比
nohup mlflow ui --host 0.0.0.0 --port 5000 >> mlflow-ui.log 2>&1 &
🐍 src/day3_analysis.py - 模型性能分析
"""
模型性能分析和可视化
"""
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import mlflow
import numpy as np
def analyze_model_performance():
"""分析模型性能"""
# 读取对比结果
results = pd.read_csv('models/comparison_results.csv')
# 创建可视化
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# R² 对比
sns.barplot(data=results, x='val_r2', y='model_name', ax=axes[0,0], palette='viridis')
axes[0,0].set_title('验证集 R² 对比')
axes[0,0].set_xlabel('R² Score')
# RMSE 对比
sns.barplot(data=results, x='val_rmse', y='model_name', ax=axes[0,1], palette='plasma')
axes[0,1].set_title('验证集 RMSE 对比')
axes[0,1].set_xlabel('RMSE')
# 验证vs测试R²
sns.scatterplot(data=results, x='val_r2', y='test_r2', s=100, ax=axes[1,0])
axes[1,0].plot([0, 1], [0, 1], 'r--', alpha=0.5)
axes[1,0].set_title('验证集 vs 测试集 R²')
axes[1,0].set_xlabel('验证集 R²')
axes[1,0].set_ylabel('测试集 R²')
# 模型复杂度vs性能
complexity = {'linear': 1, 'ridge': 2, 'lasso': 2, 'elastic_net': 3,
'random_forest': 4, 'gradient_boosting': 5}
results['complexity'] = results['model_name'].map(complexity)
sns.scatterplot(data=results, x='complexity', y='val_r2', s=100, ax=axes[1,1])
axes[1,1].set_title('模型复杂度 vs 性能')
axes[1,1].set_xlabel('复杂度')
axes[1,1].set_ylabel('验证集 R²')
plt.tight_layout()
plt.savefig('models/model_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("📊 分析图表已保存到 models/model_comparison.png")
if __name__ == "__main__":
analyze_model_performance()
🔧 运行分析并提交成果
# 运行分析
python src/day3_analysis.py
# 提交Day 3成果
git add .
git commit -m "Day 3: Multi-model comparison with MLflow
- Trained 6 different models (Linear, Ridge, Lasso, ElasticNet, RF, GBM)
- Comprehensive evaluation with train/val/test metrics
- Model comparison visualization
- Best model: [根据实际结果填写]
- All experiments tracked in MLflow"
📈 模型算法掌握
6种经典回归算法的原理和应用场景
🔬 实验管理
使用MLflow系统性追踪和对比模型
📊 性能评估
多维度指标评估和可视化分析
⚡ 调试优化
识别和解决常见训练问题
🏆 阶段 4 成就解锁
- 6个模型训练完成并对比
- MLflow实验管理熟练运用
- 最佳模型已确定
- 信心值:50% → 70%
🚀 下一步预告
阶段 5: 将使用Prefect构建自动化训练流水线,让整个过程一键执行!
你将从手动执行ML流程进化到工程师级别的自动化系统,这是从"能跑模型"到"工程师"的关键跃升。