基于LSTM和GRU的上海空气质量预测研究
基于LSTM和GRU的上海空气质量预测研究
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家,觉得好请收藏。点击跳转到网站。
1. 引言
空气质量预测是环境科学和公共健康领域的重要课题。随着工业化和城市化进程加快,空气污染问题日益严重,准确预测污染物浓度对于制定有效的环境保护政策和公众健康防护措施具有重要意义。深度学习技术,特别是长短期记忆网络(LSTM)和门控循环单元(GRU),因其出色的时序数据处理能力,在时间序列预测领域展现出巨大潜力。
本研究将使用2014年1月至2020年11月的上海天气数据和污染物指数,构建LSTM和GRU模型,预测2020年12月和2021年1月(共60天)的污染物数据。通过对比两种模型的预测性能,探讨深度学习在空气质量预测中的应用效果。
2. 数据准备与预处理
2.1 数据收集与描述
我们使用的数据集包含2014年1月至2020年11月的上海天气数据和污染物指数。数据主要包括以下特征:
- 气象数据:温度、湿度、风速、气压等
- 污染物数据:PM2.5、PM10、SO₂、NO₂、CO、O₃等
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, GRU, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping
import tensorflow as tf# 加载数据
data = pd.read_csv('shanghai_air_quality.csv', parse_dates=['date'], index_col='date')
print(data.head())
print(data.info())
2.2 数据探索与可视化
# 绘制污染物随时间变化趋势
pollutants = ['PM2.5', 'PM10', 'SO2', 'NO2', 'CO', 'O3']
data[pollutants].plot(subplots=True, figsize=(15, 12))
plt.suptitle('Shanghai Air Pollutants Trends (2014-2020)')
plt.tight_layout()
plt.show()# 绘制气象数据随时间变化趋势
weather = ['temperature', 'humidity', 'wind_speed', 'pressure']
data[weather].plot(subplots=True, figsize=(15, 8))
plt.suptitle('Shanghai Weather Data Trends (2014-2020)')
plt.tight_layout()
plt.show()
2.3 数据预处理
# 处理缺失值
data.fillna(method='ffill', inplace=True)# 特征工程
# 添加季节特征
data['month'] = data.index.month
data['season'] = data['month'].apply(lambda x: (x % 12 + 3) // 3)# 标准化数据
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data)# 划分训练集和测试集
train_data = scaled_data[:-60] # 使用2020年11月之前的数据作为训练集
test_data = scaled_data[-60:] # 最后60天作为测试集(虽然实际测试集应该是未知的)# 创建时间序列数据集
def create_dataset(data, look_back=30, forecast_horizon=60):X, y = [], []for i in range(len(data) - look_back - forecast_horizon + 1):X.append(data[i:(i + look_back)])y.append(data[(i + look_back):(i + look_back + forecast_horizon), :len(pollutants)]) # 只预测污染物return np.array(X), np.array(y)look_back = 60 # 使用过去60天的数据
forecast_horizon = 60 # 预测未来60天X_train, y_train = create_dataset(train_data, look_back, forecast_horizon)
X_test, y_test = create_dataset(test_data, look_back, forecast_horizon)print(f"Training data shape: X_train={X_train.shape}, y_train={y_train.shape}")
print(f"Test data shape: X_test={X_test.shape}, y_test={y_test.shape}")
3. 模型构建
3.1 LSTM模型构建
def build_lstm_model(input_shape, output_shape):model = Sequential([LSTM(128, return_sequences=True, input_shape=input_shape),Dropout(0.2),LSTM(64, return_sequences=True),Dropout(0.2),LSTM(32),Dropout(0.2),Dense(64, activation='relu'),Dense(output_shape[0] * output_shape[1]),tf.keras.layers.Reshape(output_shape)])model.compile(optimizer='adam', loss='mse', metrics=['mae'])return model# 获取输入输出形状
input_shape = (X_train.shape[1], X_train.shape[2])
output_shape = (y_train.shape[1], y_train.shape[2])lstm_model = build_lstm_model(input_shape, output_shape)
lstm_model.summary()
3.2 GRU模型构建
def build_gru_model(input_shape, output_shape):model = Sequential([GRU(128, return_sequences=True, input_shape=input_shape),Dropout(0.2),GRU(64, return_sequences=True),Dropout(0.2),GRU(32),Dropout(0.2),Dense(64, activation='relu'),Dense(output_shape[0] * output_shape[1]),tf.keras.layers.Reshape(output_shape)])model.compile(optimizer='adam', loss='mse', metrics=['mae'])return modelgru_model = build_gru_model(input_shape, output_shape)
gru_model.summary()
4. 模型训练
4.1 训练参数设置
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
batch_size = 32
epochs = 100
validation_split = 0.1
4.2 LSTM模型训练
lstm_history = lstm_model.fit(X_train, y_train,batch_size=batch_size,epochs=epochs,validation_split=validation_split,callbacks=[early_stopping],verbose=1
)# 绘制训练过程
plt.figure(figsize=(12, 6))
plt.plot(lstm_history.history['loss'], label='Training Loss')
plt.plot(lstm_history.history['val_loss'], label='Validation Loss')
plt.title('LSTM Model Training Process')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
4.3 GRU模型训练
gru_history = gru_model.fit(X_train, y_train,batch_size=batch_size,epochs=epochs,validation_split=validation_split,callbacks=[early_stopping],verbose=1
)# 绘制训练过程
plt.figure(figsize=(12, 6))
plt.plot(gru_history.history['loss'], label='Training Loss')
plt.plot(gru_history.history['val_loss'], label='Validation Loss')
plt.title('GRU Model Training Process')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
5. 模型评估与预测
5.1 评估指标函数
def evaluate_model(model, X_test, y_test, scaler, feature_range=(0, len(pollutants)-1)):# 预测y_pred = model.predict(X_test)# 反标准化dummy_data = np.zeros((y_test.shape[0], y_test.shape[1], scaled_data.shape[1]))dummy_data[:, :, feature_range[0]:feature_range[1]+1] = y_testy_test_original = scaler.inverse_transform(dummy_data.reshape(-1, scaled_data.shape[1]))[:, feature_range[0]:feature_range[1]+1]y_test_original = y_test_original.reshape(y_test.shape)dummy_data[:, :, feature_range[0]:feature_range[1]+1] = y_predy_pred_original = scaler.inverse_transform(dummy_data.reshape(-1, scaled_data.shape[1]))[:, feature_range[0]:feature_range[1]+1]y_pred_original = y_pred_original.reshape(y_pred.shape)# 计算指标metrics = {}for i, pollutant in enumerate(pollutants):mse = mean_squared_error(y_test_original[:, :, i].flatten(), y_pred_original[:, :, i].flatten())mae = mean_absolute_error(y_test_original[:, :, i].flatten(), y_pred_original[:, :, i].flatten())metrics[pollutant] = {'MSE': mse, 'MAE': mae}return metrics, y_test_original, y_pred_original
5.2 LSTM模型评估
lstm_metrics, lstm_y_test, lstm_y_pred = evaluate_model(lstm_model, X_test, y_test, scaler)print("LSTM Model Performance:")
for pollutant, metric in lstm_metrics.items():print(f"{pollutant}: MSE={metric['MSE']:.2f}, MAE={metric['MAE']:.2f}")
5.3 GRU模型评估
gru_metrics, gru_y_test, gru_y_pred = evaluate_model(gru_model, X_test, y_test, scaler)print("GRU Model Performance:")
for pollutant, metric in gru_metrics.items():print(f"{pollutant}: MSE={metric['MSE']:.2f}, MAE={metric['MAE']:.2f}")
5.4 预测结果可视化
# 绘制预测结果与实际值对比
def plot_predictions(y_test, y_pred, model_name):plt.figure(figsize=(15, 20))for i, pollutant in enumerate(pollutants):plt.subplot(len(pollutants), 1, i+1)plt.plot(y_test[0, :, i], label='Actual')plt.plot(y_pred[0, :, i], label='Predicted')plt.title(f'{model_name} - {pollutant} Prediction')plt.xlabel('Days')plt.ylabel('Concentration')plt.legend()plt.tight_layout()plt.show()plot_predictions(lstm_y_test, lstm_y_pred, 'LSTM')
plot_predictions(gru_y_test, gru_y_pred, 'GRU')
6. 模型比较与优化
6.1 性能比较
# 比较LSTM和GRU模型的性能
comparison = pd.DataFrame()for pollutant in pollutants:lstm_mse = lstm_metrics[pollutant]['MSE']gru_mse = gru_metrics[pollutant]['MSE']lstm_mae = lstm_metrics[pollutant]['MAE']gru_mae = gru_metrics[pollutant]['MAE']comparison = pd.concat([comparison, pd.DataFrame({'Pollutant': [pollutant],'LSTM MSE': [lstm_mse],'GRU MSE': [gru_mse],'MSE Difference': [gru_mse - lstm_mse],'LSTM MAE': [lstm_mae],'GRU MAE': [gru_mae],'MAE Difference': [gru_mae - lstm_mae]})])print(comparison)
6.2 模型优化建议
- 超参数调优:使用网格搜索或随机搜索优化网络层数、神经元数量、dropout率等
- 特征选择:通过特征重要性分析选择最具预测力的特征
- 集成方法:结合LSTM和GRU的优点,构建混合模型
- 注意力机制:引入注意力机制提高模型对关键时间点的关注
7. 实际预测应用
7.1 预测未来60天污染物数据
# 使用完整数据训练最终模型
X_full, y_full = create_dataset(scaled_data, look_back, forecast_horizon)# 重新训练LSTM模型
final_lstm_model = build_lstm_model(input_shape, output_shape)
final_lstm_model.fit(X_full, y_full,batch_size=batch_size,epochs=epochs,verbose=1
)# 准备预测输入(最后look_back天的数据)
last_sequence = scaled_data[-look_back:]
last_sequence = last_sequence.reshape((1, look_back, scaled_data.shape[1]))# 预测未来60天
future_pred = final_lstm_model.predict(last_sequence)# 反标准化预测结果
dummy_data = np.zeros((future_pred.shape[0], future_pred.shape[1], scaled_data.shape[1]))
dummy_data[:, :, :len(pollutants)] = future_pred
future_pred_original = scaler.inverse_transform(dummy_data.reshape(-1, scaled_data.shape[1]))[:, :len(pollutants)]
future_pred_original = future_pred_original.reshape(future_pred.shape)# 创建预测日期范围
last_date = data.index[-1]
pred_dates = pd.date_range(start=last_date + pd.Timedelta(days=1), periods=forecast_horizon)# 保存预测结果
prediction_results = pd.DataFrame(future_pred_original[0], columns=pollutants, index=pred_dates)
print(prediction_results.head())# 可视化预测结果
plt.figure(figsize=(15, 10))
for i, pollutant in enumerate(pollutants):plt.subplot(len(pollutants), 1, i+1)plt.plot(prediction_results.index, prediction_results[pollutant])plt.title(f'Predicted {pollutant} Concentration for Next 60 Days')plt.xlabel('Date')plt.ylabel('Concentration')
plt.tight_layout()
plt.show()
8. 结论与展望
本研究使用LSTM和GRU深度学习模型对上海空气质量进行了预测。实验结果表明:
- 两种模型都能较好地捕捉空气污染物随时间变化的复杂模式
- 在本案例中,LSTM模型在大多数污染物预测上略优于GRU模型
- 模型的预测性能在不同污染物上存在差异,对PM2.5和PM10的预测相对更准确
- 天气因素对污染物浓度预测有重要影响
未来研究方向包括:
- 结合更多外部数据(如交通流量、工业活动等)
- 尝试更先进的模型架构(如Transformer)
- 开发多任务学习框架同时预测多种污染物
- 研究不确定性量化方法提供预测置信区间
本研究为城市空气质量预测提供了一种有效的深度学习解决方案,有助于环境管理部门提前制定污染防控措施,保障公众健康。
参考文献
- Hochreiter, S., & Schmidhuber, J. (1997). Long short-term memory. Neural computation.
- Cho, K., et al. (2014). Learning phrase representations using RNN encoder-decoder for statistical machine translation.
- Zheng, Y., et al. (2015). Forecasting air quality in Beijing with LSTM networks.
- Zhang, J., et al. (2019). Attention-based bidirectional GRU networks for air quality prediction.
(注:以上代码和报告为示例框架,实际应用时需要根据具体数据进行调整和完善。)