如何在AutoGluon中处理多item_id不等长时序数据以实现预测
我正在构建模型,基于数千只股票的日度数据预测每日股价。数据中各股票的日度数据长度不同:部分股票拥有2000至2022年的数据,其他股票仅包含2010至2022年的数据,且多只股票的日期存在大量重复。
学习AutoGluon时,我曾用以下函数格式化时序数据适配.fit()方法:
def forward_fill_missing(ts_dataframe: TimeSeriesDataFrame, freq="D") -> TimeSeriesDataFrame: original_index = ts_dataframe.index.get_level_values("timestamp") start = original_index[0] end = original_index[-1] filled_index = pd.date_range(start=start, end=end, freq=freq, name="timestamp") return ts_dataframe.droplevel("item_id").reindex(filled_index, method="ffill") ts_dataframe = ts_dataframe.groupby("item_id").apply(forward_fill_missing)
处理单个item_id时有效,但处理数千个时报错:ValueError: cannot reindex from a duplicate axis。
我已用pandas做了前向填充,按道理ts_dataframe不应有缺失日期或值,但调用.fit()时仍报错:
ValueError: Frequency not provided and cannot be inferred. This is often due to the time index of the data being irregularly sampled. Please ensure that the data set used has a uniform time index, or create the TimeSeriesPredictorsettingignore_time_index=True.
我推测是只填充了缺失数据和日期,没考虑各股票数据时长不同的问题。以下是我用pandas格式化数据的代码:
df = pd.read_csv( "/content/drive/MyDrive/stock_data/training_data.csv", parse_dates=["Date"], ) df["Date"] = pd.to_datetime(df["Date"], errors="coerce", dayfirst=True) df.fillna(method='ffill', inplace=True) df = df.drop("Unnamed: 0", axis=1) df[:11]
请问如何格式化数据才能适配.fit()方法?
1. 修复批量处理item_id的重复轴问题
原函数在groupby.apply后丢失item_id层级,导致合并时索引重复。修改填充逻辑,确保每只股票处理后保留完整的标识列与连续日期:
def forward_fill_missing(group: pd.DataFrame, freq="D") -> pd.DataFrame: # 单只股票数据处理:设置日期为索引 group = group.set_index("Date") # 生成该股票时间范围内的完整日度序列 full_date_range = pd.date_range(start=group.index.min(), end=group.index.max(), freq=freq) # 重新索引并前向填充,恢复item_id列 filled_group = group.reindex(full_date_range, method="ffill") filled_group["item_id"] = group["item_id"].iloc[0] filled_group = filled_group.reset_index().rename(columns={"index": "Date"}) return filled_group # 按item_id分组批量处理 filled_df = df.groupby("item_id", group_keys=False).apply(forward_fill_missing)
2. 转换为AutoGluon兼容的时序格式
处理后的数据需要转换为TimeSeriesDataFrame,并显式指定日度频率,避免AutoGluon无法自动推断:
from autogluon.timeseries import TimeSeriesDataFrame # 转换为AutoGluon要求的格式,指定标识列与时间戳列 ts_dataframe = TimeSeriesDataFrame( filled_df, id_column="item_id", timestamp_column="Date" ) # 强制设置数据频率为日度 ts_dataframe.freq = "D"
3. 验证数据有效性
处理后可检查单只股票的时间序列是否连续:
# 随机选取5只股票验证日期间隔 sample_items = ts_dataframe.index.get_level_values("item_id").unique()[:5] for item in sample_items: item_data = ts_dataframe.loc[item] date_diff = item_data.index.to_series().diff().dropna().unique() print(f"股票{item}的日期间隔: {date_diff}")
若输出均为1 days,说明单只股票的时间序列是均匀日度采样,符合要求。
4. 兜底方案:初始化预测器时显式指定频率
如果仍有频率推断问题,初始化TimeSeriesPredictor时直接声明频率:
from autogluon.timeseries import TimeSeriesPredictor predictor = TimeSeriesPredictor( target="your_target_column", # 替换为你的预测目标列名 prediction_length=7, # 根据需求调整预测天数 freq="D" # 明确指定日度频率 ) predictor.fit(ts_dataframe)
内容的提问来源于stack exchange,提问作者ethereumboy

