机器学习实践项目(二)- 房价预测增强篇 - 模型训练与评估:从多模型对比到小网格微调

好,前述的代码,我们处理了特征工程,下面就正式进入了模型训练阶段了。

我们的策略是------用多个模型进行交叉验证并选出最佳模型

下面来分析对应的代码。


一、评测指标函数:rmse_on_log_space

python 复制代码
def rmse_on_log_space(y_true, y_pred):
    try:
        return mean_squared_error(np.log1p(y_true), np.log1p(y_pred), squared=False)
    except TypeError:
        return np.sqrt(mean_squared_error(np.log1p(y_true), np.log1p(y_pred)))
  • 把真实值/预测值先做 log1p 再算 RMSE ------ 这是竞赛中常见的做法,能缓解右偏分布。
  • 兼容旧版 sklearn:旧版 mean_squared_error 没有 squared 参数,所以兜底用 sqrt(MSE)

二、核心交叉验证函数:rmse_cv(model)

python 复制代码
pipe = Pipeline([
    ("prep", preprocess),
    ("reg", TransformedTargetRegressor(regressor=model, func=np.log1p, inverse_func=np.expm1))
])
...
for tr_idx, va_idx in stratified_splits:
    X_tr, X_va = X.iloc[tr_idx], X.iloc[va_idx]
    y_tr, y_va = y[tr_idx], y[va_idx]
    pipe.fit(X_tr, y_tr)
    pred_va = pipe.predict(X_va)
    rmses.append(rmse_on_log_space(y_va, pred_va))
  • 预处理 (preprocess)和模型 串成一个 Pipeline
    这样每折都只在训练折上拟合 imputer / 标准化 / One-Hot,避免数据泄漏。
    这个和前面介绍的"分层目标编码"一个概念。
  • TransformedTargetRegressor(TTR)让模型在 log 空间 里训练,预测时自动逆变换
    可以理解成:TTR 是一个小"批处理器",定义一组操作,执行时顺序完成。
  • 遍历"第0步"生成的 stratified_splits(分层 K 折),
    确保每次试验用同一套折分,各模型结果可公平比较。
  • 最后返回该模型的 平均 RMSE 和标准差(越小越好)。

三、候选模型与"稳收敛"设置

python 复制代码
candidates = {
    "RidgeCV": RidgeCV(...),
    "LassoCV": LassoCV(..., max_iter=200_000, tol=1e-3, selection="random"),
    "ElasticNetCV": ElasticNetCV(..., max_iter=200_000, tol=1e-3, selection="random"),
    "HistGBR": HistGradientBoostingRegressor(...)
}
  • 同时用 RidgeCV / LassoCV / ElasticNetCV / HistGBR 四类模型进行评估,选出最优者。
  • 线性稀疏模型给了更大的 max_iter、略放宽的 tol、加上 selection="random"
    是为了减少"不收敛"或"收敛慢"的告警。
  • HistGBR 则采用一组「保守但好用」的参数:
    learning_rate=0.06max_leaf_nodes=31min_samples_leaf=20l2_regularization=1e-3
    强调稳健泛化。

🌱 一句话先讲明白:

"我想比较几种不同的模型,看哪个预测房价最准。

为了防止它们训练不收敛或报错,我给每个模型设置了比较稳定的参数。"


四、模型字典与参数的通俗理解

🧩 四个模型是谁?

python 复制代码
candidates = {
    "RidgeCV": RidgeCV(...),
    "LassoCV": LassoCV(...),
    "ElasticNetCV": ElasticNetCV(...),
    "HistGBR": HistGradientBoostingRegressor(...)
}

这其实就是一个"模型字典":

模型 简单理解 作用
RidgeCV 岭回归 线性模型,防止过拟合
LassoCV 套索回归 线性模型,自动选特征
ElasticNetCV 弹性网 综合 Ridge 和 Lasso
HistGBR 树模型(梯度提升树) 捕捉非线性关系

五、模型参数逐个解释(配比喻更好记)

1️⃣ max_iter

训练时最多迭代多少次。

想象模型在不断"试探"参数,直到误差够小。

太少会"没学完",所以给大一点(如 200000)更稳。

2️⃣ tol

容忍度(容错值)。

越小越严格,模型学得更久。稍放宽(1e-3)就不会老警告。

3️⃣ selection="random"

对 Lasso/ElasticNet 来说,这表示"随机挑选参数更新"。

随机顺序能防止算法卡住,更容易收敛。

4️⃣ learning_rate=0.06

树模型的学习速度。

太大会过拟合,太小会学不完。0.06 是稳健中间值。

5️⃣ max_leaf_nodes=31

每棵树的最大分支数。

分支越多模型越复杂,31 是"刚刚好"的中等复杂度。

6️⃣ min_samples_leaf=20

每个叶子节点至少多少样本。

样本太少容易记住噪声,20 可以防过拟合。

7️⃣ l2_regularization=1e-3

给模型一个"惩罚项",让它别太激进。

值越大越"温和",泛化更好。


🧠 类比:模型就像学生

参数 比喻 调节作用
max_iter 给学生复习的次数 多学几遍才彻底掌握
tol 老师标准 放宽点别太抠细节
selection 学习顺序 随机复习更灵活
learning_rate 学习速度 太快出错,太慢浪费时间
max_leaf_nodes 笔记条数 太多=啰嗦,太少=粗糙
min_samples_leaf 每条笔记至少几句 保证总结有依据
l2_regularization 老师的管束 防止学得太极端

一句话总结:

这些参数的目的就是:让模型稳稳当当地"学完",不乱跑、不炸分。

所以叫"稳收敛设置"。


六、模型对比与最优选择

python 复制代码
results = {}
for name, model in candidates.items():
    m, s = rmse_cv(model)
    results[name] = (m, s)
    print(f"{name:12s}: {m:.5f} +/- {s:.5f}")

best_name = min(results, key=lambda k: results[k][0])
  • 对每个模型都跑一次 rmse_cv,输出"均值 ± 标准差";
  • RMSE 最小 的模型作为 best_name
  • 后续可用它进行全量训练或进一步调参。

七、小网格微调(仅当 HistGBR 最优时)

python 复制代码
DO_HGB_TUNING = (best_name == "HistGBR")
...
hgb_pipe = Pipeline([
    ("prep", preprocess),
    ("reg", TransformedTargetRegressor(
        regressor=HistGradientBoostingRegressor(random_state=42),
        func=np.log1p, inverse_func=np.expm1))
])
param_grid = {
    "reg__regressor__learning_rate": [0.03, 0.06, 0.1],
    "reg__regressor__max_leaf_nodes": [31, 63, 127],
    "reg__regressor__min_samples_leaf": [10, 20, 40],
    "reg__regressor__l2_regularization": [1e-3, 3e-3, 1e-2]
}

继续沿用同一个管道结构,只在少数关键超参上做"小网格"搜索。

时间可控,却往往能涨一点分。


😵‍💫 什么是"小网格微调"?

好,到这里估计又要懵了。

什么是"网格"?什么是"小网格微调"?难道还有"大网格"?

好吧,我也是懵的,只好让"爱老师"继续上场 😄。


🧩 一句话解释

"小网格微调"就是:

模型已经不错了,再拿出几组可能更好的参数组合

让电脑帮我们试试,看哪组最好。


🌰 举个简单例子

假设你在调一台风扇:

参数 档位
风速 [1, 2, 3]
风向 [固定, 摇头]

3 × 2 = 6 种组合 ,你挨个试试,看哪种风最舒服。

这,就是"小网格"搜索。


💡 在模型里怎么做?

HistGBR 也一样:

我们给它四个主要"旋钮":

参数 含义 可能的值
learning_rate 学习速度 [0.03, 0.06, 0.1]
max_leaf_nodes 每棵树最多叶子数 [31, 63, 127]
min_samples_leaf 每个叶子最少样本 [10, 20, 40]
l2_regularization 正则强度 [1e-3, 3e-3, 1e-2]

让电脑"自动试" → 共 3×3×3×3 = 81 种组合。

这就是"小网格(Grid)"。


⚙️ GridSearchCV 做的事

  1. 挨个尝试参数组合;
  2. 每组都做交叉验证;
  3. 记录结果(RMSE);
  4. 选出最优组合;
  5. 返回"调好参数的最优模型"。

🧮 为什么叫"小网格"

参数太多会组合爆炸:

参数数 每个取值 组合数
2 3 9
3 3 27
4 3 81
5 3 243

所以我们只在关键参数上取少量值 ,形成"小网格",

节省计算,又能有效微调。


一句话总结:

"小网格微调 = 在模型已经不错的情况下,自动帮你试几组最重要的参数,让它更稳、更高分。"


八、最终产物

  • results:每个模型在分层 CV 下的 RMSE 均值/方差。
  • best_name:最好的基础模型名。
  • best_estimator(可选):若做了 HistGBR 微调,则为最优管道(含预处理 + TTR + 最优超参)。

九、一句话总结

这段代码把**"公平、稳定、可复现"**三件事落到实处:

  1. 同一套分层折评所有模型(公平);
  2. 在 log 空间评 RMSE,且每折重拟合预处理(稳定);
  3. 固定随机种子、重用折分、必要时小网格微调(可复现 + 提升)。
相关推荐
数据库安全1 小时前
世界互联网大会|美创科技无侵入数据安全多智体治理技术首发
大数据·人工智能·科技·数据安全
海底的星星fly2 小时前
【Prompt学习技能树地图】生成知识提示技术的深度解析与应用
人工智能·学习·prompt
赵得C2 小时前
智能体的范式革命:华为全栈技术链驱动下一代AI Agent
人工智能·华为·ai·ai编程
嵌入式-老费3 小时前
自己动手写深度学习框架(感知机)
人工智能·深度学习
化作星辰3 小时前
使用 PyTorch来构建线性回归的实现
人工智能·pytorch·深度学习
mm-q29152227293 小时前
【天野学院5期】 第5期易语言半内存辅助培训班,主讲游戏——手游:仙剑奇侠传4,端游:神魔大陆2
人工智能·算法·游戏
谢景行^顾3 小时前
深度学习-损失函数
人工智能·深度学习
xier_ran3 小时前
关键词解释: LoRA(Low-Rank Adaptation)详解
人工智能
黄焖鸡能干四碗4 小时前
信息安全管理制度(Word)
大数据·数据库·人工智能·智慧城市·规格说明书