Python实战ARIMA与LSTM在气温预测中的终极对决清晨打开天气预报App时你是否好奇过那些温度曲线背后的技术逻辑当气象学家需要预测未来一周的气温走势时他们往往会面临一个关键抉择该用经典的统计模型还是新兴的深度学习工具这个问题同样困扰着许多刚踏入时间序列预测领域的数据从业者。本文将以Kaggle气候数据集为战场用Python代码作为武器带你亲历ARIMA与LSTM两大预测模型的实战对比。1. 环境准备与数据探索工欲善其事必先利其器。我们选择Kaggle上公开的Daily Climate Time Series Data作为实验数据集这份数据记录了印度德里地区2013-2017年间的每日气候指标包含平均温度、湿度、风速等关键参数。import pandas as pd import matplotlib.pyplot as plt # 加载数据集 df pd.read_csv(DailyDelhiClimate.csv, parse_dates[date], index_coldate) print(df.head()) # 可视化温度序列 plt.figure(figsize(12,6)) df[meantemp].plot(titleDelhi Daily Mean Temperature (2013-2017)) plt.ylabel(Temperature (°C)) plt.grid(True) plt.show()执行这段代码后我们会看到温度序列呈现明显的季节性波动。通过简单的.describe()方法可以快速获取统计摘要统计量温度值(°C)均值25.52标准差7.23最小值6.0025%分位18.85中位数27.3075%分位31.10最大值38.60注意数据探索阶段发现2017年12月有连续5天的温度记录为0°C这显然是异常值需要后续处理。2. ARIMA模型实战全流程2.1 数据预处理关键步骤ARIMA模型对数据平稳性有严格要求我们需要先进行以下处理异常值处理用前后三天的移动平均值替代0值记录平稳性检验使用Augmented Dickey-Fuller(ADF)测试季节性分解观察趋势、季节性和残差分量from statsmodels.tsa.stattools import adfuller from statsmodels.tsa.seasonal import seasonal_decompose # 异常值处理 df[meantemp] df[meantemp].replace(0, np.nan) df[meantemp] df[meantemp].fillna(df[meantemp].rolling(7, min_periods1).mean()) # ADF检验 result adfuller(df[meantemp].dropna()) print(fADF统计量: {result[0]:.4f}) print(fp值: {result[1]:.4f}) # 季节性分解 decomposition seasonal_decompose(df[meantemp], modeladditive, period365) decomposition.plot() plt.show()2.2 参数选择与模型训练ARIMA(p,d,q)的参数选择是模型成败的关键。我们采用网格搜索结合AIC准则的方法from statsmodels.tsa.arima.model import ARIMA import itertools # 参数搜索范围 p d q range(0, 3) pdq list(itertools.product(p, d, q)) # 网格搜索 best_aic float(inf) best_order None for order in pdq: try: model ARIMA(df[meantemp], orderorder) results model.fit() if results.aic best_aic: best_aic results.aic best_order order except: continue print(f最优参数组合: ARIMA{best_order} AIC:{best_aic:.2f})实际运行结果显示最优参数为ARIMA(1,0,2)AIC值为7284.32。这个结果有些反直觉——d0意味着不需要差分这与ADF检验结果似乎矛盾。这种情况在实际项目中很常见需要结合ACF/PACF图进行人工判断。3. LSTM模型构建与优化3.1 数据准备的特殊处理与ARIMA不同LSTM需要将数据转换为监督学习格式。我们定义以下预处理流程标准化使用MinMaxScaler将温度缩放到[0,1]区间时间步构建用过去30天的数据预测下一天的温度数据集划分按7:3比例分割训练集和测试集from sklearn.preprocessing import MinMaxScaler from keras.preprocessing.sequence import TimeseriesGenerator # 数据标准化 scaler MinMaxScaler() scaled_data scaler.fit_transform(df[[meantemp]]) # 构建时间序列生成器 look_back 30 train_size int(len(scaled_data) * 0.7) train, test scaled_data[:train_size], scaled_data[train_size:] train_generator TimeseriesGenerator(train, train, lengthlook_back, batch_size32) test_generator TimeseriesGenerator(test, test, lengthlook_back, batch_size32)3.2 网络架构设计与训练我们构建一个包含两层LSTM的神经网络中间添加Dropout层防止过拟合from keras.models import Sequential from keras.layers import LSTM, Dense, Dropout model Sequential() model.add(LSTM(100, return_sequencesTrue, input_shape(look_back, 1))) model.add(Dropout(0.2)) model.add(LSTM(50)) model.add(Dense(1)) model.compile(optimizeradam, lossmse) # 模型训练 history model.fit(train_generator, epochs50, validation_datatest_generator) # 绘制损失曲线 plt.plot(history.history[loss], labelTrain Loss) plt.plot(history.history[val_loss], labelValidation Loss) plt.legend() plt.show()在实际训练中我们发现验证损失在第35轮左右开始上升这是典型的过拟合信号。通过添加EarlyStopping回调函数可以自动停止训练。4. 模型对比与选择指南4.1 预测效果可视化对比将两个模型的预测结果绘制在同一张图中可以直观比较它们的表现# ARIMA预测 arima_pred arima_results.predict(starttest.index[0], endtest.index[-1]) # LSTM预测 lstm_pred model.predict(test_generator) lstm_pred scaler.inverse_transform(lstm_pred) plt.figure(figsize(14,6)) plt.plot(df.index, df[meantemp], labelActual) plt.plot(arima_pred.index, arima_pred, labelARIMA) plt.plot(test.index[look_back:], lstm_pred, labelLSTM) plt.legend() plt.title(Model Comparison) plt.show()从图中可以明显看出LSTM的预测曲线更贴近实际观测值特别是在温度剧烈波动的区域。4.2 量化指标对比分析我们计算三个关键评估指标进行量化对比评估指标ARIMALSTMMAE2.341.67RMSE3.122.15R²0.820.91提示MAE(平均绝对误差)和RMSE(均方根误差)越小越好R²越接近1越好4.3 模型选择决策树根据实战经验我总结出以下选择指南选择ARIMA当数据具有强线性趋势和明显季节性训练数据量有限(1000个样本)需要快速得到初步预测结果模型可解释性很重要选择LSTM当数据呈现复杂非线性模式有足够多的训练数据(10000个样本)计算资源充足预测精度是首要考虑混合策略先用ARIMA捕捉线性成分再用LSTM拟合残差对季节性强的数据可以先去季节化再用LSTM在气温预测这个具体场景中虽然LSTM表现更好但ARIMA的预测速度要快50倍。如果只是需要未来3天的粗略预测ARIMA可能是更经济的选择。
别再纠结选哪个了!用Python实战对比ARIMA和LSTM预测气温(附完整Kaggle数据集代码)
Python实战ARIMA与LSTM在气温预测中的终极对决清晨打开天气预报App时你是否好奇过那些温度曲线背后的技术逻辑当气象学家需要预测未来一周的气温走势时他们往往会面临一个关键抉择该用经典的统计模型还是新兴的深度学习工具这个问题同样困扰着许多刚踏入时间序列预测领域的数据从业者。本文将以Kaggle气候数据集为战场用Python代码作为武器带你亲历ARIMA与LSTM两大预测模型的实战对比。1. 环境准备与数据探索工欲善其事必先利其器。我们选择Kaggle上公开的Daily Climate Time Series Data作为实验数据集这份数据记录了印度德里地区2013-2017年间的每日气候指标包含平均温度、湿度、风速等关键参数。import pandas as pd import matplotlib.pyplot as plt # 加载数据集 df pd.read_csv(DailyDelhiClimate.csv, parse_dates[date], index_coldate) print(df.head()) # 可视化温度序列 plt.figure(figsize(12,6)) df[meantemp].plot(titleDelhi Daily Mean Temperature (2013-2017)) plt.ylabel(Temperature (°C)) plt.grid(True) plt.show()执行这段代码后我们会看到温度序列呈现明显的季节性波动。通过简单的.describe()方法可以快速获取统计摘要统计量温度值(°C)均值25.52标准差7.23最小值6.0025%分位18.85中位数27.3075%分位31.10最大值38.60注意数据探索阶段发现2017年12月有连续5天的温度记录为0°C这显然是异常值需要后续处理。2. ARIMA模型实战全流程2.1 数据预处理关键步骤ARIMA模型对数据平稳性有严格要求我们需要先进行以下处理异常值处理用前后三天的移动平均值替代0值记录平稳性检验使用Augmented Dickey-Fuller(ADF)测试季节性分解观察趋势、季节性和残差分量from statsmodels.tsa.stattools import adfuller from statsmodels.tsa.seasonal import seasonal_decompose # 异常值处理 df[meantemp] df[meantemp].replace(0, np.nan) df[meantemp] df[meantemp].fillna(df[meantemp].rolling(7, min_periods1).mean()) # ADF检验 result adfuller(df[meantemp].dropna()) print(fADF统计量: {result[0]:.4f}) print(fp值: {result[1]:.4f}) # 季节性分解 decomposition seasonal_decompose(df[meantemp], modeladditive, period365) decomposition.plot() plt.show()2.2 参数选择与模型训练ARIMA(p,d,q)的参数选择是模型成败的关键。我们采用网格搜索结合AIC准则的方法from statsmodels.tsa.arima.model import ARIMA import itertools # 参数搜索范围 p d q range(0, 3) pdq list(itertools.product(p, d, q)) # 网格搜索 best_aic float(inf) best_order None for order in pdq: try: model ARIMA(df[meantemp], orderorder) results model.fit() if results.aic best_aic: best_aic results.aic best_order order except: continue print(f最优参数组合: ARIMA{best_order} AIC:{best_aic:.2f})实际运行结果显示最优参数为ARIMA(1,0,2)AIC值为7284.32。这个结果有些反直觉——d0意味着不需要差分这与ADF检验结果似乎矛盾。这种情况在实际项目中很常见需要结合ACF/PACF图进行人工判断。3. LSTM模型构建与优化3.1 数据准备的特殊处理与ARIMA不同LSTM需要将数据转换为监督学习格式。我们定义以下预处理流程标准化使用MinMaxScaler将温度缩放到[0,1]区间时间步构建用过去30天的数据预测下一天的温度数据集划分按7:3比例分割训练集和测试集from sklearn.preprocessing import MinMaxScaler from keras.preprocessing.sequence import TimeseriesGenerator # 数据标准化 scaler MinMaxScaler() scaled_data scaler.fit_transform(df[[meantemp]]) # 构建时间序列生成器 look_back 30 train_size int(len(scaled_data) * 0.7) train, test scaled_data[:train_size], scaled_data[train_size:] train_generator TimeseriesGenerator(train, train, lengthlook_back, batch_size32) test_generator TimeseriesGenerator(test, test, lengthlook_back, batch_size32)3.2 网络架构设计与训练我们构建一个包含两层LSTM的神经网络中间添加Dropout层防止过拟合from keras.models import Sequential from keras.layers import LSTM, Dense, Dropout model Sequential() model.add(LSTM(100, return_sequencesTrue, input_shape(look_back, 1))) model.add(Dropout(0.2)) model.add(LSTM(50)) model.add(Dense(1)) model.compile(optimizeradam, lossmse) # 模型训练 history model.fit(train_generator, epochs50, validation_datatest_generator) # 绘制损失曲线 plt.plot(history.history[loss], labelTrain Loss) plt.plot(history.history[val_loss], labelValidation Loss) plt.legend() plt.show()在实际训练中我们发现验证损失在第35轮左右开始上升这是典型的过拟合信号。通过添加EarlyStopping回调函数可以自动停止训练。4. 模型对比与选择指南4.1 预测效果可视化对比将两个模型的预测结果绘制在同一张图中可以直观比较它们的表现# ARIMA预测 arima_pred arima_results.predict(starttest.index[0], endtest.index[-1]) # LSTM预测 lstm_pred model.predict(test_generator) lstm_pred scaler.inverse_transform(lstm_pred) plt.figure(figsize(14,6)) plt.plot(df.index, df[meantemp], labelActual) plt.plot(arima_pred.index, arima_pred, labelARIMA) plt.plot(test.index[look_back:], lstm_pred, labelLSTM) plt.legend() plt.title(Model Comparison) plt.show()从图中可以明显看出LSTM的预测曲线更贴近实际观测值特别是在温度剧烈波动的区域。4.2 量化指标对比分析我们计算三个关键评估指标进行量化对比评估指标ARIMALSTMMAE2.341.67RMSE3.122.15R²0.820.91提示MAE(平均绝对误差)和RMSE(均方根误差)越小越好R²越接近1越好4.3 模型选择决策树根据实战经验我总结出以下选择指南选择ARIMA当数据具有强线性趋势和明显季节性训练数据量有限(1000个样本)需要快速得到初步预测结果模型可解释性很重要选择LSTM当数据呈现复杂非线性模式有足够多的训练数据(10000个样本)计算资源充足预测精度是首要考虑混合策略先用ARIMA捕捉线性成分再用LSTM拟合残差对季节性强的数据可以先去季节化再用LSTM在气温预测这个具体场景中虽然LSTM表现更好但ARIMA的预测速度要快50倍。如果只是需要未来3天的粗略预测ARIMA可能是更经济的选择。