当前位置: 首页 > article >正文

基于LSTM的机场天气分析及模型预测

数据分析实操集合:

1、关于房间传感器监测数据集的探索
2、EEMD-LSTM模型择时策略 — 1.EEMD分解与LSTM模型搭建
3、EEMD-LSTM模型择时策略 — 2. 量化回测
4、国际超市电商销售数据分析
5、基于问卷调查数据的多元统计数据分析与预测(因子分析、对应分析与逻辑回归)
6、手写文本识别
7、语音情感识别
8、电商会员门店消费数据分析
9、糖尿病风险预测模型分析与构建
10、基于卷积神经网络(CNN)和ResNet50的水果与蔬菜图像分类系统
11、学生抑郁情况可视化分析及预测
12、人脸表情识别(GUI实时识别)

基于LSTM的机场天气分析及模型预测

问题描述

降水概率预测
季节性和趋势分析
深度学习建模
数据质量分析

# 若需要完整数据集以及代码请点击以下链接
https://mbd.pub/o/bread/mbd-aJWTmppx

背景描述

本数据集提供了英国希思罗机场1979 - 2023年的每日天气观测数据(STAID: 1860)。数据来自欧洲气候评估和数据集(ECA&D),包括多个天气参数,如温度、降水、日照等。

数据说明

字段说明
DATE日期,格式为YYYYMMDD。
TX每日最高气温,单位为0.1°C。
TN每日最低气温,单位为0.1°C。
TG每日平均气温,单位为0.1°C。
SS每日日照时长,单位为0.1小时。
SD每日积雪深度,单位为1厘米。
RR每日降水量,单位为0.1毫米。
QQ每日全球辐射量,单位为W/m²。
PP每日海平面气压,单位为0.1百帕(hPa)。
HU每日相对湿度,单位为百分比(%)。
CC每日云量,以八分制(oktas)表示。

1. 导包导数据

1.1 导包

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from tensorflow.keras.optimizers import Adam
from sklearn.linear_model import LinearRegression
import pyecharts.options as opts
from pyecharts.charts import Line
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import warnings
warnings.filterwarnings("ignore")

在这里插入图片描述

1.2 导数据

# 读取数据
data = pd.read_csv('/home/mw/input/01108524/london_weather_data_1979_to_2023.csv', encoding='GBK')
data.head()

在这里插入图片描述

1.3 数据预处理

数据文件中包含了若干评估数据质量的字段,如 Q_TX, Q_TN,字段的参数说明如下:

  • 0: 有效数据
  • 1: 可疑数据
  • 9: 缺失数据
    也就是说Q_开头的数据没什么用
data.isnull().sum()

在这里插入图片描述

# 删除Q_开头的数据
data = data.drop(data.filter(like='Q_', axis=1).columns, axis=1)
data.isnull().sum()

在这里插入图片描述

1.4 缺失值填充

使用回归插值进行缺失值填充

# 对数据进行回归插值
for column in data.columns:
    x = data[column].dropna().index.values.reshape(-1, 1)
    y = data[column].dropna().values
    x_interp = data[column].index.values.reshape(-1, 1)
    
    # 只对空值进行插值
    if data[column].isnull().any():
        # 创建线性回归模型并拟合数据
        model = LinearRegression()
        model.fit(x, y)
    
        # 对空值进行插值
        data[column] = np.where(data[column].isnull(), model.predict(x_interp), data[column])
data.isnull().sum()

在这里插入图片描述

1.5 日期格式转换

data['DATE'] = pd.to_datetime(data['DATE'], format='%Y%m%d')  # 转换日期格式
data = data.sort_values(by='DATE')  # 按日期排序

# 提取年、月、日等信息
data['year'] = data['DATE'].dt.year
data['month'] = data['DATE'].dt.month
data['day'] = data['DATE'].dt.day
data.head()

在这里插入图片描述

2. 数据可视化,季节性和趋势分析

2.1 日最高温度随滚动平均值的变化趋势

tx_values = data['TX'].tolist()
# 对 TX(每日最高气温)进行滚动平均,窗口大小为30天
data['TX_rolling_mean'] = data['TX'].rolling(window=30).mean()

tx_rolling_mean_values = data['TX_rolling_mean'].tolist()

# 创建折线图
line = Line()

# 添加数据系列
line.add_xaxis(data['DATE'].tolist())
line.add_yaxis("日最高温度", tx_values, is_smooth=True)
line.add_yaxis("30天滚动平均值", tx_rolling_mean_values, is_smooth=True, color='red')

# 设置图表的全局配置
line.set_global_opts(
    title_opts=opts.TitleOpts(title="日最高温度随滚动平均值的变化趋势"),
    xaxis_opts=opts.AxisOpts(type_="category", name="Date", is_scale=True),
    yaxis_opts=opts.AxisOpts(name="Temperature (0.1°C)"),
    datazoom_opts=[opts.DataZoomOpts(type_="slider", range_start=0, range_end=100)],  # 添加滑动条
    legend_opts=opts.LegendOpts(pos_right="10%")  # 图例位置
)

line.render_notebook()

在这里插入图片描述

# 使用线性回归拟合气温数据
x = np.array((data['DATE'] - data['DATE'].min()).dt.days).reshape(-1, 1)  # 日期转为天数
y = data['TX'].values

# 拟合模型
model = LinearRegression()
model.fit(x, y)
trend = model.predict(x)

# 将结果转换为适合Pyecharts的格式
dates = data['DATE'].dt.strftime('%Y-%m-%d').tolist()
tx_values = data['TX'].tolist()
trend_values = trend.tolist()
trend_values = [int(value) for value in trend_values]
# 创建折线图
line = Line()

# 添加数据系列
line.add_xaxis(dates)
line.add_yaxis("日最高温度", tx_values, is_smooth=True)
line.add_yaxis("线性回归趋势", trend_values, is_smooth=True, color='green', tooltip_opts=opts.TooltipOpts(is_show=False))

# 设置图表的全局配置
line.set_global_opts(
    title_opts=opts.TitleOpts(title="日最高温度与线性回归趋势"),
    xaxis_opts=opts.AxisOpts(type_="category", name="Date", is_scale=True),
    yaxis_opts=opts.AxisOpts(name="Temperature (0.1°C)"),
    datazoom_opts=[opts.DataZoomOpts(type_="slider", range_start=0, range_end=100)],  # 添加滑动条
    legend_opts=opts.LegendOpts(pos_right="10%")  # 图例位置
)

# 在Jupyter Notebook中渲染
line.render_notebook()

在这里插入图片描述

2.3 最高气温的月季节变化

# 按月计算每日最高气温的平均值
monthly_avg_tx = data.groupby('month')['TX'].mean()

# 绘制每月气温的季节性变化
plt.figure(figsize=(10, 6))
monthly_avg_tx.plot(kind='bar', color='skyblue')
plt.xlabel('月份')
plt.ylabel('平均最高气温(0.1°C)')
plt.title('最高气温的月季节变化')
plt.xticks(rotation=0)
plt.show()

在这里插入图片描述

2.4 平均最高气温的季节性变化

# 定义季节:春(3-5月),夏(6-8月),秋(9-11月),冬(12-2月)
def get_season(month):
    if month in [3, 4, 5]:
        return 'Spring'
    elif month in [6, 7, 8]:
        return 'Summer'
    elif month in [9, 10, 11]:
        return 'Autumn'
    else:
        return 'Winter'

data['season'] = data['month'].apply(get_season)

# 按季节计算每日最高气温的平均值
seasonal_avg_tx = data.groupby('season')['TX'].mean()

# 绘制季节性气温
plt.figure(figsize=(10, 6))
seasonal_avg_tx.plot(kind='bar', color='lightgreen')
plt.xlabel('季节')
plt.ylabel('平均最高气温 (0.1°C)')
plt.title('平均最高气温的季节性变化')
plt.xticks(rotation=0)
plt.show()

在这里插入图片描述

3. 深度学习建模及降水预测

3.1 数据划分及格式化

先使用One-Hot进行季节编码再使用MinMaxScaler进行标准化

# 使用pandas的get_dummies进行One-Hot编码
data = pd.get_dummies(data, columns=['season'], drop_first=True)
data['DATE'] = (data['DATE'] - data['DATE'].min()).dt.days
X = data.drop(['TX_rolling_mean', 'RR'], axis=1)
y = data['RR']

# 标准化数据
scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = scaler.fit_transform(X)
y_scaled = scaler.fit_transform(y.values.reshape(-1, 1))

# 数据切割为训练集和测试集(例如按80%训练,20%测试)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.2, shuffle=False)
# 转换为适合LSTM的输入格式(时间步长为1)
def create_dataset(X, y, time_step=1):
    X_data, y_data = [], []
    for i in range(len(X) - time_step):
        X_data.append(X[i:(i + time_step), :])
        y_data.append(y[i + time_step, 0])
    return np.array(X_data), np.array(y_data)

time_step = 1  # 使用1天作为时间步长
X_train_lstm, y_train_lstm = create_dataset(X_train, y_train, time_step)
X_test_lstm, y_test_lstm = create_dataset(X_test, y_test, time_step)

# LSTM输入需要是三维的:[样本数, 时间步长, 特征数]
print(X_train_lstm.shape)  # (样本数, 时间步长, 特征数)

在这里插入图片描述

3.2 构建LSTM模型

# 构建LSTM模型
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train_lstm.shape[1], X_train_lstm.shape[2])))
model.add(Dropout(0.3))
model.add(LSTM(units=50, return_sequences=False))
model.add(Dropout(0.3))
model.add(Dense(units=1))  # 输出一个值

# 编译模型
model.compile(optimizer=Adam(learning_rate=0.001), loss='mean_squared_error')

# 设置早停和学习率调整
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6)

# 定义回调函数保存最好的模型
checkpoint = ModelCheckpoint('best_model.keras', save_best_only=True, monitor='val_loss', mode='min')

# 训练模型并使用回调函数
model.fit(X_train_lstm, y_train_lstm, epochs=100, batch_size=32,
          validation_data=(X_test_lstm, y_test_lstm),
          callbacks=[early_stopping, reduce_lr, checkpoint])

在这里插入图片描述

3.3 预测时间序列模型及可视化

根据红色的预测线和蓝色的真实线对比来说,有一定的准确率,真实值高的时候预测值也高,但是预测值波动幅度没有真实值大

# 使用训练好的模型进行预测
y_pred_scaled = model.predict(X_test_lstm)

# 逆标准化(还原到原始数据范围)
y_pred = scaler.inverse_transform(y_pred_scaled)
y_test = scaler.inverse_transform(y_test_lstm.reshape(-1, 1))

# 可视化预测结果
plt.figure(figsize=(12,6))
plt.plot(y_test, color='blue', label='真实值')
plt.plot(y_pred, color='red', label='预测值')
plt.title('RR 预测')
plt.xlabel('时间')
plt.ylabel('RR')
plt.legend()
plt.show()

在这里插入图片描述

mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)

print(f'MSE: {mse}')
print(f'RMSE: {rmse}')
print(f'MAE: {mae}')

在这里插入图片描述

# 若需要完整数据集以及代码请点击以下链接
https://mbd.pub/o/bread/mbd-aJWTmppx

http://www.kler.cn/a/558400.html

相关文章:

  • mysql之事务深度解析与实战应用:保障数据一致性的基石
  • redis缓存与Mysql数据一致性,要如何解决?
  • 2025年-G14-Lc88-278.第一个坏版本 -java版
  • OpenResty
  • BUU40 [安洵杯 2019]easy_serialize_php
  • 力扣-回溯-93 复原IP地址
  • 贪吃蛇小游戏的实践
  • 计算机网络:应用层 —— 文件传送协议 FTP
  • 自动化办公|xlwings生成图表
  • go io.Pipe
  • 创客匠人:知识服务还有未来吗?个人IP如何突围下半场的生死局?
  • 蓝桥杯15 填空题
  • STM32的HAL库开发---多通道ADC采集(DMA读取)实验
  • 【Spring+MyBatis】_图书管理系统(下篇)
  • 基于 Python+OpenCV 的疲劳检测系统设计与实现(源码+文档)
  • android studio kotlin项目build时候提示错误 Unknown Kotlin JVM target: 21
  • go 并发 gorouting chan channel select Mutex sync.One
  • 国产编辑器EverEdit - 在编辑器中对文本进行排序
  • 便捷批量字符一键查找替换工具
  • 从卡顿到丝滑:火山引擎DeepSeek-R1引领AI工具新体验