景点人流预测模型

Kids-Trip 项目 / 版本 2026-07 / hk.jarrich.cn/kids-trip / 预测脚本 crowd_predict.py

1. 概述

本模型融合 6 个真实数据源,对景点人流量输出 0-100 评分,支持天级和小时级预测。 核心思路:五因子加权基线 → 类型修正 → 容量约束 → 非线性压缩 → 路况实时卡尔曼融合。

2. 计算链路

计算链路图

3. 数据源总览

因子权重数据源真实度更新频率粒度
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 或本地真实缓存。

4. 五因子基线公式

raw = 0.35·D + 0.25·H + 0.15·W + 0.15·M + 0.10·S

4.1 日期因子 D

数据源:chinese_calendar(含中国法定假日、调休数据)

日期类型D 值
法定假日(非周末,如春节、国庆)1.00
普通周末0.70
调休上班的周末0.50
普通工作日0.30

4.2 热度因子 H

数据源:merged_poi.jsonbaidu_rating 字段(1–5 星,百度 POI API 采集)

H = max(0.1, (rating − 1) / 4)
评分5.0★4.6★4.4★3.7★3.0★
H1.000.900.850.680.50

4.3 天气因子 W

数据源:weather_cache.json(网格数据,weather_cron_grid.py 每日从 wttr.in 采集,覆盖 1112 个 0.1° 网格)

温度舒适度(权重 40%)

temp_score = max(0.2, 1 − |temp − 25| / 20)
温度15°C20°C25°C30°C35°C40°C
得分0.500.751.000.750.500.25

降雨惩罚(权重 60%)

rain_score = 1.0(晴天) / max(0.1, 1 − precip_prob/100 × 0.9)(雨天)
降水概率0%30%60%90%100%
rain_score1.000.730.460.190.10

最终加权

W = temp_score × 0.4 + rain_score × 0.6

4.4 迁徙因子 M

数据源:百度迁徙 API(免费公开,huiyan.baidu.com,深圳 city_id=440300)

百度迁徙指数是基于 LBS 定位的城市间人口流动相对指标(规模指数,非人数)。取最近 7 日迁入指数做 Z-score 归一化:

M = clamp( (zscore + 2) / 4 , 0.1, 1.0 )

示例(2026-07-09):current=11.80, avg7=10.31, z=0.62 → M = (0.62+2)/4 = 0.656

4.5 季节因子 S

数据源:内置专家矩阵,按景点类型 × 月份的周期规律手动编码

类型1月2月3月4月5月6月7月8月9月10月11月12月
水上乐园0.20.20.30.50.80.91.01.00.90.50.20.1
主题公园0.70.70.60.60.70.81.01.00.70.70.60.6
城市公园1.01.01.00.80.60.50.50.50.60.81.01.0
生态公园1.01.01.00.90.70.60.60.60.70.91.01.0
海滨景区0.50.50.50.60.80.91.01.00.90.70.50.5
博物馆0.80.80.80.80.80.80.90.90.80.80.80.8

5. 三层修正

5.1 景点类型修正

corr = 1.0 + (D − 0.3) × multiplier

节假日对不同类型景点的影响差异显著。水上乐园/主题乐园在节假日爆发,自然景区反降。

类型multiplier工作日 D=0.30周末 D=0.70假日 D=1.00
水上乐园0.81.001.321.56
主题乐园/游乐园0.51.001.201.35
城市公园/普通公园0.01.001.001.00
生态公园/自然景区-0.31.000.880.79

5.2 容量约束

cap_factor = ln(1 + capacity) / ln(101)
capacity100503025105
cap_factor1.0000.8520.7440.7060.5190.388

说明:capacity 为相对容量参数(非真实面积)。深圳湾公园=100,簕杜鹃谷=30,玛雅水公园=25。

5.3 非线性压缩

compressed = 100 × (baseline/100) ^ 0.8

指数 0.8 < 1 产生中段放大效果,使 40-70 区间区分度更高。压缩比:

raw30405060708090
compressed38.248.057.466.575.283.791.9

6. 百度交通态势 & 卡尔曼融合

6.1 路况评分计算

数据源:百度交通态势 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。

6.2 非对称卡尔曼融合

R_pred = 12.0(预测噪声)  R_cong = 28.0(路况噪声)
K_full = 12 / (12+28) = 0.30

非对称设计:公园周边拥堵 → 人可以多(证实),通畅 ≠ 人少(不强力压低)

条件effective_K含义
T > baseline(路况拥堵)0.30拥堵证实预测,全增益
T ≤ baseline(路况通畅)0.10通畅不强力压低,1/3 增益
fused = compressed + K_eff × (T − compressed)

6.3 置信区间

σ² = R_pred × R_cong / (R_pred + R_cong) = 8.4
σ = 2.90
95% CI = [score − 5.7, score + 5.7]

7. 拥挤等级

畅游 舒适 适中 较挤 拥挤
评分等级颜色色值
0–19畅游#3fb950
20–39舒适#58a6ff
40–59适中#d2991d
60–79较挤#f85149
80–100拥挤#d7000f

8. 完整计算示例

景点:玛雅水公园 | 日期:2026-07-09(周四)

输入因子: D=0.30 (工作日) H=0.85 (4.4★) W=0.94 (28°C,无雨) M=0.66 (z=0.62) S=1.00 (7月旺季) ① 五因子加权: raw = 0.35×0.30 + 0.25×0.85 + 0.15×0.94 + 0.15×0.66 + 0.10×1.00 = 0.660 ② 类型修正: corr = 1.0 + (0.30−0.30)×0.8 = 1.00 (工作日无放大) after_corr = 0.660 × 1.00 = 0.660 ③ 容量约束: cap = ln(26)/ln(101) = 0.706 baseline = 0.660 × 0.706 × 100 = 46.6 ④ 非线性压缩: compressed = 100 × (46.6/100)^0.8 = 54.1 ⑤ 路况融合: T = 15.0 (整体畅通) K_eff = 0.10 (通畅侧, 1/3增益) fused = 54.1 + 0.10 × (15.0 − 54.1) = 50.2 ⑥ 等级判定: 50.2 → 适中, 95%CI = [44.5, 55.9]

9. 小时级预测

天级基线 × 时段系数,叠加实时路况修正。为控制百度交通态势 API 调用量,采用空间聚合 + 按需查询 + 时段推算三层优化策略。

crowd_hourly = baseline_daily × hour_coeff(h) ± traffic_correction

9.1 空间聚合:经纬度聚簇

640 个有分类标签的 POI 按 0.012° 网格(约 1.3km)聚簇,同簇内 POI 共享同一路况查询结果。去重后约 150 个簇,每次查询量从 640 降至 150。

9.2 查询时段:16 个有代表性时间点

并非每小时都查询百度 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  午夜

9.3 时段系数曲线

每个小时对应一个时段系数(0.00~1.00),15:00 为峰值 1.00:

小时系数小时系数小时系数
00.0580.55160.95
10.0590.75170.90
20.05100.85180.85
30.05110.85190.80
40.05120.80200.75
50.05130.85210.15
60.20140.90220.10
70.35151.00230.08

9.4 非查询时段推算

非 16 个查询时间点的小时,使用最近一次查询结果 × 时段系数比进行推算:

traffic_now = traffic_queried × (coeff(now) / coeff(queried))

推算结果再与 baseline 做非对称卡尔曼融合,得到最终 crowd_score。

9.5 API 调用量对比

方案每轮查询数每日查询轮次每日总调用量
旧: 全量 POI 每小时6402415,360
新: 聚簇后 16 个查询点150162,400
优化幅度-84.4%

10. 系统集成设计

10.1 整体架构

预测模型通过三层管道嵌入 Kids-Trip 系统,前端无需额外请求:拥挤评分随 POI 列表一并下发。

┌──────────────────────────────────────────────────────────────────┐ │ 数据采集层 (Cron) │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ wttr.in │ │ 百度迁徙 │ │ 百度POI │ │ 百度交通态势 │ │ │ │ 天气网格 │ │ 迁入指数 │ │ 评分数据 │ │ 周边路况 API │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ weather_cache 迁徙历史序列 merged_poi 实时路况 │ │ .json (内存) .json (按需拉取) │ └────────────────────────────┬─────────────────────────────────────┘ │ ┌────────────────────────────▼─────────────────────────────────────┐ │ 预测引擎 (Python) │ │ │ │ crowd_daily_cron.py crowd_hourly_cron.py │ │ 每天 6:00 执行 每小时执行 │ │ ├─ 读取 4 个静态数据源 ├─ 读取 crowd_cache.json │ │ ├─ 遍历 217 个景点 ├─ 拉取百度交通态势 │ │ ├─ 计算 baseline + level ├─ 非对称卡尔曼融合 │ │ └─ 写入 crowd_cache.json └─ 更新 live_score / CI │ └────────────────────────────┬─────────────────────────────────────┘ │ crowd_cache.json ┌────────────────┐ │ { │ │ "92dd57b6": {│ │ baseline, │ │ live_score,│ │ level, │ │ ci_low, │ │ ci_high, │ │ factors, │ │ timestamp │ │ }, ... │ │ } │ └───────┬────────┘ │ ┌───────────────────────────▼──────────────────────────────────────┐ │ API 服务层 │ │ │ │ server.py (Flask) :8767 │ │ ┌───────────────────────────────────────────────┐ │ │ │ GET /api/recommend │ │ │ │ ├─ 加载 merged_poi.json (POI 基础数据) │ │ │ │ ├─ 加载 crowd_cache.json (预测数据) │ │ │ │ ├─ 按 uid 匹配,附加字段到每个 POI │ │ │ │ └─ 返回 JSON: { pois: [{ │ │ │ │ ...原字段, │ │ │ │ crowd_score: 62.9, │ │ │ │ crowd_level: "较挤", │ │ │ │ crowd_ci: [57.2, 68.5] │ │ │ │ }]} │ │ │ │ │ │ │ │ GET /api/crowd/:uid │ │ │ │ └─ 单景点详细预测 + 因子拆解 │ │ │ └───────────────────────────────────────────────┘ │ └───────────────────────────┬──────────────────────────────────────┘ │ ▼ Nginx /kids-api/ → :8767/api/ ┌──────────────────────────────────────────────────────────────────┐ │ 前端展示层 │ │ │ │ kids-trip 首页 POI 卡片 │ │ ┌─────────────────────────────────────┐ │ │ │ 深圳湾公园 ★4.6 │ │ │ │ ┌──────────────────────────┐ 较挤 │ ← crowd_level │ │ │ │▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░│ 63 │ ← crowd_score │ │ │ └──────────────────────────┘ │ │ │ │ 预计拥挤 95%置信区间 57-69 │ ← 点击展开因子拆解 │ │ └─────────────────────────────────────┘ │ │ │ │ 详情页 │ │ ┌─────────────────────────────────────────┐ │ │ │ 人流预测详情 │ │ │ │ 拥挤评分: 62.9 等级: 较挤 │ │ │ │ 置信区间: [57.2, 68.5] │ │ │ │ ───────────────────── │ │ │ │ 日期: 工作日(0.30) ██░░░░░░ 权重35% │ │ │ │ 热度: 4.6★(0.90) ██████░░ 权重25% │ │ │ │ 天气: 28°C无雨(0.94) ██████░░ 权重15% │ │ │ │ 迁徙: Z=0.62(0.66) ████░░░░ 权重15% │ │ │ │ 季节: 夏季(0.50) ███░░░░░ 权重10% │ │ │ │ 路况: 周边畅通 [卡尔曼融合 K=0.10] │ │ │ └─────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘

10.2 数据流与延迟

路径触发更新频率延迟
天气采集 → weather_cache.jsonweather_cron_grid.py每天 1 次≤ 24h
百度迁徙 → 内存序列crowd_predict.py 读取每次预测时拉取≤ 1 天
POI 数据 → merged_poi.json手动 / 定期脚本~14 天≤ 14 天
天级基线 → crowd_cache.jsoncrowd_daily_cron.py每天 6:00≤ 24h
路况融合 → crowd_cache.jsoncrowd_hourly_cron.py16 次/天≤ 1h(非查询时段推算)
API 读取 → 前端展示用户访问页面每次请求即时

10.3 关键交互

首页 POI 列表

前端请求 /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
}

API 无预测数据时的降级

如果 crowd_cache.json 中某景点无数据(新增景点 / 首次运行前):

10.4 部署清单

步骤内容状态
1crowd_predict.py — 核心预测函数,完成五因子模型已完成
2crowd_daily_cron.py — 每天 6:00 遍历 POI 写基线已完成
3crowd_hourly_cron.py — 聚簇 + 16点查询 + 时段推算 + 卡尔曼融合已完成
4server.py 读取 crowd_cache.json 附加到 /api/recommend已完成
5server.py /api/crowd/:uid 因子拆解端点待开发
6前端 POI 卡片拥挤标签 + 进度条待开发
7前端详情页因子拆解面板待开发
8crontab 注册两条定时任务已完成

10.5 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

11. 调度架构

crontab: 0 6 * * * python3 /var/www/kids-trip/crowd_daily_cron.py │ └── 每天 6:00: 计算 217 个景点的天级基线 (D/H/W/M/S → baseline → 写入 crowd_cache.json) 0 3,6,9-21,0 * * * python3 /var/www/kids-trip/crowd_hourly_cron.py │ └── 每天 16 次: 聚簇查询百度交通态势(150簇) → 非查询时段按系数推算 → 卡尔曼融合 → 更新 live 评分 /api/recommend │ └── server.py 读取 crowd_cache.json → 附加 crowd_score / crowd_level 到每个 POI

12. 可调参数清单

参数当前值可调方向
五因子权重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 multiplier0.5–0.8与实际数据拟合修正
容量 cap_factorln(cap+1)/ln(101)替换为 sigmoid / 相对排名
压缩指数0.81.0=线性,<1=中段放大
R_pred / R_cong12 / 28可按景点类型差异化
路况非对称比K / 3 (通畅侧)可调整甚至完全不做通畅侧修正
路况查询半径1500m根据景点规模调整

13. 当前预测(2026-07-10 周五)

景点评分等级95% CIDHWMS路况
深圳湾公园62.9较挤[57.2, 68.5]0.300.900.940.660.50畅通
簕杜鹃谷(九围)46.6适中[41.0, 52.3]0.300.680.900.660.60畅通
玛雅水公园50.2适中[44.5, 55.9]0.300.850.940.661.00畅通

/var/www/kids-trip/crowd_predict.py 实时生成,结果写入 crowd_prediction_result.json