☰
基于机器学习的城市空气质量分析与预测
2026/9/30 11:17:51 网站建设 项目流程

一.背景

空气质量是人类健康和生活质量的关键保障,对其进行科学有效的监测和分析至关重要。随着全球化和城市化进程的加速,空气污染已成为一个全球性、严峻的环境问题。尤其是在发展中国家,空气污染问题日益加剧,不仅严重威胁公众健康,还对生态环境和经济发展造成了不可忽视的负面影响。作为全球发展速度最快的国家之一,印度在工业化和城市化过程中面临着巨大的空气质量挑战。空气污染的治理已成为印度及全球范围内的重要议题。

空气污染物的主要来源包括工业排放、机动车尾气、燃煤取暖以及建筑扬尘等。其中,PM2.5 和 PM10 等颗粒物是影响空气质量指数(AQI)的关键指标,长期暴露于高浓度颗粒物环境中会增加呼吸系统疾病和心血管疾病的患病风险。因此,对空气质量数据进行系统性的统计分析,有助于识别污染规律、评估治理效果,并为制定针对性的环保政策提供数据支撑。

二.数据探索

1.单变量统计分析与离散型变量分布分析

df_city_day = pd.read_csv(r"D:\数据分析\city_day.csv") df_city_day.describe().T df_desc = df_city_day.describe().T 自定义高亮函数 def highlight_min_max(s): styles = [] for index in s.index: if index == 'min': styles.append('background-color: lightcoral') # 标红色,较浅 elif index == 'max': styles.append('background-color: lightblue') # 标蓝色,较浅 else: styles.append('') return styles 使用样式格式化DataFrame styled_df = df_desc.style.apply(highlight_min_max, axis=1) 展示样式化的DataFrame styled_df #离散变量分布 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns 读取数据 df_city_day = pd.read_csv(r"D:\数据分析\city_day.csv") 设置调色板和绘图大小 plt.figure(figsize=(20, 10)) sns.set_palette('Set1') 绘制 city 与 AQI_Bucket 的堆叠柱状图 counts = df_city_day.groupby(['City', 'AQI_Bucket']).size().unstack() counts.plot(kind='bar', stacked=True, figsize=(15, 10)) plt.xlabel('City') plt.ylabel('计数') plt.title('City 与 AQI_Bucket 的分布图') plt.xticks(rotation=45, ha='right', fontsize=12) plt.yticks(fontsize=12) plt.tight_layout(pad=2) plt.show() 数据质量检查 unique_values = df_city_day['City'].unique() print(f'变量 City 的唯一值: {unique_values}') 通过离散变量分布图查看数据质量并判断是否存在异常值(可以人工判断) 如果发现异常值,可以使用 df_city_day = df_city_day[df_city_day['City'] != '异常值'] 删除异常值

运行结果如图所示

2.相关性分析

import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import numpy as np # 读取数据 df_city_day = pd.read_csv(r"D:\数据分析\city_day.csv") # 选择数值型列进行相关性分析 numeric_cols = df_city_day.select_dtypes(include=[np.number]) # 计算Spearman等级相关系数 spearman_corr = numeric_cols.corr(method='spearman') # 使用画布绘制相关性热力图 fig, ax = plt.subplots(figsize=(12, 8)) sns.heatmap(spearman_corr, annot=True, cmap='Blues', ax=ax) plt.title('变量间的Spearman相关性热力图') plt.show()

使用Spearman等级相关系数进行相关性分析

三.数据预处理

在完成数据探索之后,需要对原始数据进行预处理,以确保后续建模和分析的准确性与可靠性。数据预处理主要包括缺失值处理、异常值检测与处理、数据标准化以及特征工程等步骤。

首先,检查数据集中是否存在缺失值。对于数值型变量,可以采用均值、中位数或众数进行填充;对于类别型变量,则可以使用众数填充或删除含有缺失值的记录。其次,通过箱线图或 Z-score 方法识别异常值,并结合业务背景判断是否删除或修正这些异常值。最后,对数值型特征进行标准化或归一化处理,以消除量纲差异对模型训练的影响。

# 导入需要的库 import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler import matplotlib.pyplot as plt import seaborn as sns # 读取数据 df_city_day = pd.read_csv(r"D:\数据分析\city_day.csv") # 2. 数据探索与预处理 def show_null_value(df): null_val = df.isnull().sum() null_val_percent = 100 * df.isna().sum() / len(df) null_val_table = pd.concat([null_val, null_val_percent], axis=1) null_val_table_columns = null_val_table.rename(columns={0: '>Missing Values', 1: '> Total Null Values %'}) return null_val_table_columns # 统计各列的缺失值数量和百分比 print(show_null_value(df_city_day)) # 将日期列转换为日期格式 df_city_day['Date'] = pd.to_datetime(df_city_day['Date'], format='%Y-%m-%d') df_city_day = df_city_day.sort_values(by='Date') # 处理异常值 def replace_outliers_with_quartiles(df): for column in df.select_dtypes(include=['number']).columns: Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR # 将异常值替换为 NaN df[column] = df[column].apply(lambda x: np.nan if x < lower_bound or x > upper_bound else x) # 计算该列的均值,并用该均值填充 NaN mean_value = df[column].mean() df[column] = df[column].fillna(mean_value) return df # 处理异常值 df_city_day_before = df_city_day.copy() df_city_day = replace_outliers_with_quartiles(df_city_day) # 可视化处理前后的数据对比 plt.figure(figsize=(15, 5)) sns.boxplot(data=df_city_day_before[['AQI', 'PM2.5', 'PM10', 'NO', 'NO2', 'NOx', 'NH3', 'O3', 'CO', 'SO2', 'Benzene', 'Toluene', 'Xylene']], width=0.6) plt.title('可视化处理前') plt.show() plt.figure(figsize=(15, 5)) sns.boxplot(data=df_city_day[['AQI', 'PM2.5', 'PM10', 'NO', 'NO2', 'NOx', 'NH3', 'O3', 'CO', 'SO2', 'Benzene', 'Toluene', 'Xylene']], width=0.6) plt.title('可视化处理后') plt.show() numerical_features = ['PM2.5', 'PM10', 'NO', 'NO2', 'NOx', 'NH3', 'CO', 'SO2', 'O3', 'AQI'] scaler = MinMaxScaler() df_city_day[numerical_features] = scaler.fit_transform(df_city_day[numerical_features]) # 查看处理后的数据 print("处理后的数据:") df_city_day.head(10)

处理后展示

分类,建立映射关系

# 导入需要的库 import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler import matplotlib.pyplot as plt import seaborn as sns # 读取数据 df_city_day = pd.read_csv(r"D:\数据分析\city_day.csv") # 2. 数据探索与预处理 def show_null_value(df): null_val = df.isnull().sum() null_val_percent = 100 * df.isna().sum() / len(df) null_val_table = pd.concat([null_val, null_val_percent], axis=1) null_val_table_columns = null_val_table.rename(columns={0: '>Missing Values', 1: '> Total Null Values %'}) return null_val_table_columns # 统计各列的缺失值数量和百分比 print(show_null_value(df_city_day)) # 将日期列转换为日期格式 df_city_day['Date'] = pd.to_datetime(df_city_day['Date'], format='%Y-%m-%d') df_city_day = df_city_day.sort_values(by='Date') # 处理异常值 def replace_outliers_with_quartiles(df): for column in df.select_dtypes(include=['number']).columns: Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR # 将异常值替换为 NaN df[column] = df[column].apply(lambda x: np.nan if x < lower_bound or x > upper_bound else x) # 计算该列的均值,并用该均值填充 NaN mean_value = df[column].mean() df[column] = df[column].fillna(mean_value) return df # 处理异常值 df_city_day_before = df_city_day.copy() df_city_day = replace_outliers_with_quartiles(df_city_day) # 创建年份和月份列 df_city_day['Year'] = df_city_day['Date'].dt.year df_city_day['Month'] = df_city_day['Date'].dt.to_period('M') df_city_day = df_city_day.drop(columns=['Xylene', 'Benzene', 'Toluene']) # 去除 AQI_Bucket 中的 NaN 行 df_city_day = df_city_day.dropna(subset=['AQI_Bucket']) numerical_features = ['PM2.5', 'PM10', 'NO', 'NO2', 'NOx', 'NH3', 'CO', 'SO2', 'O3', 'AQI'] scaler = MinMaxScaler() df_city_day[numerical_features] = scaler.fit_transform(df_city_day[numerical_features]) # 将 AQI_Bucket 转换为数值类型(从好到差的顺序),并输出对应属性值 bucket_order = ['Good', 'Satisfactory', 'Moderate', 'Poor', 'Very Poor', 'Severe'] df_city_day['AQI_Bucket'] = pd.Categorical(df_city_day['AQI_Bucket'], categories=bucket_order, ordered=True) df_city_day['AQI_Bucket_Numeric'] = df_city_day['AQI_Bucket'].cat.codes

四.模型构建与评估

在数据预处理完成后,进入模型构建阶段。本文采用多种机器学习算法对空气质量等级进行预测,包括逻辑回归、随机森林、梯度提升树(GBDT)以及 XGBoost 等。通过交叉验证方法划分训练集与测试集,并使用准确率、精确率、召回率、F1 分数以及 ROC-AUC 等指标对模型性能进行评估。

# 导入需要的库 import pandas as pd from sklearn.model_selection import train_test_split, cross_val_predict, KFold from sklearn.tree import DecisionTreeClassifier from sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC from xgboost import XGBClassifier from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, roc_auc_score, roc_curve import seaborn as sns import matplotlib.pyplot as plt # 假设 df_city_day_filtered 是经过预处理后的数据框 # 使用 PM2.5, PM10, NO, NO2, NOx, NH3, CO, SO2, Toluene 来预测 AQI_Bucket_Numeric # 定义特征和目标值 features = ['PM2.5', 'PM10', 'NO', 'NO2', 'NOx', 'NH3', 'CO', 'SO2', 'O3'] X = df_city_day_filtered[features] y = df_city_day_filtered['AQI_Bucket_Numeric'] # 拆分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 初始化单个分类器 model1 = DecisionTreeClassifier(random_state=42) model2 = GaussianNB() model3 = RandomForestClassifier(n_estimators=100, random_state=42) model_xgb = XGBClassifier(random_state=42, use_label_encoder=False, eval_metric='mlogloss') model_svm = SVC(kernel='rbf', probability=True, random_state=42) # 创建一个字典来存储所有模型 models = { 'Decision Tree': model1, 'Naive Bayes': model2, 'Random Forest': model3, 'XGBoost': model_xgb, 'SVM': model_svm } # 存储模型评估结果 accuracy_results = {} roc_auc_results = {} confusion_matrices = {} # 使用五折交叉验证对每个模型进行训练和评估 kf = KFold(n_splits=5, shuffle=True, random_state=42) for model_name, model in models.items(): print(f"\n模型: {model_name}") # 进行五折交叉验证预测 y_pred = cross_val_predict(model, X_train, y_train, cv=kf, method='predict') y_pred_proba = cross_val_predict(model, X_train, y_train, cv=kf, method='predict_proba') if hasattr(model, 'predict_proba') else None # 计算准确率并输出 accuracy = accuracy_score(y_train, y_pred) accuracy_results[model_name] = accuracy print(f"分类准确率: {accuracy}") # 输出分类报告 print("分类报告:") print(classification_report(y_train, y_pred)) # 输出混淆矩阵 cm = confusion_matrix(y_train, y_pred) confusion_matrices[model_name] = cm print("混淆矩阵:") print(cm) # ROC-AUC 评估 if y_pred_proba is not None: roc_auc = roc_auc_score(y_train, y_pred_proba, multi_class='ovr') roc_auc_results[model_name] = roc_auc print(f"ROC-AUC: {roc_auc}") # 可视化混淆矩阵,将所有混淆矩阵画在同一张画布上 fig, axes = plt.subplots(3, 2, figsize=(15, 15)) axes = axes.ravel() for idx, (model_name, cm) in enumerate(confusion_matrices.items()): sns.heatmap(cm, annot=True, cmap='viridis', fmt='g', ax=axes[idx]) axes[idx].set_title(f'{model_name} 的混淆矩阵') axes[idx].set_xlabel('预测值') axes[idx].set_ylabel('真实值') plt.tight_layout() plt.show() # 比较不同模型的准确率 plt.figure(figsize=(10, 6)) model_names = list(accuracy_results.keys()) accuracies = list(accuracy_results.values()) sns.barplot(x=model_names, y=accuracies, palette='viridis') plt.xlabel('模型') plt.ylabel('准确率') plt.title('不同模型的准确率比较') plt.ylim(0, 1) plt.show() # 比较不同模型的 ROC-AUC if roc_auc_results: plt.figure(figsize=(10, 6)) model_names = list(roc_auc_results.keys()) roc_aucs = list(roc_auc_results.values()) sns.barplot(x=model_names, y=roc_aucs, palette='viridis') plt.xlabel('模型') plt.ylabel('ROC-AUC') plt.title('不同模型的 ROC-AUC 比较') plt.ylim(0, 1) plt.show()

实验结果表明,集成学习算法(如随机森林和 XGBoost)在空气质量等级预测任务中表现优于单一模型,能够更有效地捕捉特征之间的复杂非线性关系。其中,XGBoost 模型在测试集上取得了最高的准确率,说明其在处理高维、非线性数据时具有较强的泛化能力。

五.结果分析与讨论

为了更直观地展示各特征对空气质量等级预测的贡献程度,本文基于 XGBoost 模型的特征重要性属性绘制了条形图,结果如下图所示。

import pandas as pd import matplotlib.pyplot as plt import xgboost as xgb 假设 model 为已训练好的 XGBoost 模型,X_train 为训练集特征 feature_names = X_train.columns importance = model.feature_importances_ 按重要性降序排序 sorted_idx = importance.argsort()[::-1] sorted_names = [feature_names[i] for i in sorted_idx] sorted_importance = importance[sorted_idx] 绘制特征重要性条形图 plt.figure(figsize=(10, 6)) plt.barh(sorted_names, sorted_importance, color='steelblue') plt.xlabel('特征重要性') plt.ylabel('特征名称') plt.title('XGBoost 特征重要性排序') plt.gca().invert_yaxis() plt.tight_layout() plt.show()

从图中可以看出,PM2.5 和 PM10 的特征重要性得分显著高于其他特征,说明颗粒物浓度是决定空气质量等级的最关键指标。紧随其后的是 NO2 和 SO2,它们对模型预测结果也具有较为明显的影响。相比之下,CO 和 O3 的重要性相对较低,但仍对整体预测有一定贡献。这一排序结果与空气质量领域的已有研究结论基本一致,进一步验证了模型特征选择的合理性。

通过对模型预测结果的分析,可以发现影响空气质量等级的关键特征主要包括 PM2.5、PM10、NO2、SO2、CO 以及 O3 等污染物浓度。此外,气象因素如温度、湿度和风速也对空气质量产生显著影响。进一步的特征重要性分析表明,PM2.5 和 PM10 是决定空气质量等级的最重要指标。

本文的研究结果对于空气污染治理具有重要的参考价值。通过准确预测空气质量等级,政府和环保部门可以提前采取预警措施,减少空气污染对公众健康的影响。同时,本文的方法也可以推广到其他城市和地区,为全球空气质量管理提供技术支持。

六.结论与展望

本文基于印度城市空气质量数据,系统地完成了数据探索、预处理、模型构建与评估的全流程分析。实验结果表明,集成学习算法在空气质量等级预测中具有较好的表现,能够为空气污染治理提供有效的决策支持。

未来的工作可以从以下几个方面展开:一是引入更多维度的数据,如气象预报数据和卫星遥感数据,进一步提升模型的预测精度;二是探索深度学习模型(如 LSTM、Transformer)在时间序列空气质量预测中的应用;三是将研究成果应用于实际环境监测系统,实现空气质量的实时预警与动态管理。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询