Files
PolyWeather/docs/LGBM_DAILY_HIGH_ZH.md
T
2026-04-18 14:40:29 +08:00

326 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```