基于 UCI 真实数据的城市 PM2.5 预测与预警系统实战
关键词PM2.5 预测、城市空气质量预测、UCI 真实数据、机器学习回归、GradientBoosting、AQI 预警、Streamlit 可视化、Python 数据分析项目、课程设计摘要这篇文章围绕一个可以直接运行的城市空气质量 PM2.5 预测与预警系统展开。项目使用 UCI Beijing Multi-Site Air Quality Data 整理出的北京 12 个监测站日级数据共 16,966 条记录时间范围为 2013-03-01 至 2017-02-28。系统完成了真实数据预处理、气象与污染物特征工程、多模型训练、PM2.5 下一日预测、AQI 预警等级转换、健康建议输出和 Streamlit Web 看板展示。项目不是只给几段模型代码而是提供完整源码、配置文件、真实数据整理脚本、训练脚本、预测 CSV、评估报告、结果图表和正式运行截图。核心模型包含 Ridge、RandomForestRegressor 和 GradientBoostingRegressor程序按测试集 MAE 自动选择最佳模型。本次真实数据运行结果中最佳模型为 GradientBoostingMAE 为 35.508 μg/m³RMSE 为 54.378 μg/m³R² 为 0.448预警等级准确率为 0.466。项目适合机器学习课程设计、数据挖掘实验、空气质量预测原型、Python 数据分析项目和 CSDN 项目实战展示。读者可以直接运行真实数据流程也可以替换为新的城市监测站数据继续扩展。1. 项目场景与业务目标PM2.5 是城市空气质量监测中最常见的指标之一它受季节、温度、湿度、气压、风速、降雨和其他污染物共同影响。空气质量预测项目的重点不只是拟合一个数值还要把预测浓度转换成用户能理解的预警等级并给出是否需要减少户外活动的提示。真实雾霾天气下能见度、出行体验和健康风险都会明显变化。预测系统的价值就在于把空气质量数据、气象变化和历史污染趋势转成可解释的未来预警。本项目最终实现的是一个“从数据到预警”的完整流程加载真实监测数据按日期和站点聚合构造滞后与滚动统计特征训练多个回归模型保存最佳模型生成未来 7 天 PM2.5 预测并将结果转换为 AQI、预警等级和健康建议。系统架构如下图所示。数据层负责保存原始 zip、整理后的日级 CSV 和输出结果算法层完成特征工程、模型训练、预测与预警转换展示层负责输出图表、报告和 Streamlit 看板。2. 数据来源与字段整理本项目使用 UCI Beijing Multi-Site Air Quality Data。原始数据是北京多个监测站的小时级空气质量和气象记录项目内通过tools/prepare_uci_beijing_data.py聚合为日级站点数据输出到data/external/uci_beijing_daily_pm25.csv整理后的数据包含 12 个监测站、16,966 条日级记录日期范围为 2013-03-01 至 2017-02-28。核心字段如下字段含义date日期city北京监测站名称格式如 Beijing-Aotizhongxintemp_c日均气温humidity由温度和露点估算的相对湿度pressure_hpa日均气压wind_speed_mps日均风速wind_dir当日主导风向rainfall_mm日累计降雨量so2 / no2 / co / o3其他污染物浓度pm10PM10 浓度pm25PM2.5 浓度UCI 原始数据中没有交通强度和工业活动指数因此项目在预处理时加入了可复现的站点与工作日代理变量作为工程演示字段。它们不是外部真实业务指标正式研究中可以替换为城市交通指数、产业活动强度或排放源统计数据。3. 项目目录结构项目结构按“源码、数据、模型、结果、文档”分开便于复现和打包。city_pm25_forecast_warning_system/ ├── app.py ├── run_demo.py ├── requirements.txt ├── README.md ├── blog.md ├── configs/ │ └── config.yaml ├── data/ │ ├── city_pm25_sample.csv │ ├── external/ │ │ └── uci_beijing_daily_pm25.csv │ └── raw/ │ └── PRSA2017_Data_20130301-20170228.zip ├── tools/ │ ├── prepare_uci_beijing_data.py │ └── run_real_uci_demo.py ├── src/ │ ├── aqi.py │ ├── data_loader.py │ ├── feature_engineering.py │ ├── model_training.py │ ├── predictor.py │ ├── report.py │ └── visualization.py ├── models/ │ ├── best_pm25_model.joblib │ └── real_uci_best_pm25_model.joblib ├── images/ │ ├── figures/ │ └── results/ └── outputs/ ├── predictions/ └── reports/src/是核心代码目录tools/放真实数据整理与复现实验脚本data/external/保存整理后的真实数据outputs/保存预测结果和报告images/results/保存正式图表和页面截图。4. 特征工程与建模流程PM2.5 预测不能只看当天浓度。空气污染具有明显的持续性和季节性因此项目在src/feature_engineering.py中构造了日期周期、气象污染物、类别变量、滞后值和滚动统计特征。真实数据建模流程如下图所示。原始小时级监测数据先按天聚合并映射字段然后进行训练集和测试集切分后续进入特征工程、多模型训练、误差评估和未来 7 天预测。本项目的预测目标是下一日 PM2.5target_pm25_next_day groupby(city).shift(-1)这意味着模型使用第 t 天的气象、污染物和历史 PM2.5 特征预测第 t1 天的 PM2.5。滞后特征包括pm25_lag_1、pm25_lag_2、pm25_lag_3、pm25_lag_7滚动统计包括 3 日和 7 日窗口。所有滞后与滚动计算都按监测站分组避免不同站点之间串数据。项目使用三类模型做对比模型作用Ridge线性基线训练快便于判断非线性建模是否必要RandomForestRegressor稳健的树模型能处理非线性和特征交互GradientBoostingRegressor梯度提升树在中小规模表格数据上通常表现较强训练完成后程序按 MAE 从小到大排序并保存最佳模型。模型包中不仅包含 pipeline还包含训练时的特征列、数值特征、类别特征和评估指标便于后续预测时保持特征顺序一致。5. AQI 预警规则预测 PM2.5 浓度只是第一步预警系统还需要把浓度值转成可读的空气质量等级。本项目在src/aqi.py中实现 PM2.5 到 AQI 的转换并追加aqi、warning_level和health_advice三列。代码采用公开 AQI breakpoint 的线性插值方式AQI (AQI_high - AQI_low) / (C_high - C_low) * (C - C_low) AQI_low其中C是 PM2.5 浓度C_low和C_high是对应等级的浓度上下界。这样模型输出连续 PM2.5 后系统可以直接给出 Good、Moderate、Unhealthy for Sensitive Groups、Unhealthy 等等级。6. 运行方式安装依赖后可以先重新生成真实数据的日级 CSVpipinstall-rrequirements.txt python tools/prepare_uci_beijing_data.py然后运行真实数据训练与预测流程python tools/run_real_uci_demo.py如果只想快速检查基础流程也可以运行样例数据脚本python run_demo.pyWeb 看板运行命令如下streamlit run app.py项目内存在data/external/uci_beijing_daily_pm25.csv时Streamlit 默认使用 UCI 真实数据如果该文件不存在则退回内置样例数据保证代码仍能离线跑通。7. 真实数据运行结果本次验证已执行python tools/prepare_uci_beijing_data.py python tools/run_real_uci_demo.py数据整理脚本输出 16,966 条日级记录覆盖 12 个北京监测站。真实数据训练结果如下modelMAERMSER²预警等级准确率GradientBoosting35.50854.3780.4480.466RandomForest36.70055.7050.4210.480Ridge37.61555.9720.4160.439从 MAE 和 RMSE 看GradientBoosting 是当前配置下误差最低的模型因此被保存为最佳模型。模型对比图如下这里的预警等级准确率不是回归指标而是把真实 PM2.5 和预测 PM2.5 分别转换成 AQI 等级后比较两者是否落在同一预警等级。它能更贴近预警系统的业务目标。8. 测试集预测曲线仅看指标表不够还需要观察预测曲线是否能跟随真实 PM2.5 的变化。下图展示了 Beijing-Aotizhongxin 监测站测试集中的真实值和预测值。可以看到模型对多数日常波动具备跟随能力但对极端污染峰值仍会低估。这是空气质量预测中的常见问题如果没有未来气象预报、排放源变化、区域传输和突发污染事件信息仅靠历史日级数据很难完整捕捉尖峰。因此该系统更适合做趋势判断和预警辅助而不应替代官方空气质量预报。9. 未来 7 天 PM2.5 预测与预警项目会基于每个监测站的最新历史数据递归预测未来 7 天 PM2.5并输出 AQI 与健康建议。结果保存到outputs/predictions/real_uci_future_forecast.csv监测站预测摘要如下cityavg_pm25max_pm25high_daysBeijing-Aotizhongxin54.2769.027Beijing-Changping48.9662.757Beijing-Dingling50.0762.957Beijing-Dongsi50.9963.377Beijing-Guanyuan49.4065.287Beijing-Wanliu51.8969.277预警分布图如下。未来 7 天预测中主要出现Unhealthy for Sensitive Groups和Unhealthy两类预警说明系统不仅输出浓度也能给出风险分层。部分预测明细如下datecitysteppredicted_pm25AQIwarning_level2017-03-01Beijing-Aotizhongxin150.71138Unhealthy for Sensitive Groups2017-03-02Beijing-Aotizhongxin269.02160Unhealthy2017-03-03Beijing-Aotizhongxin365.86158Unhealthy2017-03-04Beijing-Aotizhongxin451.97142Unhealthy for Sensitive Groups2017-03-05Beijing-Aotizhongxin548.28132Unhealthy for Sensitive Groups2017-03-06Beijing-Aotizhongxin648.51133Unhealthy for Sensitive Groups2017-03-07Beijing-Aotizhongxin745.53126Unhealthy for Sensitive Groups这些日期从真实数据最后一天 2017-02-28 之后开始是模型基于历史序列向后递推得到的预测结果。10. 特征重要性分析对于机器学习项目不能只给出预测值还要说明模型主要依赖哪些信号。项目会从最佳模型中提取特征重要性并保存图表和 CSVimages/results/real_uci_feature_importance.png images/results/real_uci_feature_importance.csv本次真实数据结果中当前 PM2.5、前一日变化、风速、气压、NO2、降雨量和季节周期等特征排在前列。特征重要性不能直接解释因果关系但可以帮助检查模型是否依赖了合理信号。如果某个明显无关字段权重异常就需要回到数据清洗和特征构造阶段排查泄漏或异常值。11. Streamlit Web 看板效果项目提供app.py作为 Web 可视化入口。页面会展示数据概览、模型指标、模型对比、测试集预测曲线、未来预警表和特征重要性。下图是本次使用 UCI 真实数据启动 Streamlit 后截取的正式运行页面。页面中可以看到当前数据源、数据行数、监测站数量、起止日期、最佳模型和核心指标。用户也可以上传自定义 CSV只要字段满足docs/dataset_notes.md中的说明系统就会基于新数据重新训练和预测。12. 核心代码说明真实数据入口是tools/run_real_uci_demo.py它会覆盖配置中的数据路径和输出路径保证真实数据结果与样例数据结果分开保存config[data][sample_path]data/external/uci_beijing_daily_pm25.csvconfig[training][model_path]models/real_uci_best_pm25_model.joblibconfig[training][metrics_path]outputs/reports/real_uci_model_metrics.jsonconfig[forecast][forecast_path]outputs/predictions/real_uci_future_forecast.csv训练函数train_and_evaluate会完成监督数据构造、时间顺序切分、候选模型训练、指标计算和最佳模型保存。预测函数forecast_next_days则基于最近历史数据递推未来多天并调用append_warning_columns追加 AQI、预警等级和健康建议。13. 如何替换为自己的城市数据如果要替换为新的城市数据需要把字段整理成本项目标准格式。最关键的字段是date, city, temp_c, humidity, pressure_hpa, wind_speed_mps, wind_dir, rainfall_mm, so2, no2, co, o3, pm10, pm25如果没有traffic_index或industrial_index可以先用稳定的代理变量也可以从特征工程配置中删除对应字段。小时级数据可以先按天聚合例如计算日均 PM2.5、日均温度、日均风速和累计降雨量再进入当前日级预测流程。替换数据后建议重新运行python tools/run_real_uci_demo.py如果使用的是新的文件名可以修改configs/config.yaml或复制tools/run_real_uci_demo.py中的路径配置。14. 可扩展方向第一可以增加模型类型。对于表格数据LightGBM、XGBoost 和 CatBoost 往往表现较强对于严格时序建模可以加入 LSTM、TCN 或 Transformer 类模型。第二可以增加时间序列交叉验证。当前代码按时间顺序划分训练集和测试集避免未来信息泄漏正式实验中可以进一步使用 walk-forward validation。第三可以接入未来气象预报。当前未来 7 天预测使用递推方式估计外生变量如果接入天气预报 API短期预测的业务意义会更强。第四可以加入地图可视化。多站点数据可以结合经纬度用 Folium、PyDeck 或 ECharts 展示空间分布。第五可以扩展为后台服务。将预测结果写入数据库再用 Flask 或 FastAPI 提供接口就可以形成空气质量预警后台。15. 常见问题为什么不用 LSTMLSTM 对时序数据有优势但对环境、数据量和训练调参要求更高。这个项目定位是可运行、易部署、适合课程设计和工程展示因此先使用传统机器学习模型。预警等级准确率为什么不高PM2.5 极端峰值往往与未来气象、区域传输、突发排放和节假日活动有关。当前模型只使用历史日级数据和已有气象污染物字段因此能做趋势辅助但不能完全预测极端污染过程。UCI 数据能直接用于当前城市决策吗不能。本文使用的是历史公开数据适合学习、实验和原型验证。实际部署需要接入当地最新监测数据、气象预报和业务规则。为什么还保留样例数据样例数据用于兜底运行避免没有真实 CSV 时项目无法启动。正式博客和截图使用的是包内 UCI 真实数据。16. 总结本文完成了一个基于 UCI 真实空气质量数据的城市 PM2.5 预测与预警系统。项目从真实数据整理、特征工程、模型训练、指标评估、未来预测、AQI 预警到 Streamlit 可视化都给出了完整实现。本次真实数据运行中系统处理了 16,966 条北京多监测站日级记录最佳模型为 GradientBoosting测试集 MAE 为 35.508 μg/m³RMSE 为 54.378 μg/m³R² 为 0.448并输出了未来 7 天预警表、特征重要性图、模型对比图和正式 Web 页面截图。相比只展示零散代码的教程这个版本更适合用于 CSDN 技术博客、课程设计、机器学习实验报告和二次开发。参考资料UCI Beijing PM2.5 Data: https://archive.ics.uci.edu/dataset/381/beijingpm25dataUCI PM2.5 Data of Five Chinese Cities: https://archive.ics.uci.edu/dataset/394/pm25dataoffivechinesecitiesUCI Beijing Multi-Site Air Quality Data: https://archive.ics.uci.edu/dataset/501/beijingmultisiteairqualitydataEPA AQI Breakpoints: https://aqs.epa.gov/aqsweb/documents/codetables/aqi_breakpoints.htmlscikit-learn RandomForestRegressor: https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.htmlscikit-learn GradientBoostingRegressor: https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.htmlStreamlit Documentation: https://docs.streamlit.io/Wikimedia Commons 北京雾霾场景图https://commons.wikimedia.org/wiki/File:Beijing_Forbidden_City_Smog.jpg