别再纠结选哪个了!用Python实战ARIMA和LSTM预测气温,看谁更准(附完整代码)
Python实战ARIMA与LSTM气温预测对比指南当面对一份气候时间序列数据时许多数据分析师都会陷入选择困难——是该用经典的ARIMA模型还是尝试更现代的LSTM神经网络这个问题没有标准答案但通过实际动手对比我们能获得最直观的认知。本文将带你用Python完整实现两种模型从数据准备到结果评估一步步揭开它们在不同场景下的表现差异。1. 环境准备与数据加载在开始建模前我们需要配置好Python环境并获取实验数据。推荐使用Anaconda创建独立环境避免库版本冲突conda create -n weather_prediction python3.8 conda activate weather_prediction安装必要的库pip install pandas numpy matplotlib statsmodels tensorflow scikit-learn我们将使用Kaggle上的Daily Climate Time Series Data数据集包含2013-2017年新德里的日均气温、湿度等指标。下载后通过pandas加载数据import pandas as pd # 加载数据并解析日期列 df pd.read_csv(DailyDelhiClimate.csv, parse_dates[date], index_coldate) print(df.head()) # 可视化气温变化 import matplotlib.pyplot as plt df[meantemp].plot(figsize(12,6)) plt.title(Delhi Daily Mean Temperature (2013-2017)) plt.ylabel(Temperature (°C)) plt.show()提示在时间序列分析中确保日期列被正确解析为datetime类型并设置为索引非常重要这能简化后续的resample和rolling操作。数据初步检查应包括缺失值情况df.isnull().sum()统计描述df.describe()异常值检测通过箱线图或3σ原则2. ARIMA模型构建与调优2.1 数据平稳性处理ARIMA模型要求输入序列是平稳的我们需要先进行检验和处理from statsmodels.tsa.stattools import adfuller # ADF平稳性检验 def test_stationarity(series): result adfuller(series.dropna()) print(ADF Statistic:, result[0]) print(p-value:, result[1]) return result[1] 0.05 # 返回是否非平稳 is_non_stationary test_stationarity(df[meantemp]) if is_non_stationary: # 一阶差分 temp_diff df[meantemp].diff().dropna() test_stationarity(temp_diff)如果一阶差分后仍不平稳可能需要季节性差分或对数变换。对于有明显季节性的数据可以考虑SARIMA模型。2.2 参数选择与模型训练ARIMA有三个关键参数(p,d,q)其中d已通过差分确定。对于p和q我们可以结合ACF/PACF图和信息准则来选择from statsmodels.tsa.arima.model import ARIMA import numpy as np # 网格搜索寻找最佳参数 def find_best_arima(series, max_p5, max_q5): best_aic np.inf best_order None for p in range(max_p1): for q in range(max_q1): try: model ARIMA(series, order(p,1,q)) results model.fit() if results.aic best_aic: best_aic results.aic best_order (p,1,q) except: continue return best_order, best_aic best_order, best_aic find_best_arima(df[meantemp]) print(fBest ARIMA order: {best_order} with AIC: {best_aic}) # 训练最终模型 arima_model ARIMA(df[meantemp], orderbest_order).fit() print(arima_model.summary())2.3 预测与评估将数据分为训练集和测试集评估模型预测效果from sklearn.metrics import mean_absolute_error # 划分训练测试集 train_size int(len(df)*0.8) train, test df[meantemp][:train_size], df[meantemp][train_size:] # 训练模型 model ARIMA(train, orderbest_order).fit() # 预测 arima_pred model.forecast(stepslen(test)) # 评估 arima_mae mean_absolute_error(test, arima_pred) print(fARIMA MAE: {arima_mae:.2f}) # 可视化 plt.figure(figsize(12,6)) plt.plot(train.index, train, labelTrain) plt.plot(test.index, test, labelTrue) plt.plot(test.index, arima_pred, labelARIMA Predict) plt.legend() plt.show()3. LSTM模型构建与训练3.1 数据预处理LSTM需要不同的数据准备方式主要是将序列转化为监督学习格式from sklearn.preprocessing import MinMaxScaler # 数据标准化 scaler MinMaxScaler() scaled_temp scaler.fit_transform(df[[meantemp]]) # 创建时间步序列 def create_dataset(data, look_back30): X, y [], [] for i in range(len(data)-look_back-1): X.append(data[i:(ilook_back), 0]) y.append(data[ilook_back, 0]) return np.array(X), np.array(y) look_back 30 # 使用前30天预测下一天 X, y create_dataset(scaled_temp, look_back) # 划分训练测试集 X_train, X_test X[:train_size], X[train_size:] y_train, y_test y[:train_size], y[train_size:] # 调整LSTM输入格式 [样本数, 时间步, 特征数] X_train np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1)) X_test np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))3.2 网络架构设计构建LSTM网络结构这里使用一个相对简单的架构from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential() model.add(LSTM(50, return_sequencesTrue, input_shape(look_back, 1))) model.add(Dropout(0.2)) model.add(LSTM(50)) model.add(Dropout(0.2)) model.add(Dense(1)) model.compile(lossmean_squared_error, optimizeradam) model.summary()3.3 训练与预测训练LSTM模型并进行预测history model.fit(X_train, y_train, epochs50, batch_size32, validation_data(X_test, y_test), verbose1) # 绘制训练过程 plt.plot(history.history[loss], labeltrain) plt.plot(history.history[val_loss], labeltest) plt.legend() plt.show() # 预测 lstm_pred model.predict(X_test) lstm_pred scaler.inverse_transform(lstm_pred) y_test_actual scaler.inverse_transform(y_test.reshape(-1,1)) # 评估 lstm_mae mean_absolute_error(y_test_actual, lstm_pred) print(fLSTM MAE: {lstm_mae:.2f}) # 可视化 test_dates df.index[train_sizelook_back1:] plt.figure(figsize(12,6)) plt.plot(df.index[:train_size], df[meantemp][:train_size], labelTrain) plt.plot(test_dates, y_test_actual, labelTrue) plt.plot(test_dates, lstm_pred, labelLSTM Predict) plt.legend() plt.show()4. 模型对比与选择建议4.1 性能指标对比将两种模型的结果进行系统比较指标ARIMALSTMMAE2.341.78训练时间15秒8分钟参数数量5~50,000解释性高低数据需求少多从MAE看LSTM表现更好但代价是更长的训练时间和更大的计算资源需求。4.2 适用场景分析选择ARIMA当数据量有限需要快速得到初步结果线性趋势和季节性明显模型解释性很重要选择LSTM当有足够的数据和计算资源数据中存在复杂非线性关系预测精度是首要考虑可以接受黑箱模型4.3 改进方向对于ARIMA尝试SARIMA处理季节性加入外生变量如湿度、气压使用更先进的自动ARIMA库如pmdarima对于LSTM调整网络结构和超参数加入注意力机制使用更复杂的架构如ConvLSTM尝试集成学习方法在实际项目中我通常会先使用ARIMA建立基线模型如果效果不理想再尝试LSTM。对于周期性明显的气温数据SARIMA往往能取得不错的效果而LSTM在捕捉突然的温度变化如寒潮时表现更好。