资讯详情

数据挖掘实战:基于随机森林算法的空气质量污染预测模型

📅 2026/10/28 22:02:28 | 华诺云谱 👁 阅读
数据挖掘实战:基于随机森林算法的空气质量污染预测模型
简介这份资源面向数据挖掘初学者与希望掌握回归建模实战的开发者围绕空气质量污染预测这一典型场景提供从数据到模型落地的完整方案。包内共3个文件包含一份可交互运行的Jupyter Notebook、一份经过整理的污染数据集CSV以及一份便于直接浏览结果的HTML报告压缩包整体约616KB体量轻巧却覆盖了建模全流程。读者可借助Notebook逐步理解随机森林算法在污染预测中的特征工程、参数调优与效果评估思路并通过CSV数据复现实验、替换自有数据做迁移练习HTML报告则方便快速查看关键结论与可视化图表。目前已有129人学习下载适合作为课程设计、竞赛练手或自学数据挖掘的参考案例帮助读者在真实数据上建立对集成学习方法的直观认知。1. 空气质量预测这件事为什么我最后选了随机森林而不是 LSTM去年冬天帮一个做环保监测的朋友看数据他手里攒了三年多的城市空气质量小时级记录想提前一天预测 PM2.5 和 AQI 的走势。他一开始执念于上 LSTM觉得时序问题就该用深度学习结果折腾了两周MAE 卡在 18 上下下不去训练还动不动就过拟合。我让他换成随机森林回归试一版特征工程做完当天下午就跑到 MAE 11 左右而且特征重要性一拉出来哪些污染物、哪些气象因子在起作用一目了然。这就是这份「数据挖掘实战-基于随机森林算法的空气质量污染预测模型」资源的价值所在它不是一个炫技的深度模型而是一套能跑通、能解释、能复现的完整流程。压缩包里给了分析.ipynb、updated_pollution_dataset.csv和导出的分析.html覆盖了从数据读取、清洗、特征构造、模型训练到结果可视化的全链路。适合两类人一类是刚接触数据挖掘、想找一个真实数据集把随机森林回归从头到尾走一遍的新手另一类是做环境、气象、能源方向的数据从业者需要一个可解释性强的基线模型而不是一个调不动的黑匣子。下面我按自己拆包复现的顺序把这份资源讲透。2. 拆开压缩包先看数据字段、缺失与分布怎么摸拿到任何一份数据挖掘资源我习惯先不碰模型先把数据摸清楚。这份资源的updated_pollution_dataset.csv是核心分析.ipynb是操作手册分析.html是跑完之后的快照方便你没装环境时先看结果长什么样。2.1 数据集字段与目标变量的确认先加载数据看形状、字段类型和缺失情况。这一步决定了后面特征工程怎么做。import pandas as pd import numpy as np # 读取数据集注意编码中文环境常见 utf-8 或 gbk df pd.read_csv(updated_pollution_dataset.csv, encodingutf-8) # 基础体检形状、字段、类型 print(数据形状:, df.shape) print(字段列表:, df.columns.tolist()) print(df.dtypes) # 缺失值统计按缺失比例排序 missing df.isnull().sum().sort_values(ascendingFalse) print(缺失值情况:\n, missing[missing 0]) # 目标变量分布先看偏度和分位数 target PM2.5 # 具体列名以实际数据为准 print(df[target].describe()) print(偏度:, df[target].skew())逻辑说明shape告诉你样本量和特征维度决定后面要不要做降维dtypes里如果时间字段是 object必须先转 datetime否则时序特征全废缺失值排序能让你一眼看出哪些列是「重灾区」缺失超过 40% 的列我一般直接考虑丢弃而不是硬填。目标变量的偏度很关键——如果 PM2.5 严重右偏直接回归会被极端高值带偏常见做法是对目标做对数变换再训练。参数说明encoding要按实际文件试读进来报UnicodeDecodeError就换gbk或utf-8-sig。target这个变量名一定要先确认不同数据集里可能叫PM2.5、pm25、AQI写错了后面全错。2.2 时间字段处理与特征构造思路空气质量数据几乎都带时间戳这是随机森林能吃到的最有价值的特征来源之一。原始时间戳对树模型没用必须拆成可比较的数值。# 时间字段转 datetime 并拆解周期特征 df[datetime] pd.to_datetime(df[datetime]) df[hour] df[datetime].dt.hour df[month] df[datetime].dt.month df[dayofweek] df[datetime].dt.dayofweek df[is_weekend] df[dayofweek].isin([5, 6]).astype(int) # 周期性编码小时和月份用正余弦避免 23 点和 0 点被当成距离最远 df[hour_sin] np.sin(2 * np.pi * df[hour] / 24) df[hour_cos] np.cos(2 * np.pi * df[hour] / 24) df[month_sin] np.sin(2 * np.pi * df[month] / 12) df[month_cos] np.cos(2 * np.pi * df[month] / 12) # 滞后特征用前一时刻的污染物浓度预测当前时序场景必做 for col in [PM2.5, PM10, SO2, NO2, CO, O3]: if col in df.columns: df[f{col}_lag1] df[col].shift(1) df[f{col}_lag24] df[col].shift(24) # 滞后会产生首行 NaN直接删掉 df df.dropna().reset_index(dropTrue)逻辑说明hour、month这类离散周期特征如果直接当数值喂给树模型会出现「23 点和 0 点差 23」的荒谬距离正余弦编码是标准解法。滞后特征是空气质量预测的命门——当前时刻的污染浓度和前一小时、前 24 小时高度相关lag1抓短期惯性lag24抓日周期。这一步做完模型效果通常能提升一大截。参数说明shift(1)是滞后一步shift(24)是滞后 24 步具体滞后阶数要看你的采样频率。如果是小时数据24 就是一天如果是日数据shift(7)更合理。滞后阶数不是越多越好阶数太多会引入大量缺失行样本量不够时反而伤模型。提示滞后特征构造后一定要检查样本量还剩多少。如果原始数据只有几千行加了两阶滞后再 dropna可能直接少掉几百行训练集就不够分了。3. 随机森林回归建模参数怎么设、特征重要性怎么看数据摸清楚之后进入建模。这份资源用的是随机森林回归我把它拆成「为什么选它」「怎么训」「怎么读结果」三段来讲每一段都对应分析.ipynb里的实际操作。3.1 为什么空气质量预测适合随机森林先说选型理由这决定了你后面调参的方向。随机森林回归相比线性回归和深度学习在这个场景有三个实打实的优势。第一它能自动处理非线性关系和特征交互。污染物浓度和气象因子温度、湿度、风速之间的关系高度非线性比如风速对 PM2.5 的稀释作用在低风速区间和高风速区间完全不同线性模型必须手动构造交互项随机森林靠树分裂天然捕捉。第二它对特征尺度不敏感。PM2.5 动辄上百CO 可能只有个位数量纲差异巨大。线性模型和神经网络必须做标准化随机森林不用省掉一步且不容易出错。第三也是我最看重的——特征重要性可解释。环保场景里你不仅要预测准还要说清楚「到底是哪个因子在推高污染」。随机森林的feature_importances_能直接给出排序这对写报告、做决策比一个高深模型有用得多。当然它也有边界随机森林不能外推。如果训练集里 PM2.5 最高只到 300你让它预测 500 的极端污染事件它大概率给你一个接近 300 的值。这是树模型的通病遇到极端值场景要心里有数。3.2 训练流程与关键参数设置下面是完整的训练代码包含数据集划分、模型初始化和训练。from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score # 特征与目标分离注意把时间列和原始目标列排除 drop_cols [datetime, PM2.5] feature_cols [c for c in df.columns if c not in drop_cols] X df[feature_cols] y df[PM2.5] # 时序数据不能随机打乱按时间顺序切分更合理 split_idx int(len(df) * 0.8) X_train, X_test X.iloc[:split_idx], X.iloc[split_idx:] y_train, y_test y.iloc[:split_idx], y.iloc[split_idx:] # 随机森林回归先给一组稳健的初始参数 rf RandomForestRegressor( n_estimators300, # 树的数量越多越稳但越慢 max_depth15, # 限制深度防止过拟合 min_samples_split5, # 节点分裂最小样本数 min_samples_leaf2, # 叶节点最小样本数 max_featuressqrt, # 每次分裂考虑的特征数 random_state42, n_jobs-1 # 用满所有 CPU 核心 ) rf.fit(X_train, y_train) # 预测与评估 y_pred rf.predict(X_test) print(MAE:, mean_absolute_error(y_test, y_pred)) print(RMSE:, np.sqrt(mean_squared_error(y_test, y_pred))) print(R2:, r2_score(y_test, y_pred))逻辑说明时序数据我用的是按时间顺序切分而不是train_test_split随机切因为随机切会让未来数据泄漏到训练集评估结果虚高上线就翻车。n_estimators300是经验起点树太少方差大树太多收益递减还费时间。max_depth15和min_samples_leaf2是控制过拟合的两个闸门深度不限制的话单棵树能长到记住每个样本集成起来照样过拟合。参数说明max_featuressqrt是回归任务的常用值分类任务默认也是 sqrt但回归有时用0.3或0.5效果更好可以网格搜一下。n_jobs-1在服务器上能显著加速本地小数据无所谓。random_state固定住保证你每次跑结果一致方便对比调参效果。3.3 特征重要性解读与结果验证训练完别急着收工把特征重要性拉出来看这是随机森林最有价值的输出。# 特征重要性排序 importances pd.Series(rf.feature_importances_, indexfeature_cols) importances importances.sort_values(ascendingFalse) print(importances.head(15)) # 可视化 import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 中文显示 plt.rcParams[axes.unicode_minus] False importances.head(15).plot(kindbarh, figsize(8, 6)) plt.xlabel(重要性) plt.title(随机森林特征重要性 Top15) plt.gca().invert_yaxis() plt.tight_layout() plt.savefig(feature_importance.png, dpi150)逻辑说明feature_importances_基于不纯度减少计算数值越大说明该特征在树分裂中贡献越多。我一般重点看两件事一是滞后特征是不是排在前列如果是说明时序惯性被正确捕捉二是气象因子温度、湿度、风速有没有进前十五如果全是污染物自回归特征霸榜说明气象信息没被有效利用可能要检查气象字段的清洗是否出了问题。参数说明head(15)只取前十五全画出来太挤。dpi150保证导出图片清晰写报告够用。中文字体设置是必须的否则标题全是方框这是新手最常见的翻车点之一。注意特征重要性高不等于因果。风速重要性高说明它和污染浓度统计相关不代表「加大风速就能降污染」这种因果结论写分析报告时措辞要谨慎。4. 避坑与排查这份资源复现时最容易翻车的五个地方这一章是我自己复现和帮别人调这份代码时踩过的坑按「现象 → 原因 → 解决」写你对照着排查能省不少时间。4.1 中文列名或中文路径导致读取失败现象pd.read_csv报UnicodeDecodeError或者 matplotlib 画图标题全是方框。原因CSV 文件编码可能是 gbk而 pandas 默认 utf-8matplotlib 默认字体不含中文。解决读取时显式指定encodinggbk或encodingutf-8-sig逐个试画图前设置plt.rcParams[font.sans-serif] [SimHei]和plt.rcParams[axes.unicode_minus] False。文件路径也尽量用英文中文路径在某些环境下会出玄学问题。4.2 时间字段没排序就做滞后特征现象滞后特征构造完模型效果异常好或者异常差R2 忽高忽低。原因原始 CSV 的行顺序不一定是按时间排的直接shift会把错位的数据当成「前一时刻」。解决构造滞后特征前先df df.sort_values(datetime).reset_index(dropTrue)确保时间单调递增。这一步不做后面全是错的属于血泪经验。4.3 随机切分导致数据泄漏现象测试集 R2 高达 0.98上线后实际预测一塌糊涂。原因用了train_test_split随机切分未来时刻的样本混进了训练集模型「偷看」了答案。解决时序预测必须按时间顺序切分前 80% 训练、后 20% 测试。如果数据量够还可以做滚动窗口验证更贴近真实上线场景。4.4 树太多导致训练慢到怀疑人生现象n_estimators设成 1000训练跑了十几分钟还没完。原因树的数量和训练时间近似线性增长数据量大时尤其明显。解决先用 100 到 300 棵树快速验证流程和特征工程是否合理确认方向对了再往上加。同时开n_jobs-1用满多核。如果还是慢考虑降max_depth或减少特征数。4.5 目标变量含极端值拉偏评估现象MAE 看着还行但一到重污染天气预测就离谱。原因PM2.5 分布右偏少数极端高值主导了损失函数模型偏向拟合这些点普通样本反而欠拟合。解决对目标做np.log1p变换再训练预测时用np.expm1还原。或者改用 Huber 损失这类对异常值不敏感的评估方式。这一步做完普通天气的预测精度通常明显改善。5. 把模型用起来交叉验证、调参与结果落地的具体技巧模型能跑通只是第一步真正要用起来还得解决「参数怎么定」和「结果怎么交付」两个问题。这一章讲我实际会用的进阶操作。先说调参。随机森林的参数不算多但盲目网格搜很费时间。我一般用RandomizedSearchCV做粗搜再用小范围GridSearchCV精调。下面这段可以直接抄。from sklearn.model_selection import RandomizedSearchCV, TimeSeriesSplit # 时序交叉验证不能用默认的 KFold tscv TimeSeriesSplit(n_splits5) param_dist { n_estimators: [100, 200, 300, 500], max_depth: [8, 12, 15, 20, None], min_samples_split: [2, 5, 10], min_samples_leaf: [1, 2, 4], max_features: [sqrt, 0.3, 0.5] } search RandomizedSearchCV( RandomForestRegressor(random_state42, n_jobs-1), param_distributionsparam_dist, n_iter30, # 随机采样 30 组 cvtscv, # 时序交叉验证 scoringneg_mean_absolute_error, random_state42, n_jobs-1 ) search.fit(X_train, y_train) print(最优参数:, search.best_params_) print(最优 MAE:, -search.best_score_)逻辑说明TimeSeriesSplit是时序场景的正确交叉验证方式它保证每折的训练集都在验证集之前不会泄漏未来信息。n_iter30是随机搜的采样次数比网格搜省时间先粗定位再精调。scoring用负 MAE因为 sklearn 的评分是越大越好MAE 越小越好所以取负。参数说明max_depth里放了个None代表不限制深度让搜索自己决定要不要放开。max_features同时试了sqrt和浮点数回归任务里浮点数有时比 sqrt 效果好。n_iter根据你的算力调30 到 50 是常见范围。再说结果落地。训练完的模型要能交付我一般做三件事一是把特征重要性和预测对比图导出成图片写报告直接用二是把模型用joblib存下来方便后续加载预测新数据三是留一份预测结果 CSV包含时间、真实值、预测值和残差方便业务方核对。import joblib # 保存模型 joblib.dump(search.best_estimator_, rf_pollution_model.pkl) # 导出预测结果 result pd.DataFrame({ datetime: df[datetime].iloc[split_idx:].values, actual: y_test.values, predicted: y_pred, residual: y_test.values - y_pred }) result.to_csv(prediction_result.csv, indexFalse, encodingutf-8-sig)逻辑说明joblib比 pickle 更适合存 sklearn 模型尤其是带大量树的随机森林序列化和反序列化更快。encodingutf-8-sig保证 Excel 打开 CSV 不乱码这是交付给非技术同事时的细节。残差列一定要留业务方最关心的就是「你哪里预测得不准」残差能直接回答这个问题。最后说一个验证技巧把模型在时间上做滚动预测比如用前 30 天预测第 31 天然后窗口往后滑一天重复几十次看 MAE 的波动范围。如果波动很大说明模型对时间段敏感可能某些季节的特征分布差异大需要考虑分季节建模或者加入更多气象特征。这个验证比单次切分靠谱得多也是我从那次 LSTM 翻车之后养成的习惯——任何时序模型不跑滚动验证我都不敢说它稳。从那以后我每次交付预测模型都强制走一遍滚动验证加残差分析再附上特征重要性说明业务方看得懂自己也踏实。希望这份拆解帮到你压缩包里的分析.ipynb和分析.html对照着看跑通一遍就有感觉了。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑