# LightGBM 日最高温模型(中文) 最后更新:`2026-04-18` ## 1. 目标 这套 `LightGBM` 模型是给 PolyWeather 增加一个轻量级的统计学习预测源。 它的定位不是替代: - `DEB` - `EMOS` - `ECMWF / GFS / GEM / JMA / ICON / Open-Meteo / MGM / NWS` 而是作为一个新的点预测源: `现有模型 + 观测特征 -> LGBM -> 并入 current_forecasts -> DEB -> EMOS` 第一版只做: - `D0` 当日最高温预测 不做: - `D1-D3` - 小时级曲线 - 原始独立概率分布 - 独立结算源 注意:前端出现的“LGBM 校准概率”不是把 LGBM 模型票数直接当成概率,而是概率层基于 LGBM / DEB / 观测上下文输出的校准分布。模型共识只保留为解释性参考。 ## 2. 适用场景 这条链路是为低资源 VPS 准备的。 当前项目线上环境只有 `2GB RAM` 时,不适合引入 `TimesFM` 这类大模型,但适合用 `LightGBM` 做轻量推理。 当前方案是: 1. 训练离线完成 2. 训练产物直接提交到仓库 3. VPS 线上只加载模型文件并推理 4. VPS 不训练,不起额外服务 ## 3. 文件结构 核心文件如下: - 运行时推理: - [src/models/lgbm_daily_high.py](/E:/web/PolyWeather/src/models/lgbm_daily_high.py) - 特征构建: - [src/models/lgbm_features.py](/E:/web/PolyWeather/src/models/lgbm_features.py) - 训练脚本: - [scripts/train_lgbm_daily_high.py](/E:/web/PolyWeather/scripts/train_lgbm_daily_high.py) - 训练报告脚本: - [scripts/report_lgbm_daily_high.py](/E:/web/PolyWeather/scripts/report_lgbm_daily_high.py) - 模型文件: - [artifacts/models/lgbm_daily_high.txt](/E:/web/PolyWeather/artifacts/models/lgbm_daily_high.txt) - 模型 schema / 指标: - [artifacts/models/lgbm_daily_high_schema.json](/E:/web/PolyWeather/artifacts/models/lgbm_daily_high_schema.json) 接入链路位置: - Web API 聚合: - [web/analysis_service.py](/E:/web/PolyWeather/web/analysis_service.py) - 共享趋势引擎: - [src/analysis/trend_engine.py](/E:/web/PolyWeather/src/analysis/trend_engine.py) ## 4. 特征说明 第一版特征固定为以下几组。 ### 4.1 历史日高温特征 - `actual_high_lag_1` - `actual_high_lag_2` - `actual_high_lag_3` - `actual_high_lag_7` - `actual_high_mean_7` - `actual_high_mean_14` - `actual_high_trend_3` ### 4.2 当天模型特征 - `Open-Meteo` - `ECMWF` - `GFS` - `GEM` - `JMA` - `ICON` - `MGM` - `NWS` - `deb_prediction` - `model_median` - `model_spread` ### 4.3 当前观测特征 - `current_temp` - `max_so_far` - `humidity` - `wind_speed_kt` - `visibility_mi` ### 4.4 时间与状态特征 - `local_hour` - `month` - `weekday` - `peak_status_code` 其中: - `before = 0` - `in_window = 1` - `past = 2` ## 5. 训练数据来源 训练数据主要来自两份运行时历史文件: - [data/daily_records.json](/E:/web/PolyWeather/data/daily_records.json) - [data/probability_training_snapshots.jsonl](/E:/web/PolyWeather/data/probability_training_snapshots.jsonl) 作用分工: - `daily_records.json` - 提供 `actual_high` - 提供当天各模型 forecast - 提供历史 `deb_prediction` - `probability_training_snapshots.jsonl` - 提供 `max_so_far` - 提供 `peak_status` - 提供观测特征快照 为后续重训,概率快照归档现在还会额外写入: - `current_temp` - `humidity` - `wind_speed_kt` - `visibility_mi` - `local_hour` 对应代码: - [src/analysis/probability_snapshot_archive.py](/E:/web/PolyWeather/src/analysis/probability_snapshot_archive.py) ## 6. 训练流程 训练脚本: ```bash ./venv/Scripts/python.exe scripts/train_lgbm_daily_high.py ``` 训练流程如下: 1. 从历史文件构造监督样本 2. 目标值固定为 `actual_high` 3. 按日期做简单的时间顺序切分 4. 最后约 20% 做验证集 5. 先训练并评估验证集 6. 再用全量样本训练最终模型 7. 输出模型文件和 schema 文件 输出产物: - [artifacts/models/lgbm_daily_high.txt](/E:/web/PolyWeather/artifacts/models/lgbm_daily_high.txt) - [artifacts/models/lgbm_daily_high_schema.json](/E:/web/PolyWeather/artifacts/models/lgbm_daily_high_schema.json) ## 7. 如何看训练结果 查看训练报告: ```bash ./venv/Scripts/python.exe scripts/report_lgbm_daily_high.py ``` 这个脚本会读取 schema,并打印: - `Sample Count` - `Train Count` - `Valid Count` - `LGBM MAE` - `DEB MAE` - `Best Single MAE` - `Median MAE` - `Winner` 当前这版训练结果是: - `sample_count = 29` - `validation_count = 12` - `validation.lgbm_mae = 2.975` - `validation.deb_mae = 2.267` - `validation.best_single_mae = 1.167` 这说明: - 当前 `LGBM` 链路已经可用 - 但现阶段验证集表现还没有超过 `DEB` - 所以默认配置仍建议保持关闭 ## 8. 线上运行逻辑 运行时推理逻辑不是“直接替代 DEB”,而是: 1. 先收集现有模型 forecast 2. 先算一版基线 `DEB` 3. 把这版 `DEB` 当作 `LGBM` 的一个输入特征 4. 输出 `LGBM` 点预测 5. 把 `LGBM` 注入 `current_forecasts` 6. 重新计算最终 `DEB` 这样做的原因是: - `LGBM` 需要吃到 `deb_prediction` 特征 - 但最终 `DEB` 又要把 `LGBM` 当成一个新的输入模型 ## 8.1 前端概率展示口径 当前网页的概率区按以下顺序解释: 1. 如果后端 `probabilities.engine` 表示 LGBM 校准概率可用,则标题显示为 `LGBM 校准概率`。 2. 如果 LGBM 不可用,但 EMOS / legacy 概率可用,则显示为 `校准模型概率`。 3. 模型舍入票数只保留为“模型共识参考”,用于说明哪些模型四舍五入后落在同一温度档,不作为最终命中概率。 4. 市场价格只保留为“市场参考”,不和校准概率混成同一结论。 这能避免用户把 `4/8 模型支持 82°F` 误读成 `82°F 有 50% 概率`。模型共识是解释层,概率引擎才是结论层。 ## 9. 环境变量 示例配置见: - [.env.example](/E:/web/PolyWeather/.env.example) 相关变量: ```env POLYWEATHER_LGBM_ENABLED=false POLYWEATHER_LGBM_MODEL_PATH=/app/artifacts/models/lgbm_daily_high.txt POLYWEATHER_LGBM_SCHEMA_PATH=/app/artifacts/models/lgbm_daily_high_schema.json POLYWEATHER_LGBM_MIN_HISTORY_POINTS=3 ``` 说明: - `POLYWEATHER_LGBM_ENABLED` - 是否启用运行时推理 - `POLYWEATHER_LGBM_MODEL_PATH` - 模型文件路径 - `POLYWEATHER_LGBM_SCHEMA_PATH` - schema 文件路径 - `POLYWEATHER_LGBM_MIN_HISTORY_POINTS` - 某城市最低历史样本门槛 默认是 `3`,原因不是最理想,而是当前整体样本仍然偏少。 如果门槛设太高,很多城市现在根本不会触发 `LGBM`。 ## 10. VPS 部署建议 如果你的 VPS 只有 `2GB RAM`: - 可以跑这套 `LightGBM` - 不要在 VPS 上训练 - 不要起额外模型服务 推荐方式: 1. 在本地或开发环境训练 2. 提交模型产物 3. VPS 拉代码 4. 开启 `POLYWEATHER_LGBM_ENABLED=true` 5. 重启主服务 不推荐: - 在 VPS 上跑训练脚本 - 把 `LightGBM` 当成长任务服务单独部署 - 同时引入大模型推理 ## 11. 当前结论 这条链路已经完成了: - 离线训练 - 模型产物固化 - 运行时懒加载 - Web / 共享分析链路注入 - 前端模型类型兼容 但当前样本量仍偏少,所以建议运营策略是: 1. 先继续积累历史 `actual_high` 2. 继续积累概率快照观测字段 3. 定期重训 4. 只有当验证集 `MAE` 持续接近或优于 `DEB` 时,再考虑默认线上开启 ## 12. 常用命令 ### 训练 ```bash ./venv/Scripts/python.exe scripts/train_lgbm_daily_high.py ``` ### 查看训练报告 ```bash ./venv/Scripts/python.exe scripts/report_lgbm_daily_high.py ``` ### 本地测试 ```bash ./venv/Scripts/python.exe -m pytest tests/test_lgbm_features.py tests/test_lgbm_daily_high.py ``` ### 编译检查 ```bash ./venv/Scripts/python.exe -m compileall src web scripts tests ```