【问题标题】:Export multiple GluonTS forecasts to pandas dataframe将多个 GluonTS 预测导出到 pandas 数据框
【发布时间】:2020-08-08 12:47:38
【问题描述】:

我有多个时间序列,我想用GluonTS 进行预测,然后连接,所以我的结果是一个带有列标题datey(目标)、series(系列号)。

问题在于 GluonTS 生成了一个生成器。我可以使用next(iter(forecast_id)) 查看每个系列,但我想将所有预测叠加在一起,以便更容易导出为 csv。

如何将所有系列的预测叠加到一个 pandas 数据框中?

import pandas as pd 
import numpy as np 
import mxnet as mx
from mxnet import gluon
from gluonts.dataset import common
from gluonts.model.baseline import SeasonalNaivePredictor
from gluonts.trainer import Trainer
from gluonts.evaluation.backtest import make_evaluation_predictions
from gluonts.dataset.util import to_pandas

N = 10  # number of time series
T = 100  # number of timesteps
prediction_length = 24
custom_dataset = np.random.normal(size=(N, T))
start = pd.Timestamp("01-01-2019", freq='1H') 

# train dataset: cut the last window of length "prediction_length", add "target" and "start" fields
train_ds = [{'target': x, 'start': start} for x in custom_dataset[:, :-prediction_length]]
# test dataset: use the whole dataset, add "target" and "start" fields
test_ds = [{'target': x, 'start': start} for x in custom_dataset]

predictor = SeasonalNaivePredictor(
    prediction_length=prediction_length,
    season_length=24,
    freq='1H'
)

forecast_it, ts_it = make_evaluation_predictions(
    dataset=test_ds,  # test dataset
    predictor=predictor,  # predictor
    num_samples=100,  # number of sample paths we want for evaluation
)

test_entry = next(iter(forecast_it))
print(test_entry)
> gluonts.model.forecast.SampleForecast(freq="1H", info=None, item_id=None, samples=numpy.array([[-1.078548550605774, 0.3002452254295349, 0.1025903970003128, -1.6613410711288452, -0.2776057720184326, -0.020864564925432205, -1.9355241060256958, 1.0598571300506592, 0.16316552460193634, -0.9441472887992859, 2.7307169437408447, -0.35861697793006897, 0.22022956609725952, 0.8052476048469543, -1.1194337606430054, 0.05703512206673622, -1.1357367038726807, -2.544445037841797, 1.2661969661712646, 0.17130693793296814, 0.8647393584251404, -1.9620181322097778, -0.5465423464775085, 0.26572829484939575]], numpy.dtype("float32")), start_date=pandas.Timestamp("2019-01-04 04:00:00", freq="H"))

【问题讨论】:

  • 如果你能显示print(test_entry)的输出将会有很大帮助。

标签: python pandas numpy time-series


【解决方案1】:

你可以像这样解压一个条目:

def sample_df(forecast):
    samples = forecast.samples
    ns, h = samples.shape
    dates = pd.date_range(forecast.start_date, freq=forecast.freq, periods=h)
    return pd.DataFrame(samples.T, index=dates)

这只是从SampleForecast 中获取各种属性。

它以预测 samples 开头,ndarray 每个样本一行,每个时间段一列。列数给出了预测范围h,可以将start_datefreq 属性赋予pd.date_range 以构造预测dates

然后samples 被转置,每个时间段给出一行,每个样本给出一列。这可以使用重构的dates 进行索引,并且您已准备好接受一个样本。

sample_df(test_entry)
#                             0
# 2019-01-04 04:00:00  0.748107
# 2019-01-04 05:00:00  1.620660
# 2019-01-04 06:00:00 -0.648520
# 2019-01-04 07:00:00  0.277669
# 2019-01-04 08:00:00 -1.010820
# ...

要处理所有结果,您可以在每个DataFrame 上独立运行此方法,并将它们与pd.concat 放在一起。

parts = [sample_df(entry).assign(entry=i)
         for i, entry in enumerate(forecast_it)]
pd.concat(parts)
#                             0  entry
# 2019-01-04 04:00:00  0.748107      0
# 2019-01-04 05:00:00  1.620660      0
# 2019-01-04 06:00:00 -0.648520      0
# 2019-01-04 07:00:00  0.277669      0
# 2019-01-04 08:00:00 -1.010820      0
# ...                       ...    ...
# 2019-01-04 23:00:00  0.999718      9
# 2019-01-05 00:00:00  0.027250      9
# 2019-01-05 01:00:00  2.030961      9
# 2019-01-05 02:00:00 -1.414711      9
# 2019-01-05 03:00:00  0.737124      9

这还会用entry 标记每个DataFrame,以标记它来自哪个预测结果。

您还可以使用pd.DataFrame.melt 将每个样本一列转换为带有一列来标识样本的长格式。最后的一些重命名可以使一切变得漂亮,以供以后分析。

long_form = pd.concat(parts).reset_index().melt(['index', 'entry'])
long_form.rename(columns={
    'index': 'ts',
    'variable': 'sample',
    'value': 'forecast',
})
#                      ts  entry sample     value
# 0   2019-01-04 04:00:00      0      0  0.748107
# 1   2019-01-04 05:00:00      0      0  1.620660
# 2   2019-01-04 06:00:00      0      0 -0.648520
# 3   2019-01-04 07:00:00      0      0  0.277669
# 4   2019-01-04 08:00:00      0      0 -1.010820
# ..                  ...    ...    ...       ...
# 235 2019-01-04 23:00:00      9      0  0.999718
# 236 2019-01-05 00:00:00      9      0  0.027250
# 237 2019-01-05 01:00:00      9      0  2.030961
# 238 2019-01-05 02:00:00      9      0 -1.414711
# 239 2019-01-05 03:00:00      9      0  0.737124

注意:此代码适用于任意数量的样本,为每个样本(或长格式的行)提供一列。但是这里的结果只有一个样本。什么给了?

我通读了相关代码,RepresentablePredictor 基类只会生成一个样本,无论您向make_evaluation_predictions 提出什么要求。参数永远不会传递。这个基类用于非 Gluon 预测方法,所以我猜他们只是希望那些是非随机的并且只适合生成单个示例。或者这是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    相关资源
    最近更新 更多