andreslill/lfb-response-time-analysis
GitHub: andreslill/lfb-response-time-analysis
一个基于Streamlit的交互式仪表板,分析伦敦消防队2021至2025年间58.6万起事件的响应时间表现,揭示地理因素对响应绩效的主导作用并提供假设性场景模拟能力。
Stars: 0 | Forks: 0
# 伦敦消防队响应时间分析 (2021–2025)



一个用于分析伦敦整体作战响应表现的交互式仪表板。
**核心洞察:** 自治市面积通过行程时间主导了响应表现的大部分差异。出动时间在所有站点几乎保持不变。
**[Streamlit 仪表板 →](https://lfb-response-time-dashboard-cqk7jfyroyw9dfkfbcj9w5.streamlit.app/)**
## 项目概述
伦敦消防队针对第一辆消防车设定了两个官方性能基准:
- 第一辆水泵车在 **6 分钟**内到达
- 90% 的第一辆水泵车在 **10 分钟**内到达
针对第二辆消防车存在一个单独的 8 分钟目标。然而,由于第二辆水泵车仅部署于 36% 的事件中(反映为第二辆水泵车出动时间 64% 的缺失率),因此它无法为跨事件比较提供一致的基础,故不包含在本分析中。
本报告检视了在不同时间段、事件类型和地理区域下,对第一辆消防车目标的遵守情况,以及驱动响应表现差异的结构性因素。
**核心发现:** 地理位置是表现差异的主要驱动因素。自治市面积解释了 59% 的响应时间中位数差异和 62% 的 6 分钟合规率差异。行程时间约占总响应时间的 77%,而出动时间在所有自治市中保持显著稳定(四分位距 IQR:仅 4 秒)。
## 仪表板预览
### 站点覆盖与部署模式

**图 1.** *伦敦各地的消防站覆盖情况。圆圈大小代表每个站点出警的事件数量,颜色表示行程时间中位数。工具提示显示站点级别的部署指标。*
### 响应时间分布

**图 2.** *各事件第一辆水泵车响应时间分布。垂直线分别表示中位数、平均值、第 90 百分位数和官方 6 分钟响应目标。*
## 仪表板页面
| 页面 | 描述 |
|------|-------------|
| **Introduction (简介)** | 项目背景、研究问题和仪表板结构 |
| **Executive Summary (执行摘要)** | 全市关键绩效指标、响应时间分布和性能概览 |
| **Incident Composition (事件构成)** | 按事件类型细分、季节性模式和每小时需求热力图 |
| **Response Performance (响应表现)** | 按事件类型、月份和一天中各小时计算的合规率 |
| **Geographic Performance (地理表现)** | 响应时间、合规率和事件数量的自治市级别等值线图 |
| **Drivers of Response Time (响应时间驱动因素)** | 出动与行程时间分解、每小时变化及延误代码分析 |
| **Key Findings & Implications (关键发现与启示)** | 发现总结、运营启示、研究局限性和未来展望 |
| **Scenario Explorer (场景探索器)** | 交互式假设工具:模拟每个自治市统一减少行程时间,并基于事件级数据直接重新计算 6 分钟合规率 |
所有描述性页面均根据侧边栏筛选器(年份、月份、事件类型)动态更新。场景探索器使用完整的 2021–2025 年数据以确保最大样本量。
## 关键发现
- **响应时间中位数:5.02 分钟**,在总体水平上低于 6 分钟目标
- **6 分钟合规率:69.5%**,意味着大约三分之一的真实事件超过了主要目标
- **自治市范围:** 4.22 分钟(Kensington & Chelsea)至 6.02 分钟(Hillingdon),差距为 1.80 分钟
- **行程时间**约占总响应时间的 77%,而出动时间高度一致(IQR:4 秒)
- **自治市面积**解释了 59% 的响应时间差异和 62% 的合规率差异(r = −0.79)
- **61.6% 的所有超标记录**被标记为“未受阻”,意味着没有特定的运营原因
## 交互式场景分析
场景探索器页面超越了描述性分析。它模拟了如果行程时间统一减少特定秒数,6 分钟合规率将如何变化。它使用来自基础事件级数据的直接重新计算,而非基于汇总数据的估算。
这使得针对任何特定自治市,量化需要多少运营改进(例如新建站点或路线优化)才能显著改变合规率成为可能。
## 技术栈
- **Python**:数据处理与分析
- **Pandas / NumPy**:数据操作和统计计算
- **Streamlit**:多页面交互式仪表板
- **Matplotlib / Seaborn**:静态可视化
- **Plotly**:交互式等值线图
- **GeoPandas / Folium**:地理边界数据与地图绘制
- **SciPy**:统计检验(相关性分析)
- **statsmodels**:OLS 回归与统计建模
## 数据管道
分析管道包含三个阶段:
1. **数据获取** – 从 London Datastore 下载伦敦消防队事件和调度数据集。
2. **数据准备** – 清洗、合并数据集,并筛选出 2021–2025 年间的事件。调度记录使用第一辆水泵车到达时间聚合到事件级别。
3. **空间丰富** – 将站点坐标与自治市边界连接,以分析站点覆盖和跨自治市部署情况。
处理后的数据集导出为压缩的 **Parquet (Snappy)** 格式,以便在 Streamlit 仪表板中快速加载。
## 项目结构
```
lfb-response-time-dashboard/
│
├── Introduction.py # Entry point
├── data_loader.py # Cached data loading and preprocessing
├── pages/
│ ├── 1_Executive_Summary.py
│ ├── 2_Incident_Composition.py
│ ├── 3_Response_Performance.py
│ ├── 4_Geographic_Performance.py
│ ├── 5_Drivers_of_Response_Time.py
│ └── 6_Key_Findings_&_Implications.py
├── Data/
│ ├── lfb_streamlit.parquet
│ ├── london_boroughs/ # GeoJSON boundary files
│ └── london_population_borough.csv
├── analysis/
│ └── London_Fire_Brigade_Analysis.ipynb # EDA and preprocessing notebook
├── .streamlit/
│ └── config.toml # Theme configuration
├── requirements.txt
└── README.md
```
## 本地运行应用
```
pip install -r requirements.txt
streamlit run Introduction.py
```
## 数据来源
使用了通过 London Datastore 获取的两个伦敦消防队公开数据集。
- **LFB Incident Records (事件记录)** — [data.london.gov.uk](https://data.london.gov.uk/dataset/london-fire-brigade-incident-records)
- **LFB Mobilisation Records (调度记录)** — [data.london.gov.uk](https://data.london.gov.uk/dataset/london-fire-brigade-mobilisation-records)
地理边界数据(GIS 自治市边界)来源于 [London Datastore Statistical GIS Boundary Files](https://data.london.gov.uk/dataset/statistical-gis-boundary-files-for-london-20od9/)。
### 消防站位置(站点覆盖图)
站点坐标来源于 Open Data Institute (ODI) 消防与救援分析仓库:
- 仓库:https://github.com/theodi/FNR_Analysis
- 使用文件:https://raw.githubusercontent.com/theodi/FNR_Analysis/refs/heads/master/data/preprocessed/stations.csv
- ODI 项目背景(站点关闭影响工具):https://theodi.org/project/tools-developing-tools-to-assess-the-impact-of-fire-station-closures/
ODI 站点列表反映了 2014 年之前的伦敦消防队站点网络。2014 年 1 月,作为《第五次伦敦安全计划》的一部分,十个站点被关闭,站点总数从 112 个减少到 102 个。
ODI 文件包含 113 个站点条目,这与通常报道的数量(例如 112 个)略有不同。这种差异可能反映了在站点清单中如何表示专业或非标准单位(例如河流/支援站点)的不同。
对于本项目,站点坐标仅用于**空间可视化**。运营指标来源于伦敦消防队事件和调度数据集,并在连接原始年度文件后,基于筛选出的 2021–2025 年子集进行计算。
站点覆盖指标通过 `analysis/prepare_station_coverage.py` 生成,该脚本将站点坐标与自治市边界关联,并从筛选后的事件数据中聚合站点部署模式。
完整的数据预处理和探索性分析管道记录在 [`analysis/London_Fire_Brigade_Analysis.ipynb`](analysis/London_Fire_Brigade_Analysis.ipynb) 中。
## 分析笔记本
[`analysis/London_Fire_Brigade_Analysis.ipynb`](analysis/London_Fire_Brigade_Analysis.ipynb)
包含完整的分析管道,是所有仪表板发现的方法论基础。
**结构:**
- **步骤 1:数据探索:** 分别检查两个原始数据集(事件和调度),包括分布分析、变量分类和元数据审查。
- **步骤 2:清洗与预处理:** 记录每列的缺失值处理策略、日期时间特征工程(小时、工作日、月份、年份)以及数据集合并。
- **步骤 3:探索性数据分析 (EDA):** 包含 10 个分析部分,涵盖事件趋势、时间需求模式、响应时间分布、自治市级别性能和延误代码分析。包括单因素方差分析(到达时间 ~ 报警小时)及 Eta² 效应量以量化一天中时间的影响,以及 OLS 回归以识别自治市级别响应时间差异的结构性驱动因素。
- **步骤 4:导出:** 将处理后的数据集导出为压缩 Parquet 格式供 Streamlit 仪表板使用。
笔记本不仅记录了发现了*什么*,还记录了*为什么*做出特定的分析选择——包括排除第二辆水泵车数据(64% 缺失率)的原因,以及在响应时间比较中使用中位数而非平均数的理由。
## 作者
Andrés Lill · 2026
标签:DNS解析, Folium, GeoPandas, Kubernetes, Mutation, Plotly, Python, Streamlit, 交互式地图, 代码示例, 仪表盘, 伦敦, 伦敦消防队, 公共安全, 可视化, 响应时间, 地理空间分析, 库, 应急响应, 开源项目, 政府数据, 数据分析, 无后门, 智慧城市, 消防站覆盖, 访问控制, 运营绩效, 逆向工具