本模型融合 6 个真实数据源,对景点人流量输出 0-100 评分,支持天级和小时级预测。 核心思路:五因子加权基线 → 类型修正 → 容量约束 → 非线性压缩 → 路况实时卡尔曼融合。
| 因子 | 权重 | 数据源 | 真实度 | 更新频率 | 粒度 |
|---|---|---|---|---|---|
| D 日期 | 35% | chinese_calendar Python 库 |
真实 | 每天 | 天级 |
| H 热度 | 25% | merged_poi.json → baidu_rating |
真实 | ~14 天(百度 POI 轮询) | 静态 |
| W 天气 | 15% | weather_cache.json(wttr.in 采集) |
真实 | 每天(weather_cron_grid.py) | 天级 |
| M 迁徙 | 15% | 百度迁徙 API huiyan.baidu.com |
真实 | 每次拉取(返回历史全量) | 天级 |
| S 季节 | 10% | 内置专家矩阵(6 类 × 12 月) | 静态规则 | 手动维护 | 月级 |
| T 路况 | 卡尔曼融合 | 百度交通态势 API traffic/v1/around |
真实实时 | 每小时 | 分钟级 |
零 Mock 数据。季节矩阵为离线编码的专家常识,其余五个因子全部来自在线 API 或本地真实缓存。
数据源:chinese_calendar(含中国法定假日、调休数据)
| 日期类型 | D 值 |
|---|---|
| 法定假日(非周末,如春节、国庆) | 1.00 |
| 普通周末 | 0.70 |
| 调休上班的周末 | 0.50 |
| 普通工作日 | 0.30 |
数据源:merged_poi.json 中 baidu_rating 字段(1–5 星,百度 POI API 采集)
| 评分 | 5.0★ | 4.6★ | 4.4★ | 3.7★ | 3.0★ |
|---|---|---|---|---|---|
| H | 1.00 | 0.90 | 0.85 | 0.68 | 0.50 |
数据源:weather_cache.json(网格数据,weather_cron_grid.py 每日从 wttr.in 采集,覆盖 1112 个 0.1° 网格)
| 温度 | 15°C | 20°C | 25°C | 30°C | 35°C | 40°C |
|---|---|---|---|---|---|---|
| 得分 | 0.50 | 0.75 | 1.00 | 0.75 | 0.50 | 0.25 |
| 降水概率 | 0% | 30% | 60% | 90% | 100% |
|---|---|---|---|---|---|
| rain_score | 1.00 | 0.73 | 0.46 | 0.19 | 0.10 |
数据源:百度迁徙 API(免费公开,huiyan.baidu.com,深圳 city_id=440300)
百度迁徙指数是基于 LBS 定位的城市间人口流动相对指标(规模指数,非人数)。取最近 7 日迁入指数做 Z-score 归一化:
示例(2026-07-09):current=11.80, avg7=10.31, z=0.62 → M = (0.62+2)/4 = 0.656
数据源:内置专家矩阵,按景点类型 × 月份的周期规律手动编码
| 类型 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 水上乐园 | 0.2 | 0.2 | 0.3 | 0.5 | 0.8 | 0.9 | 1.0 | 1.0 | 0.9 | 0.5 | 0.2 | 0.1 |
| 主题公园 | 0.7 | 0.7 | 0.6 | 0.6 | 0.7 | 0.8 | 1.0 | 1.0 | 0.7 | 0.7 | 0.6 | 0.6 |
| 城市公园 | 1.0 | 1.0 | 1.0 | 0.8 | 0.6 | 0.5 | 0.5 | 0.5 | 0.6 | 0.8 | 1.0 | 1.0 |
| 生态公园 | 1.0 | 1.0 | 1.0 | 0.9 | 0.7 | 0.6 | 0.6 | 0.6 | 0.7 | 0.9 | 1.0 | 1.0 |
| 海滨景区 | 0.5 | 0.5 | 0.5 | 0.6 | 0.8 | 0.9 | 1.0 | 1.0 | 0.9 | 0.7 | 0.5 | 0.5 |
| 博物馆 | 0.8 | 0.8 | 0.8 | 0.8 | 0.8 | 0.8 | 0.9 | 0.9 | 0.8 | 0.8 | 0.8 | 0.8 |
节假日对不同类型景点的影响差异显著。水上乐园/主题乐园在节假日爆发,自然景区反降。
| 类型 | multiplier | 工作日 D=0.30 | 周末 D=0.70 | 假日 D=1.00 |
|---|---|---|---|---|
| 水上乐园 | 0.8 | 1.00 | 1.32 | 1.56 |
| 主题乐园/游乐园 | 0.5 | 1.00 | 1.20 | 1.35 |
| 城市公园/普通公园 | 0.0 | 1.00 | 1.00 | 1.00 |
| 生态公园/自然景区 | -0.3 | 1.00 | 0.88 | 0.79 |
| capacity | 100 | 50 | 30 | 25 | 10 | 5 |
|---|---|---|---|---|---|---|
| cap_factor | 1.000 | 0.852 | 0.744 | 0.706 | 0.519 | 0.388 |
说明:capacity 为相对容量参数(非真实面积)。深圳湾公园=100,簕杜鹃谷=30,玛雅水公园=25。
指数 0.8 < 1 产生中段放大效果,使 40-70 区间区分度更高。压缩比:
| raw | 30 | 40 | 50 | 60 | 70 | 80 | 90 |
|---|---|---|---|---|---|---|---|
| compressed | 38.2 | 48.0 | 57.4 | 66.5 | 75.2 | 83.7 | 91.9 |
数据源:百度交通态势 API (api.map.baidu.com/traffic/v1/around),以景点坐标为中心画半径 1500m 圆查询周边道路。
对返回的 road_traffic[].congestion_sections[] 综合计算:
| 子项 | 权重 | 公式 |
|---|---|---|
| 速度评分 | 40% | max(0, (40 − avg_speed) / 30 × 100) |
| 拥堵等级 | 40% | status (1/2/3) → 33%/67%/100% |
| 趋势调整 | 20% | WORSE +20 / SAME 0 / BETTER −20 |
无拥堵路段时,根据整体 evaluation.status 赋底分:畅通=15,缓行=30,拥堵=45。
非对称设计:公园周边拥堵 → 人可以多(证实),通畅 ≠ 人少(不强力压低)
| 条件 | effective_K | 含义 |
|---|---|---|
| T > baseline(路况拥堵) | 0.30 | 拥堵证实预测,全增益 |
| T ≤ baseline(路况通畅) | 0.10 | 通畅不强力压低,1/3 增益 |
| 评分 | 等级 | 颜色 | 色值 |
|---|---|---|---|
| 0–19 | 畅游 | #3fb950 | |
| 20–39 | 舒适 | #58a6ff | |
| 40–59 | 适中 | #d2991d | |
| 60–79 | 较挤 | #f85149 | |
| 80–100 | 拥挤 | #d7000f |
景点:玛雅水公园 | 日期:2026-07-09(周四)
天级基线 × 时段系数,叠加实时路况修正。为控制百度交通态势 API 调用量,采用空间聚合 + 按需查询 + 时段推算三层优化策略。
640 个有分类标签的 POI 按 0.012° 网格(约 1.3km)聚簇,同簇内 POI 共享同一路况查询结果。去重后约 150 个簇,每次查询量从 640 降至 150。
并非每小时都查询百度 API,而是精选 16 个关键时刻:
3:00 夜间低谷基准 6:00 清晨开始 9:00 早高峰后 10:00 上午稳定段 11:00 午前上升 12:00 午间 13:00 午后 14:00 下午段 15:00 下午段 16:00 下午段 17:00 晚高峰前 18:00 晚高峰 19:00 晚间段 20:00 晚间段 21:00 晚间收尾 24:00 午夜
每个小时对应一个时段系数(0.00~1.00),15:00 为峰值 1.00:
| 小时 | 系数 | 小时 | 系数 | 小时 | 系数 |
|---|---|---|---|---|---|
| 0 | 0.05 | 8 | 0.55 | 16 | 0.95 |
| 1 | 0.05 | 9 | 0.75 | 17 | 0.90 |
| 2 | 0.05 | 10 | 0.85 | 18 | 0.85 |
| 3 | 0.05 | 11 | 0.85 | 19 | 0.80 |
| 4 | 0.05 | 12 | 0.80 | 20 | 0.75 |
| 5 | 0.05 | 13 | 0.85 | 21 | 0.15 |
| 6 | 0.20 | 14 | 0.90 | 22 | 0.10 |
| 7 | 0.35 | 15 | 1.00 | 23 | 0.08 |
非 16 个查询时间点的小时,使用最近一次查询结果 × 时段系数比进行推算:
推算结果再与 baseline 做非对称卡尔曼融合,得到最终 crowd_score。
| 方案 | 每轮查询数 | 每日查询轮次 | 每日总调用量 |
|---|---|---|---|
| 旧: 全量 POI 每小时 | 640 | 24 | 15,360 |
| 新: 聚簇后 16 个查询点 | 150 | 16 | 2,400 |
| 优化幅度 | -84.4% | ||
预测模型通过三层管道嵌入 Kids-Trip 系统,前端无需额外请求:拥挤评分随 POI 列表一并下发。
| 路径 | 触发 | 更新频率 | 延迟 |
|---|---|---|---|
| 天气采集 → weather_cache.json | weather_cron_grid.py | 每天 1 次 | ≤ 24h |
| 百度迁徙 → 内存序列 | crowd_predict.py 读取 | 每次预测时拉取 | ≤ 1 天 |
| POI 数据 → merged_poi.json | 手动 / 定期脚本 | ~14 天 | ≤ 14 天 |
| 天级基线 → crowd_cache.json | crowd_daily_cron.py | 每天 6:00 | ≤ 24h |
| 路况融合 → crowd_cache.json | crowd_hourly_cron.py | 16 次/天 | ≤ 1h(非查询时段推算) |
| API 读取 → 前端展示 | 用户访问页面 | 每次请求 | 即时 |
前端请求 /kids-api/recommend,server.py 从 crowd_cache.json 中按 uid 匹配,为每个 POI 附加三个字段:
crowd_score → POI 卡片拥挤进度条 + 数字 crowd_level → 彩色标签 (畅游/舒适/适中/较挤/拥挤) crowd_ci → 展开后显示置信区间
无需前端额外请求,crowd 数据随 POI 列表一次返回。
用户点击 POI 卡片进入详情页时,前端调用 /kids-api/crowd/:uid 获取完整因子拆解:
{
"uid": "92dd57b6",
"name": "玛雅水公园",
"crowd_score": 50.2,
"crowd_level": "适中",
"confidence_interval": [44.5, 55.9],
"factors": {
"D": { "value": 0.30, "weight": 0.35, "label": "工作日" },
"H": { "value": 0.85, "weight": 0.25, "label": "4.4★" },
"W": { "value": 0.94, "weight": 0.15, "label": "28°C 无雨" },
"M": { "value": 0.66, "weight": 0.15, "label": "Z=0.62" },
"S": { "value": 1.00, "weight": 0.10, "label": "7月旺季" }
},
"traffic": {
"score": 15.0,
"status": "畅通",
"K_eff": 0.10,
"sections": []
},
"baseline_raw": 46.6,
"baseline_compressed": 54.1
}
如果 crowd_cache.json 中某景点无数据(新增景点 / 首次运行前):
crowd_score 返回 null| 步骤 | 内容 | 状态 |
|---|---|---|
| 1 | crowd_predict.py — 核心预测函数,完成五因子模型 | 已完成 |
| 2 | crowd_daily_cron.py — 每天 6:00 遍历 POI 写基线 | 已完成 |
| 3 | crowd_hourly_cron.py — 聚簇 + 16点查询 + 时段推算 + 卡尔曼融合 | 已完成 |
| 4 | server.py 读取 crowd_cache.json 附加到 /api/recommend | 已完成 |
| 5 | server.py /api/crowd/:uid 因子拆解端点 | 待开发 |
| 6 | 前端 POI 卡片拥挤标签 + 进度条 | 待开发 |
| 7 | 前端详情页因子拆解面板 | 待开发 |
| 8 | crontab 注册两条定时任务 | 已完成 |
# 每天 6:00 计算天级基线 0 6 * * * cd /var/www/kids-trip && python3 crowd_daily_cron.py >> /var/log/kids-trip/crowd_daily.log 2>&1 # 每天 16 个查询点 (3,6,9,10,11,12,13,14,15,16,17,18,19,20,21,24 整点) 0 3,6,9,10,11,12,13,14,15,16,17,18,19,20,21,0 * * * cd /var/www/kids-trip && python3 crowd_hourly_cron.py >> /var/log/kids-trip/crowd_hourly.log 2>&1
| 参数 | 当前值 | 可调方向 |
|---|---|---|
| 五因子权重 | 35/25/15/15/10 | 依据真实人流数据做线性回归校准 |
| D 日期阈值 | 0.30/0.50/0.70/1.00 | 可替换为连续函数 D = t + weekend_bonus |
| H 热度公式 | (rating−1)/4 线性 | 可加权(加入评论数、来源一致性) |
| W 温雨权重 | temp:rain=40:60 | 加入 AQI、风速、体感温度 |
| M Z 归一化 | (z+2)/4 → [0.1, 1] | 替换为净流入、来源城市结构 |
| S 季节矩阵 | 6 类 × 12 月 | 扩展至更多景点类型 |
| type_corr multiplier | 0.5–0.8 | 与实际数据拟合修正 |
| 容量 cap_factor | ln(cap+1)/ln(101) | 替换为 sigmoid / 相对排名 |
| 压缩指数 | 0.8 | 1.0=线性,<1=中段放大 |
| R_pred / R_cong | 12 / 28 | 可按景点类型差异化 |
| 路况非对称比 | K / 3 (通畅侧) | 可调整甚至完全不做通畅侧修正 |
| 路况查询半径 | 1500m | 根据景点规模调整 |
| 景点 | 评分 | 等级 | 95% CI | D | H | W | M | S | 路况 |
|---|---|---|---|---|---|---|---|---|---|
| 深圳湾公园 | 62.9 | 较挤 | [57.2, 68.5] | 0.30 | 0.90 | 0.94 | 0.66 | 0.50 | 畅通 |
| 簕杜鹃谷(九围) | 46.6 | 适中 | [41.0, 52.3] | 0.30 | 0.68 | 0.90 | 0.66 | 0.60 | 畅通 |
| 玛雅水公园 | 50.2 | 适中 | [44.5, 55.9] | 0.30 | 0.85 | 0.94 | 0.66 | 1.00 | 畅通 |