城市共享单车
动态定价策略
基于纽约 CitiBike 大数据的站点需求预测与智能定价
大数据管理与应用 · 课程设计 Topic 2 · 2026年6月
基于纽约 CitiBike 大数据的站点需求预测与智能定价
大数据管理与应用 · 课程设计 Topic 2 · 2026年6月
Shakleen · CitiBike-Demand-Prediction
借鉴:Medallion数据管道、事件拆分、双目标回归、训练流水线
用于:阶段二、阶段四
Charan · CitiBike_BigData (Bikenomic)
借鉴:供需缺口定价思路、站点空间推荐逻辑
用于:阶段五
19个特征完整清单(括号=中译)
11 时间特征
month(月份)· day(日)
weekday(星期几)· weekofyear(第几周)
dayofyear(第几天)· hour(小时)
is_weekend(是否周末)
is_rush_hour(是否早晚高峰)
hour_sin · hour_cos(小时周期编码)
weekday_sin · weekday_cos(星期周期编码)
is_holiday(是否假期)
5 业务
electric_ratio(电动车占比)
member_ratio(年费会员占比)
avg_trip_duration_min(平均骑行时长)
capacity(站点桩位数)
total_events(总事件数)
3 天气
temp_c(气温)· precip_mm(降水)
wind_kmh(风速)
5 个主成分解释
PC1 日周期节律 (34.8%) — hour_sin + hour_cos + is_rush_hour。描述"一天中哪个时段"
PC2 季节性趋势 (21.5%) — month + dayofyear + weekofyear。描述"一年中哪个季节"
PC3 周周期模式 (20.7%) — weekday + is_weekend + weekday_sin/cos。描述"工作日 vs 周末"
PC4 节假日效应 (11.6%) — is_holiday + day。节假日偏离正常模式的独立信号
PC5 残余变异 (11.5%) — 前 4 个没覆盖到的微小差异(如特殊活动)
PCA 做了什么?为什么需要它?
11 个时间特征中有很多"在说同一件事"——比如 hour、hour_sin、hour_cos 三个都在描述时间。PCA 把说同一件事的特征合成一个主成分,从 11 个压缩成 5 个。累计方差 100% = 压缩过程没有丢失任何信息,只是去掉了冗余。
三轮特征迭代 — R² 进化
模型:Random Forest (PySpark MLlib)
100棵树 · Bagging抗过拟合 · 自带特征重要性
350万训练数据 · R²=0.644, RMSE=3.04
特征重要性 Top-4
前3个业务特征合计 = 0.889 vs 所有时间特征合计 = 0.111
自研 Hyperopt 贝叶斯自动调参
"搜索空间" = 告诉算法"你可以试的参数范围":
每棵树最多长多深 (maxDepth:5-25)、造多少棵树 (numTrees:20-150)、每次用多少数据 (subsamplingRate:0.5-1.0) 等 5 个。
模型对比:RF vs GBT
| 指标 | Random Forest | GBT |
| R² | 0.644 | 0.142 |
| RMSE | 3.04 | 4.71 |
| 训练时间 | 57s | 44s |
GBT(梯度提升树)= Random Forest 的表兄弟。RF 是 100 棵树同时训练、投票平均;GBT 是一棵一棵串行训练,每棵新树专门修正前面所有树的错误。训练更快(44s vs 57s),但在我们只有时间特征时 R² 很低(0.14),加入业务特征后内存不够——因此选了 RF 做主模型。
设计理念
"预测 + 规则"解耦:ML模型负责准、规则引擎负责解释
19个特征去哪了?为什么定价只看车和桩?
19个特征 = 模型的知识。它们被训练时"喂"给了模型,所以模型看到"电动车多+会员多+早8点"就知道这个站需求高。但定价引擎只需要模型的输出数字(预测借出量、预测还入量)+ 当前库存。就像天气预报用了卫星云图、气压、湿度算出"明天80%下雨"——你出门只需看这个80%来决定带不带伞,不需要看卫星云图。
Surge 涨价 1.2-2.0×
借出需求 > 现有车辆 → 缺车涨价,引导用户步行 200米去附近有空余的站
Mild Surge 1.1-1.3×
还入需求 > 空桩数 → 站点快被塞满,阻止还车
Normal 标准定价 1.0×
供需基本平衡 → 维持 CitiBike 基础价 $4.49
Discount 降价 0.7-0.9×
车辆+空桩充裕 → 降价吸引用户来此站借车,消化闲置
全量分析结果:438万条记录
Surge(涨价):30,278条 (0.7%) · 均价 $6.72
Mild Surge:10,144条 (0.2%) · 均价 $5.25
Normal:406,000条 (9.3%) · 均价 $4.49
Discount:3,941,937条 (89.8%) · 均价 $3.56
三个 API 接口
PyEcharts 看板 (6图)
23个 pytest 测试
定价引擎 6场景 · 空间匹配 2场景 · 供需缺口 3场景 · IO 3场景 · 距离计算
23/23 全部通过 · 0.9秒
代码规范
flake8:0 错误 · PEP8标准 · 39源文件 + 4测试文件
自动化流水线
git push → flake8 → pytest → ✅
答辩当天怎么演示给老师看:
1. 打开终端,进入项目目录:cd <项目目录>
2. 运行 flake8:..\airline-satisfaction-analysis\venv\Scripts\python.exe -m flake8 src/ tests/ --count → 输出 0
3. 运行 pytest:..\airline-satisfaction-analysis\venv\Scripts\python.exe -m pytest tests/ -v → 23 条全部 PASSED
文档
Word 课程设计报告(含6张图表 + 7个截图位)
HTML 答辩演示(15页 · Signal风格)
Topic 9 制作指导 Markdown(供后续选题使用)
代码
39个 Python 源文件
4个测试文件(23个测试用例)
CI/CD GitHub Actions 配置
PEP8 标准 · flake8 0 错误
数据 + 模型
Bronze Parquet 1.3 GB(满足 ≥1GB)
Silver 73MB · Gold 188MB
4个 RF/GBT 训练好的模型
PCA 降维模型 + gold_pipeline
服务
FastAPI 在线推理服务(3个接口)
PyEcharts 数据看板大屏(6图表)
Swagger UI 自动文档
数据处理
特征工程
模型性能
工程质量
1 环境+数据 — venv · JDK 17 · PySpark · 下载 CitiBike 5个月 CSV + GBFS + 天气
2 数据管道 — Medallion 四层 Parquet(Raw→Bronze→Silver→Gold)。1450万 → 438万条
3 特征工程 — 空间匹配(99.3%) + 业务特征(3个) + 天气(3个) = 19特征。PCA降维
4 模型训练 — Random Forest · R² 0.14→0.64 · Hyperopt 贝叶斯优化 8轮
5 定价策略 ⭐ — 2×2供需矩阵 · 四场景定价 · 预测+规则解耦 · 438万条全量分析
6 API+看板 — FastAPI 三个接口 · PyEcharts 六个图表 · Swagger UI
7 测试+交付 — 23 tests · flake8 0 · CI/CD · Word报告 · HTML答辩
技术能力
商业思维
职业方向
核心认知:商业分析师的价值 = 数据 → 决策建议 → 可用的产品
演示地址:http://localhost:8000/docs
看板大屏:http://localhost:8000/dashboard
项目代码:bike-pricing-analysis/
大数据管理与应用 · 2026年6月 · 感谢老师的指导与聆听