机器学习开发完整流程
机器学习开发完整流程
以下是机器学习开发完整流程的Markdown流程图,包含每一步的作用和说明:
详细说明
1. 问题定义
- 作用:明确任务目标(分类、回归、聚类等)和评估指标(如准确率、RMSE)。
- 关键问题:
- 预测什么?
- 如何衡量模型成功?
- 示例:预测用户流失(二分类任务),评估指标为 AUC-ROC。
2. 数据收集
- 作用:获取与问题相关的原始数据,可能来自数据库、API 或公开数据集。
- 关键点:
- 数据量是否足够?
- 数据是否包含标签?
- 示例:从 CRM 系统导出用户行为日志和流失标签。
3. 数据预处理
- 作用:清洗数据,使其适合模型输入。
- 子步骤:
- 处理缺失值(删除/填充)
- 处理异常值(截断或转换)
- 数据标准化(如 StandardScaler)
- 数据分箱(如年龄分段)
- 示例:对用户消费金额进行对数变换,缓解长尾分布。
4. 特征工程
- 作用:从原始数据中提取或构造对模型有用的特征。
- 方法:
- 特征选择(过滤法、包装法)
- 特征构造(如日期转星期几)
- 降维(如 PCA)
- 示例:从用户注册时间中提取“注册距今天数”特征。
5. 模型选择与训练
- 作用:选择合适的算法并训练模型。
- 选择依据:
- 任务类型(线性回归用于回归,随机森林用于分类)
- 数据规模(小数据用 SVM,大数据用深度学习)
- 示例:使用 XGBoost 训练用户流失预测模型。
6. 模型评估
- 作用:验证模型在测试集上的性能。
- 评估方法:
- 分类:混淆矩阵、F1-Score
- 回归:RMSE、R²
- 交叉验证(避免过拟合)
- 示例:计算模型 AUC-ROC 为 0.85,满足业务需求。
7. 部署与监控
- 作用:将模型集成到生产环境,并持续跟踪表现。
- 工具:
- 部署:Flask API、TensorFlow Serving
- 监控:Prometheus、ELK 日志
- 示例:将模型封装为 REST API,实时预测用户流失概率。
8. 持续优化
- 作用:根据监控结果迭代改进模型。
- 优化方向:
- 收集新数据重新训练
- 调整特征工程策略
- 更新超参数
- 示例:发现模型在新用户群体中 AUC 下降,重新训练并发布 V2 模型。
流程图特点
- 迭代性:模型评估不通过时返回训练步骤(如调整超参数)。
- 端到端:覆盖从业务问题到工程落地的全生命周期。
- 灵活性:根据任务复杂度可扩展子步骤(如数据标注、模型解释)。
示例场景:电商销量预测
- 问题定义:预测未来 7 天商品销量(回归任务),评估指标为 RMSE。
- 数据收集:从数仓获取历史销量、促销活动、天气数据。
- 数据预处理:填充缺失的促销信息,标准化价格字段。
- 特征工程:构造“节假日标志”和“历史销量滑动平均”特征。
- 模型训练:使用 LightGBM 训练时间序列模型。
- 模型评估:测试集 RMSE 为 15.2,优于基线模型。
- 部署:通过 Airflow 调度每日预测任务,结果写入数据库。
- 监控:监控预测值与实际销量的偏差,触发阈值告警。
通过这一流程,可系统化解决复杂业务问题,并确保模型持续提供价值。
示例代码:电商销量预测
以下是一个针对电商销量预测的完整 Python 代码示例,涵盖数据生成、特征工程、模型训练、评估和可视化。代码使用模拟数据,并基于 LightGBM 回归模型实现。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, TimeSeriesSplit, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import lightgbm as lgb
from datetime import datetime
# ======================
# 1. 模拟电商数据集生成
# ======================
def generate_sales_data(days=365):
"""生成模拟电商销售数据,包含日期、促销、广告费用、节假日标志和销量"""
np.random.seed(42)
# 生成日期范围
dates = pd.date_range(start="2023-01-01", periods=days, freq="D")
# 生成特征
data = pd.DataFrame({
"date": dates,
"price": np.random.normal(50, 10, days), # 商品价格
"promotion": np.random.choice([0, 1], days, p=[0.7, 0.3]), # 促销活动(0/1)
"ad_spend": np.random.lognormal(3, 0.5, days), # 广告费用(右偏分布)
"is_holiday": np.where(dates.month.isin([12, 1, 7]), 1, 0), # 节假日标志
"sales": 0 # 目标变量(销量)
})
# 生成销量(与特征相关)
data["sales"] = (
100 * data["price"] # 价格越低,销量越高
+ 500 * data["promotion"] # 促销显著提升销量
+ 0.5 * data["ad_spend"] # 广告费用正向影响
+ 300 * data["is_holiday"] # 节假日销量增加
+ np.random.normal(0, 50, days) # 随机噪声
)
return data
sales_data = generate_sales_data()
print("模拟数据示例:\n", sales_data.head(3))
# ======================
# 2. 数据预处理与特征工程
# ======================
def feature_engineering(df):
"""时间序列特征工程"""
# 提取日期特征
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["day_of_week"] = df["date"].dt.dayofweek # 周一=0, 周日=6
df["is_weekend"] = np.where(df["day_of_week"] >= 5, 1, 0)
# 滞后特征(过去3天的销量)
df["lag_1"] = df["sales"].shift(1) # 前1天销量
df["lag_3"] = df["sales"].shift(3) # 前3天销量
df["lag_7"] = df["sales"].shift(7) # 前7天销量
# 删除初始缺失值(由滞后特征引入)
df = df.dropna()
return df
# 应用特征工程
sales_data = feature_engineering(sales_data)
features = ["price", "promotion", "ad_spend", "is_holiday",
"year", "month", "day_of_week", "is_weekend",
"lag_1", "lag_3", "lag_7"]
target = "sales"
# 划分训练集和测试集(按时间顺序)
train_size = int(len(sales_data) * 0.8)
train_data = sales_data.iloc[:train_size]
test_data = sales_data.iloc[train_size:]
X_train, y_train = train_data[features], train_data[target]
X_test, y_test = test_data[features], test_data[target]
# ======================
# 3. 模型训练(LightGBM)
# ======================
# 初始化模型
model = lgb.LGBMRegressor(
objective="regression",
n_estimators=200,
random_state=42
)
# 训练模型
model.fit(X_train, y_train)
# ======================
# 4. 模型评估
# ======================
def evaluate_model(model, X_test, y_test):
"""计算评估指标并绘制预测结果"""
y_pred = model.predict(X_test)
# 计算指标
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
mae = mean_absolute_error(y_test, y_pred)
print(f"RMSE: {rmse:.2f}, MAE: {mae:.2f}")
# 绘制预测 vs 实际值
plt.figure(figsize=(10, 6))
plt.plot(y_test.values, label="实际销量")
plt.plot(y_pred, label="预测销量", alpha=0.7)
plt.title("实际销量 vs 预测销量")
plt.xlabel("样本索引")
plt.ylabel("销量")
plt.legend()
plt.show()
# 特征重要性分析
lgb.plot_importance(model, max_num_features=10, figsize=(10, 6))
plt.show()
evaluate_model(model, X_test, y_test)
# ======================
# 5. 超参数调优(可选)
# ======================
param_grid = {
"n_estimators": [100, 200],
"max_depth": [3, 5],
"learning_rate": [0.01, 0.1],
}
# 时间序列交叉验证(避免未来数据泄露)
tscv = TimeSeriesSplit(n_splits=3)
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=tscv, scoring="neg_mean_squared_error")
grid_search.fit(X_train, y_train)
best_model = grid_search.best_estimator_
print("最优参数:", grid_search.best_params_)
evaluate_model(best_model, X_test, y_test)
# ======================
# 6. 模型保存与监控(伪代码)
# ======================
# 保存模型
# import joblib
# joblib.dump(best_model, "sales_forecast_model.pkl")
# 监控逻辑示例(定期重新训练)
# if 监测到模型性能下降:
# 收集新数据 -> 重新训练 -> 更新模型
代码说明
-
数据生成
- 生成模拟电商数据,包含:
date
: 日期price
: 商品价格(正态分布)promotion
: 是否促销(二分类)ad_spend
: 广告费用(对数正态分布,模拟右偏数据)is_holiday
: 节假日标志(12月、1月、7月标记为节假日)sales
: 目标变量(销量),由线性公式生成并添加噪声。
- 生成模拟电商数据,包含:
-
特征工程
- 时间特征:提取年、月、星期几、是否周末。
- 滞后特征:添加过去1天、3天、7天的销量(
lag_1
,lag_3
,lag_7
),捕捉时间依赖性。 - 数据清洗:删除由滞后特征引入的缺失值。
-
模型训练
- 使用 LightGBM(高效梯度提升框架),适合表格数据和非线性关系建模。
- 默认参数:200棵树,无深度限制(通过后续调优优化)。
-
模型评估
- 评估指标:
- RMSE(均方根误差):衡量预测值与真实值的平均偏差。
- MAE(平均绝对误差):更鲁棒的误差指标。
- 可视化:
- 实际销量 vs 预测销量曲线。
- 特征重要性图(分析哪些特征对预测贡献最大)。
- 评估指标:
-
超参数调优
- 使用 GridSearchCV 搜索最优参数组合。
- 时间序列交叉验证(TimeSeriesSplit):避免随机划分导致未来数据泄露。
-
模型监控(伪代码)
- 保存模型为 .pkl 文件,供生产环境调用。
- 监控模型性能(如误差上升时触发重新训练)。
关键输出示例
RMSE: 52.31, MAE: 41.28
最优参数: {'learning_rate': 0.1, 'max_depth': 5, 'n_estimators': 200}
调优后 RMSE: 48.76
场景扩展
- 实时预测:将模型部署为 API(使用 Flask/FastAPI),接收实时数据并返回预测结果。
- 自动化管道:通过 Airflow 或 Prefect 定期重新训练模型。
- 异常检测:监控预测值与实际值的偏差,触发库存调整或促销策略。
通过这一流程和代码示例,可以系统化地解决复杂业务问题,并确保模型持续提供价值。