mirror of
https://github.com/wassname/pytorch-ts.git
synced 2026-08-02 13:03:05 +08:00
forecast and predictor
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from .common import DataEntry, FieldName, Dataset
|
||||
from .list_dataset import ListDataset
|
||||
from .loader import TrainDataLoader
|
||||
from .loader import TrainDataLoader, InferenceDataLoader
|
||||
from .sampler import (
|
||||
InstanceSampler,
|
||||
BucketInstanceSampler,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .estimator import Estimator, PTSEstimator
|
||||
from .forecast import Forecast
|
||||
from .forecast import Forecast, SampleForecast, QuantileForecast
|
||||
from .predictor import Predictor
|
||||
from .quantile import Quantile
|
||||
from .utils import get_module_forward_input_names, copy_parameters
|
||||
+71
-72
@@ -322,84 +322,83 @@ class QuantileForecast(Forecast):
|
||||
)
|
||||
|
||||
|
||||
# class DistributionForecast(Forecast):
|
||||
# """
|
||||
# A `Forecast` object that uses a distribution directly.
|
||||
# This can for instance be used to represent marginal probability
|
||||
# distributions for each time point -- although joint distributions are
|
||||
# also possible, e.g. when using MultiVariateGaussian).
|
||||
class DistributionForecast(Forecast):
|
||||
"""
|
||||
A `Forecast` object that uses a distribution directly.
|
||||
This can for instance be used to represent marginal probability
|
||||
distributions for each time point -- although joint distributions are
|
||||
also possible, e.g. when using MultiVariateGaussian).
|
||||
|
||||
# Parameters
|
||||
# ----------
|
||||
# distribution
|
||||
# Distribution object. This should represent the entire prediction
|
||||
# length, i.e., if we draw `num_samples` samples from the distribution,
|
||||
# the sample shape should be
|
||||
Parameters
|
||||
----------
|
||||
distribution
|
||||
Distribution object. This should represent the entire prediction
|
||||
length, i.e., if we draw `num_samples` samples from the distribution,
|
||||
the sample shape should be
|
||||
|
||||
# samples = trans_dist.sample(num_samples)
|
||||
# samples.shape -> (num_samples, prediction_length)
|
||||
samples = trans_dist.sample(num_samples)
|
||||
samples.shape -> (num_samples, prediction_length)
|
||||
|
||||
# start_date
|
||||
# start of the forecast
|
||||
# freq
|
||||
# forecast frequency
|
||||
# info
|
||||
# additional information that the forecaster may provide e.g. estimated
|
||||
# parameters, number of iterations ran etc.
|
||||
# """
|
||||
# @validated()
|
||||
# def __init__(
|
||||
# self,
|
||||
# distribution: Distribution,
|
||||
# start_date,
|
||||
# freq,
|
||||
# item_id: Optional[str] = None,
|
||||
# info: Optional[Dict] = None,
|
||||
# ):
|
||||
# self.distribution = distribution
|
||||
# self.shape = (self.distribution.batch_shape +
|
||||
# self.distribution.event_shape)
|
||||
# self.prediction_length = self.shape[0]
|
||||
# self.item_id = item_id
|
||||
# self.info = info
|
||||
start_date
|
||||
start of the forecast
|
||||
freq
|
||||
forecast frequency
|
||||
info
|
||||
additional information that the forecaster may provide e.g. estimated
|
||||
parameters, number of iterations ran etc.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
distribution: Distribution,
|
||||
start_date,
|
||||
freq,
|
||||
item_id: Optional[str] = None,
|
||||
info: Optional[Dict] = None,
|
||||
):
|
||||
self.distribution = distribution
|
||||
self.shape = (self.distribution.batch_shape +
|
||||
self.distribution.event_shape)
|
||||
self.prediction_length = self.shape[0]
|
||||
self.item_id = item_id
|
||||
self.info = info
|
||||
|
||||
# assert isinstance(
|
||||
# start_date,
|
||||
# pd.Timestamp), "start_date should be a pandas Timestamp object"
|
||||
# self.start_date = start_date
|
||||
assert isinstance(
|
||||
start_date,
|
||||
pd.Timestamp), "start_date should be a pandas Timestamp object"
|
||||
self.start_date = start_date
|
||||
|
||||
# assert isinstance(freq, str), "freq should be a string"
|
||||
# self.freq = freq
|
||||
# self._mean = None
|
||||
assert isinstance(freq, str), "freq should be a string"
|
||||
self.freq = freq
|
||||
self._mean = None
|
||||
|
||||
# @property
|
||||
# def mean(self):
|
||||
# """
|
||||
# Forecast mean.
|
||||
# """
|
||||
# if self._mean is not None:
|
||||
# return self._mean
|
||||
# else:
|
||||
# self._mean = self.distribution.mean.asnumpy()
|
||||
# return self._mean
|
||||
@property
|
||||
def mean(self):
|
||||
"""
|
||||
Forecast mean.
|
||||
"""
|
||||
if self._mean is not None:
|
||||
return self._mean
|
||||
else:
|
||||
self._mean = self.distribution.mean.asnumpy()
|
||||
return self._mean
|
||||
|
||||
# @property
|
||||
# def mean_ts(self):
|
||||
# """
|
||||
# Forecast mean, as a pandas.Series object.
|
||||
# """
|
||||
# return pd.Series(self.index, self.mean)
|
||||
@property
|
||||
def mean_ts(self):
|
||||
"""
|
||||
Forecast mean, as a pandas.Series object.
|
||||
"""
|
||||
return pd.Series(self.index, self.mean)
|
||||
|
||||
# def quantile(self, level):
|
||||
# level = Quantile.parse(level).value
|
||||
# q = self.distribution.quantile(mx.nd.array([level])).asnumpy()[0]
|
||||
# return q
|
||||
def quantile(self, level):
|
||||
level = Quantile.parse(level).value
|
||||
q = self.distribution.quantile(mx.nd.array([level])).asnumpy()[0]
|
||||
return q
|
||||
|
||||
# def to_sample_forecast(self, num_samples: int = 200) -> SampleForecast:
|
||||
# return SampleForecast(
|
||||
# samples=self.distribution.sample(num_samples),
|
||||
# start_date=self.start_date,
|
||||
# freq=self.freq,
|
||||
# item_id=self.item_id,
|
||||
# info=self.info,
|
||||
# )
|
||||
def to_sample_forecast(self, num_samples: int = 200) -> SampleForecast:
|
||||
return SampleForecast(
|
||||
samples=self.distribution.sample(num_samples),
|
||||
start_date=self.start_date,
|
||||
freq=self.freq,
|
||||
item_id=self.item_id,
|
||||
info=self.info,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Callable, Iterator, List, Optional
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
from pts.dataset import InferenceDataLoader, DataEntry
|
||||
from pts.model import Forecast, DistributionForecast
|
||||
from pts.modules import DistributionOutput
|
||||
|
||||
OutputTransform = Callable[[DataEntry, np.ndarray], np.ndarray]
|
||||
|
||||
|
||||
class ForecastGenerator(ABC):
|
||||
"""
|
||||
Classes used to bring the output of a network into a class.
|
||||
"""
|
||||
@abstractmethod
|
||||
def __call__(self,
|
||||
inference_data_loader: InferenceDataLoader,
|
||||
prediction_net: nn.Module,
|
||||
input_names: List[str],
|
||||
freq: str,
|
||||
output_transform: Optional[OutputTransform],
|
||||
num_samples: Optional[int],
|
||||
**kwargs) -> Iterator[Forecast]:
|
||||
pass
|
||||
|
||||
|
||||
class DistributionForecastGenerator(ForecastGenerator):
|
||||
def __init__(self, distr_output: DistributionOutput) -> None:
|
||||
self.distr_output = distr_output
|
||||
|
||||
def __call__(self,
|
||||
inference_data_loader: InferenceDataLoader,
|
||||
prediction_net: nn.Module,
|
||||
input_names: List[str],
|
||||
freq: str,
|
||||
output_transform: Optional[OutputTransform],
|
||||
num_samples: Optional[int],
|
||||
**kwargs) -> Iterator[DistributionForecast]:
|
||||
|
||||
@@ -20,3 +20,5 @@ class Predictor(ABC):
|
||||
|
||||
class PTSPredictor(Predictor):
|
||||
BlockType = nn.Module
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user