机器学习实验手册

本手册把机器学习知识变成可重复的实验。建议每个实验都保留:问题定义、数据版本、训练/验证/测试划分、基线、指标、错误分析和结论。

1. 环境准备

python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
python -m pip install -U pip
pip install numpy pandas matplotlib scikit-learn joblib

建议把依赖版本写入 requirements.txt;正式实验使用锁定版本的环境,避免不同版本造成结果漂移。

2. 先理解问题与数据

问题目标常见指标
回归预测连续数值MAE、RMSE、R²
二分类判断两个类别Precision、Recall、F1、ROC-AUC、PR-AUC
多分类预测多个互斥类别Accuracy、Macro-F1、混淆矩阵
聚类发现无标签分组Silhouette、Davies–Bouldin(结合业务解释)
异常检测找出少数异常样本Precision@K、Recall、PR-AUC

先问清楚:预测发生在什么时候?预测时能拿到哪些特征?漏报和误报哪个代价更高?如果特征包含预测时刻之后才产生的信息,就可能发生数据泄漏。

3. 核心算法的直觉与公式

3.1 线性回归

模型:。常见平方误差目标:

它适合建立可解释基线。注意异常值会显著影响平方误差;特征量纲差异较大时,正则化前通常需要标准化。

3.2 逻辑回归

二元交叉熵:

输出是概率估计,不是天然可靠的业务决策。阈值应根据误报/漏报成本和验证集选择。

3.3 决策树与随机森林

决策树通过特征切分降低节点不纯度。分类常见 Gini:

随机森林对多个随机化决策树进行集成,降低单棵树方差;代价是模型体积、推理开销和解释难度增加。

3.4 梯度提升树

每轮拟合当前模型的残差或损失梯度,逐步修正错误。XGBoost、LightGBM、CatBoost 是表格数据常见强基线。调参时重点关注树深、学习率、树数量、叶子数、采样比例和正则化。

3.5 支持向量机

最大间隔分类器通过间隔与惩罚项权衡泛化和训练误差。核函数可表达非线性边界,但大样本训练成本可能较高;特征尺度对结果影响明显。

4. 可运行分类实验:乳腺癌数据集

下面示例使用 Pipeline,确保标准化只在训练折上拟合,避免先对全量数据标准化造成泄漏。

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, StratifiedKFold, cross_validate
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
 
data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.2,
    random_state=42, stratify=data.target
)
 
model = make_pipeline(
    StandardScaler(),
    LogisticRegression(max_iter=3000, class_weight="balanced")
)
 
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_validate(
    model, X_train, y_train, cv=cv,
    scoring=["f1", "roc_auc"], return_train_score=False
)
print("CV F1:", scores["test_f1"].mean())
print("CV ROC-AUC:", scores["test_roc_auc"].mean())
 
model.fit(X_train, y_train)
pred = model.predict(X_test)
prob = model.predict_proba(X_test)[:, 1]
print(confusion_matrix(y_test, pred))
print(classification_report(y_test, pred, target_names=data.target_names))
print("Test ROC-AUC:", roc_auc_score(y_test, prob))

说明:该数据集适合教学,不代表真实临床系统。不要把教学实验当作医疗诊断工具。

5. 实验对比:不要只报一个准确率

建议至少比较:

  • DummyClassifier:确认模型是否真的优于简单基线。
  • LogisticRegression:可解释线性基线。
  • RandomForest / HistGradientBoosting:非线性树模型。
  • 不同阈值:观察 Precision 与 Recall 的权衡。
  • 类别不平衡处理:class_weight、重采样;重采样必须只在训练折内完成。

6. 常见错误排查

现象优先检查
训练分数高、测试分数低过拟合、数据泄漏、分布漂移、样本量
所有指标都很差标签定义、特征、数据质量、基线和实现
Accuracy 很高但业务效果差类别不平衡,检查 Recall、PR-AUC、混淆矩阵
交叉验证波动很大样本量、分层划分、分组/时间相关性
线上效果下降数据漂移、特征计算差异、标签延迟、训练服务不一致

时间序列必须按时间切分;同一用户/设备有多条记录时,考虑 Group split,避免同一实体同时进入训练集和测试集。

7. 进阶实验任务

  1. 用同一数据集比较逻辑回归、随机森林、梯度提升树。
  2. 绘制学习曲线,判断增加数据是否可能改善泛化。
  3. 用校准曲线检查概率是否可信。
  4. 使用 Permutation Importance 分析特征影响,并检查相关特征的解释局限。
  5. 构建一个带时间切分的预测任务,验证没有未来信息泄漏。
  6. 保存模型、预处理器、依赖版本和评估报告,写出可复现实验 README。

8. 学习资料

相关