You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python ARIMA模型设置500天预测步长仅返回2个有效结果求助

问题描述

大家好:
我正在使用Python构建ARIMA模型,我的数据集包含MasterDate、AREA和QTY三个字段。
代码起始阶段我先对导出的Excel文件做过滤:筛选指定AREA取值的数据,删除GRPCODE列,随后拆分了训练集和验证集。
训练集为MasterDate小于等于2020-12-01的所有历史数据,验证集为MasterDate大于等于2020-11-01的数据,两组数据均按MasterDate分组求和得到,相关核心代码如下:

X_train = df2[df2['MasterDate'] <= '01-12-2020'].groupby(by='MasterDate').sum()
X_train.reset_index(inplace = True)
X_valid = df2[df2['MasterDate'] >= '01-11-2020'].groupby(by='MasterDate').sum()
X_valid.reset_index(inplace = True)

完整代码如下:
我设置ARIMA预测步长为500天,但运行后仅返回2天的有效预测值,其余预测点数值均为134.67,绘图后也只能看到2个预测点,请问是什么原因导致该问题?该如何排查修复?

########################################################################################################
######################################### Packages / libraries #########################################
########################################################################################################
import os                                  #provides functions for interacting with the operating system
import numpy as np 
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns



########################################################################################################
################################################ ARIMA #################################################
########################################################################################################
# To change scientific numbers to float
np.set_printoptions(formatter={'float_kind':'{:f}'.format})

# Increases the size of sns plots
sns.set(rc={'figure.figsize':(8,6)})

from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.api import ExponentialSmoothing, SimpleExpSmoothing, Holt

from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn import linear_model

import pmdarima as pm
from pmdarima.model_selection import train_test_split

from pandas import to_datetime

import itertools
import warnings

import datetime
from datetime import datetime
warnings.filterwarnings('ignore')

########################################################################################################
######################################### Read and Filter CSV ##########################################
########################################################################################################

#Read CSV from Boels shared folders (with check)
df = pd.read_csv (r'\\nlstd116qvs01\QlikView\QDF\99.Shared_Folders\7.Export\B2-371\12098.csv',sep = ';')
print (df) 

df=df.drop(columns=['GRPCODE'])

##Select only AREA's. Scope!
df.loc[df['AREA'].isin(['NL Z5','NL Z1','NL Z2','NL Z3', 'NL Z4'])].to_csv(r'C:\Users\dassej\Documents\Analytics\Eindstage\export_dataframe.csv',index = False, header=True, encoding='utf8')

#Read edited CSV from Boels 
df2 = pd.read_csv (r'C:\Users\dassej\Documents\Analytics\Eindstage\export_dataframe.csv',sep = ',')
print (df2)

df2['MasterDate'] = pd.to_datetime(df2['MasterDate'], format = '%d-%m-%Y')
print(df2)

X_train = df2[df2['MasterDate'] <= '01-12-2020'].groupby(by='MasterDate').sum()
X_train.reset_index(inplace = True)


X_valid = df2[df2['MasterDate'] >= '01-11-2020'].groupby(by='MasterDate').sum()
X_valid.reset_index(inplace = True)


print('X_train Shape', X_train.shape)
print('X_Valid Shape', X_valid.shape)

#X_train['MasterDate'].unique()


# filtering the train data
au = X_train
au2 = au
print(au)

#filtering the valid data
au_v = X_valid
au_v2 = au_v

# set the date into index
au2.set_index('MasterDate', inplace=True)
au_v2.set_index('MasterDate', inplace=True)

# Setting the Index for 6 years
index_3_years = pd.date_range(au_v2.index[-0], freq='D', periods = 500) #500 days


# Running ARIMA with random numbers
model = ARIMA(au2, order=(0,0,1)) 
model_fit = model.fit()

# print summary of fit model
print(model_fit.summary())

# The default is to get a one-step-ahead forecast:
print(model_fit.forecast(steps=5))
fcast1 = model_fit.forecast(steps=500) #500 days forecast

# Saving ARIMA predictions
#fcast1 = model_fit.forecast(7)[0] #-> NOT working
print(fcast1)


# Passing the same index as the others
fcast1 = pd.Series(fcast1, index=index_3_years)
fcast1 = fcast1.rename("Arima") 
print(fcast1)


# Ploting the predictions
fig, ax = plt.subplots(figsize=(15,5))
chart = sns.lineplot(x='MasterDate', y='QTY', data = au)
chart.set_title('AU')
fcast1.plot(ax=ax, color='red', marker="o", legend=True)
au_v2.plot(ax=ax, color='blue', marker="o", legend=True)
plt.show()

#Printing the AI
print('The MSE of ARIMA is:', mean_squared_error(au_v['QTY'].values, fcast1.values, squared=False))

问题原因

  1. ARIMA阶数设置不合理:你手动指定的order=(0,0,1)属于1阶移动平均模型(MA(1)),该模型的固有属性是仅能输出1步有效预测,超过1步的预测值会直接收敛到训练集序列的均值,也就是你看到的固定值134.67,这是模型特性,不是代码运行错误。
  2. 时间序列不连续:你对原始数据按MasterDate分组求和时,没有补全无数据的日期,训练集和验证集的时间序列都是非连续的,导致500个预测值中只有2个日期和实际的验证集日期匹配,绘图时自然只显示2个有效点。
  3. 预测索引对齐错误:你生成预测序列的索引起始是验证集的第一个日期,而训练集的结束日期是2020-12-01,预测的起始日期应该是训练集结束后的第一天,否则预测值和实际值的日期错位,也会导致有效匹配的点极少。

修复步骤

  1. 补全时间序列的连续日期,将索引设置为日度频率,缺失值填0:
# 在set_index之后添加该行,把au2转为连续日度序列
au2 = au2.asfreq('D', fill_value=0)
  1. 用pmdarima的auto_arima自动选择最优ARIMA阶数,代替手动指定的不合理阶数:
# 替换原来的ARIMA初始化代码
model = pm.auto_arima(au2['QTY'], seasonal=False, suppress_warnings=True)
model_fit = model.fit(au2['QTY'])
  1. 修正预测索引的起始日期,和训练集的结束日期衔接:
# 替换原来的index_3_years生成逻辑
index_500_days = pd.date_range(start=au2.index.max() + pd.Timedelta(days=1), freq='D', periods=500)
  1. 计算MSE时只取预测值和验证集重叠的日期对应的值,避免维度不匹配:
# 取两个序列的交集日期计算误差
common_idx = fcast1.index.intersection(au_v2.index)
rmse = mean_squared_error(au_v2.loc[common_idx, 'QTY'], fcast1.loc[common_idx], squared=False)
print('The RMSE of ARIMA is:', rmse)

内容的提问来源于stack exchange,提问作者Jesse Boels

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:45:04