Beispiel #1
0
 def create_transformation(self) -> Transformation:
     return AsNumpyArray(field=FieldName.TARGET,
                         expected_ndim=2,
                         dtype=self.dtype) + AddObservedValuesIndicator(
                             target_field=FieldName.TARGET,
                             output_field=FieldName.OBSERVED_VALUES,
                             dtype=self.dtype,
                         )
    def create_transformation(self) -> Transformation:
        remove_field_names = [FieldName.FEAT_DYNAMIC_CAT]
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)
        if not self.use_feat_static_real:
            remove_field_names.append(FieldName.FEAT_STATIC_REAL)

        return Chain([RemoveFields(field_names=remove_field_names)] + (
            [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0]
                      )] if not self.use_feat_static_cat else []
        ) + ([SetField(
            output_field=FieldName.FEAT_STATIC_REAL, value=[0.0]
        )] if not self.use_feat_static_real else []) + [
            AsNumpyArray(
                field=FieldName
                .TARGET,
                expected_ndim=1 +
                len(self.distr_output
                    .event_shape),
            ),
            # maps the target to (1, T)
            # if the target data is uni dimensional
            ExpandDimArray(
                field=FieldName.TARGET,
                axis=0 if self.distr_output.event_shape[0] == 1 else None,
            ),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=self.time_features,
                pred_length=self.prediction_length,
            ),
            AddAgeFeature(
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_AGE,
                pred_length=self.prediction_length,
                log_scale=True,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_TIME,
                input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE] +
                ([FieldName.FEAT_DYNAMIC_REAL] if self.
                 use_feat_dynamic_real else []),
            ),
            TargetDimIndicator(
                field_name="target_dimension_indicator",
                target_field=FieldName.TARGET,
            ),
            AsNumpyArray(field=FieldName.FEAT_STATIC_CAT,
                         expected_ndim=1,
                         dtype=np.long),
            AsNumpyArray(field=FieldName.FEAT_STATIC_REAL, expected_ndim=1),
        ])
def test_simple_model():
    dsinfo, training_data, test_data = default_synthetic()

    freq = dsinfo.metadata.freq
    prediction_length = dsinfo.prediction_length
    context_length = 2 * prediction_length
    hidden_dimensions = [10, 10]

    net = LightningFeedForwardNetwork(
        freq=freq,
        prediction_length=prediction_length,
        context_length=context_length,
        hidden_dimensions=hidden_dimensions,
        distr_output=NormalOutput(),
        batch_norm=True,
        scaling=mean_abs_scaling,
    )

    transformation = Chain([
        AddObservedValuesIndicator(
            target_field=FieldName.TARGET,
            output_field=FieldName.OBSERVED_VALUES,
        ),
        InstanceSplitter(
            target_field=FieldName.TARGET,
            is_pad_field=FieldName.IS_PAD,
            start_field=FieldName.START,
            forecast_start_field=FieldName.FORECAST_START,
            train_sampler=ExpectedNumInstanceSampler(num_instances=1),
            past_length=context_length,
            future_length=prediction_length,
            time_series_fields=[FieldName.OBSERVED_VALUES],
        ),
    ])

    data_loader = TrainDataLoader(
        training_data,
        batch_size=8,
        stack_fn=batchify,
        transform=transformation,
        num_batches_per_epoch=5,
    )

    trainer = pl.Trainer(max_epochs=3, callbacks=[], weights_summary=None)
    trainer.fit(net, train_dataloader=data_loader)

    predictor = net.get_predictor(transformation)

    forecast_it, ts_it = make_evaluation_predictions(
        dataset=test_data,
        predictor=predictor,
        num_samples=100,
    )

    evaluator = Evaluator(quantiles=[0.5, 0.9], num_workers=None)

    agg_metrics, _ = evaluator(ts_it, forecast_it)
Beispiel #4
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [FieldName.FEAT_DYNAMIC_CAT]
        if not self.use_feat_static_real:
            remove_field_names.append(FieldName.FEAT_STATIC_REAL)
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain(
            [RemoveFields(field_names=remove_field_names)] +
            ([SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0]
                       )] if not self.use_feat_static_cat else []) +
            ([SetField(output_field=FieldName.FEAT_STATIC_REAL, value=[0.0]
                       )] if not self.use_feat_static_real else []) +
            [
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_CAT,
                    expected_ndim=1,
                    dtype=self.dtype,
                ),
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_REAL,
                    expected_ndim=1,
                    dtype=self.dtype,
                ),
                AsNumpyArray(
                    field=FieldName.TARGET,
                    # in the following line, we add 1 for the time dimension
                    expected_ndim=1 + len(self.distr_output.event_shape),
                    dtype=self.dtype,
                ),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                    dtype=self.dtype,
                    imputation_method=self.imputation_method,
                ),
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=self.time_features,
                    pred_length=self.prediction_length,
                ),
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    log_scale=True,
                    dtype=self.dtype,
                ),
                VstackFeatures(
                    output_field=FieldName.FEAT_TIME,
                    input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE] +
                    ([FieldName.FEAT_DYNAMIC_REAL] if self.
                     use_feat_dynamic_real else []),
                ),
            ])
Beispiel #5
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain(
            [RemoveFields(field_names=remove_field_names)] +
            ([SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0]
                       )] if not self.use_feat_static_cat else []) +
            [
                AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
                AsNumpyArray(
                    field=FieldName.TARGET,
                    # in the following line, we add 1 for the time dimension
                    expected_ndim=1 + len(self.distr_output.event_shape),
                ),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                ),
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=self.time_features,
                    pred_length=self.prediction_length,
                ),
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    log_scale=True,
                ),
                VstackFeatures(
                    output_field=FieldName.FEAT_TIME,
                    input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE] +
                    ([FieldName.FEAT_DYNAMIC_REAL] if self.
                     use_feat_dynamic_real else []),
                ),
                InstanceSplitter(
                    target_field=FieldName.TARGET,
                    is_pad_field=FieldName.IS_PAD,
                    start_field=FieldName.START,
                    forecast_start_field=FieldName.FORECAST_START,
                    train_sampler=ExpectedNumInstanceSampler(num_instances=1),
                    past_length=self.history_length,
                    future_length=self.prediction_length,
                    time_series_fields=[
                        FieldName.FEAT_TIME,
                        FieldName.OBSERVED_VALUES,
                    ],
                ),
            ])
Beispiel #6
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain(
            [RemoveFields(field_names=remove_field_names)]
            + (
                [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0])]
                if not self.use_feat_static_cat
                else []
            )
            + [
                AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
                AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
                # gives target the (1, T) layout
                ExpandDimArray(field=FieldName.TARGET, axis=0),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                ),
                # Unnormalized seasonal features
                AddTimeFeatures(
                    time_features=self.issm.time_features(),
                    pred_length=self.prediction_length,
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=SEASON_INDICATORS_FIELD,
                ),
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=self.time_features,
                    pred_length=self.prediction_length,
                ),
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    log_scale=True,
                ),
                VstackFeatures(
                    output_field=FieldName.FEAT_TIME,
                    input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]
                    + (
                        [FieldName.FEAT_DYNAMIC_REAL]
                        if self.use_feat_dynamic_real
                        else []
                    ),
                ),
            ]
        )
Beispiel #7
0
 def create_transformation(self) -> Transformation:
     return Chain([
         RemoveFields(field_names=[
             FieldName.FEAT_STATIC_REAL,
             FieldName.FEAT_DYNAMIC_REAL,
             FieldName.FEAT_DYNAMIC_CAT,
         ]),
         AddObservedValuesIndicator(
             target_field=FieldName.TARGET,
             output_field=FieldName.OBSERVED_VALUES,
             dtype=self.dtype,
         ),
     ])
Beispiel #8
0
 def create_transformation(
     self, bin_edges: np.ndarray, pred_length: int
 ) -> transform.Transformation:
     return Chain(
         [
             AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
             AddObservedValuesIndicator(
                 target_field=FieldName.TARGET,
                 output_field=FieldName.OBSERVED_VALUES,
             ),
             AddTimeFeatures(
                 start_field=FieldName.START,
                 target_field=FieldName.TARGET,
                 output_field=FieldName.FEAT_TIME,
                 time_features=time_features_from_frequency_str(self.freq),
                 pred_length=self.prediction_length,
             ),
             AddAgeFeature(
                 target_field=FieldName.TARGET,
                 output_field=FieldName.FEAT_AGE,
                 pred_length=self.prediction_length,
             ),
             VstackFeatures(
                 output_field=FieldName.FEAT_TIME,
                 input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE],
             ),
             SetFieldIfNotPresent(
                 field=FieldName.FEAT_STATIC_CAT, value=[0.0]
             ),
             AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
             InstanceSplitter(
                 target_field=FieldName.TARGET,
                 is_pad_field=FieldName.IS_PAD,
                 start_field=FieldName.START,
                 forecast_start_field=FieldName.FORECAST_START,
                 train_sampler=ExpectedNumInstanceSampler(num_instances=1),
                 past_length=self.context_length,
                 future_length=pred_length,
                 output_NTC=False,
                 time_series_fields=[
                     FieldName.FEAT_TIME,
                     FieldName.OBSERVED_VALUES,
                 ],
             ),
             QuantizeScaled(
                 bin_edges=bin_edges.tolist(),
                 future_target="future_target",
                 past_target="past_target",
             ),
         ]
     )
Beispiel #9
0
 def create_transformation(self) -> Transformation:
     mask_unobserved = AddObservedValuesIndicator(
         target_field=FieldName.TARGET,
         output_field=FieldName.OBSERVED_VALUES,
     )
     add_age_feature = AddAgeFeature(
         target_field=FieldName.TARGET,
         output_field=FieldName.FEAT_AGE,
         pred_length=self.prediction_length,
         log_scale=True,
     )
     concat_feature = ConcatFeatures(output_field="exog",
                                     input_fields=[FieldName.FEAT_AGE],
                                     drop_inputs=True)
     return mask_unobserved + add_age_feature + concat_feature
Beispiel #10
0
 def create_transformation(self) -> Transformation:
     return Chain([
         AddObservedValuesIndicator(
             target_field=FieldName.TARGET,
             output_field=FieldName.OBSERVED_VALUES,
             dtype=self.dtype,
         ),
         InstanceSplitter(
             target_field=FieldName.TARGET,
             is_pad_field=FieldName.IS_PAD,
             start_field=FieldName.START,
             forecast_start_field=FieldName.FORECAST_START,
             train_sampler=self.train_sampler,
             past_length=self.context_length,
             future_length=self.prediction_length,
             time_series_fields=[FieldName.OBSERVED_VALUES],
         ),
     ])
Beispiel #11
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [FieldName.FEAT_DYNAMIC_CAT]
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain([
            RemoveFields(field_names=remove_field_names),
            AsNumpyArray(
                field=FieldName.TARGET,
                expected_ndim=2,
            ),
            # maps the target to (1, T)
            # if the target data is uni dimensional
            ExpandDimArray(
                field=FieldName.TARGET,
                axis=None,
            ),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=self.time_features,
                pred_length=self.prediction_length,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_TIME,
                input_fields=[FieldName.FEAT_TIME] +
                ([FieldName.FEAT_DYNAMIC_REAL]
                 if self.use_feat_dynamic_real else []),
            ),
            SetFieldIfNotPresent(field=FieldName.FEAT_STATIC_CAT, value=[0]),
            TargetDimIndicator(
                field_name="target_dimension_indicator",
                target_field=FieldName.TARGET,
            ),
            AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
        ])
Beispiel #12
0
 def create_transformation(self) -> Transformation:
     return Chain(trans=[
         AsNumpyArray(
             field=FieldName.TARGET, expected_ndim=2, dtype=self.dtype),
         AddObservedValuesIndicator(
             target_field=FieldName.TARGET,
             output_field=FieldName.OBSERVED_VALUES,
             dtype=self.dtype,
         ),
         InstanceSplitter(
             target_field=FieldName.TARGET,
             is_pad_field=FieldName.IS_PAD,
             start_field=FieldName.START,
             forecast_start_field=FieldName.FORECAST_START,
             train_sampler=ExpectedNumInstanceSampler(num_instances=1),
             time_series_fields=[FieldName.OBSERVED_VALUES],
             past_length=self.context_length,
             future_length=self.future_length,
             output_NTC=False,  # output NCT for first layer conv1d
         ),
     ])
Beispiel #13
0
 def create_transformation(self) -> Transformation:
     return Chain(
         [
             AsNumpyArray(
                 field=FieldName.TARGET,
                 expected_ndim=1 + len(self.distr_output.event_shape),
             ),
             # maps the target to (1, T) if the target data is uni
             # dimensional
             ExpandDimArray(
                 field=FieldName.TARGET,
                 axis=0 if self.distr_output.event_shape[0] == 1 else None,
             ),
             AddObservedValuesIndicator(
                 target_field=FieldName.TARGET,
                 output_field=FieldName.OBSERVED_VALUES,
             ),
             AddTimeFeatures(
                 start_field=FieldName.START,
                 target_field=FieldName.TARGET,
                 output_field=FieldName.FEAT_TIME,
                 time_features=self.time_features,
                 pred_length=self.prediction_length,
             ),
             VstackFeatures(
                 output_field=FieldName.FEAT_TIME,
                 input_fields=[FieldName.FEAT_TIME],
             ),
             SetFieldIfNotPresent(
                 field=FieldName.FEAT_STATIC_CAT, value=[0.0]
             ),
             TargetDimIndicator(
                 field_name=FieldName.TARGET_DIM_INDICATOR,
                 target_field=FieldName.TARGET,
             ),
             AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
         ]
     )
Beispiel #14
0
 def create_transformation(self) -> Transformation:
     return AddObservedValuesIndicator(
         target_field=FieldName.TARGET,
         output_field=FieldName.OBSERVED_VALUES,
         dtype=self.dtype,
     )
Beispiel #15
0
    def create_transformation(self) -> Transformation:
        chain = []
        dynamic_feat_fields = []
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]

        # --- GENERAL TRANSFORMATION CHAIN ---

        # determine unused input
        if not self.use_past_feat_dynamic_real:
            remove_field_names.append(FieldName.PAST_FEAT_DYNAMIC_REAL)
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)
        if not self.use_feat_static_cat:
            remove_field_names.append(FieldName.FEAT_STATIC_CAT)

        chain.extend(
            [
                RemoveFields(field_names=remove_field_names),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                    dtype=self.dtype,
                ),
            ]
        )

        # --- TRANSFORMATION CHAIN FOR DYNAMIC FEATURES ---

        if self.add_time_feature:
            chain.append(
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=time_features_from_frequency_str(self.freq),
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_TIME)

        if self.add_age_feature:
            chain.append(
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_AGE)

        if self.use_feat_dynamic_real:
            # Backwards compatibility:
            chain.append(
                RenameFields({"dynamic_feat": FieldName.FEAT_DYNAMIC_REAL})
            )
            dynamic_feat_fields.append(FieldName.FEAT_DYNAMIC_REAL)

        # we need to make sure that there is always some dynamic input
        # we will however disregard it in the hybrid forward.
        # the time feature is empty for yearly freq so also adding a dummy feature
        # in the case that the time feature is the only one on
        if len(dynamic_feat_fields) == 0 or (
            not self.add_age_feature
            and not self.use_feat_dynamic_real
            and self.freq == "Y"
        ):
            chain.append(
                AddConstFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_CONST,
                    pred_length=self.prediction_length,
                    const=0.0,  # For consistency in case with no dynamic features
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_CONST)

        # now we map all the dynamic input of length context_length + prediction_length onto FieldName.FEAT_DYNAMIC
        # we exclude past_feat_dynamic_real since its length is only context_length
        if len(dynamic_feat_fields) > 1:
            chain.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_DYNAMIC,
                    input_fields=dynamic_feat_fields,
                )
            )
        elif len(dynamic_feat_fields) == 1:
            chain.append(
                RenameFields({dynamic_feat_fields[0]: FieldName.FEAT_DYNAMIC})
            )

        # --- TRANSFORMATION CHAIN FOR STATIC FEATURES ---

        if not self.use_feat_static_cat:
            chain.append(
                SetField(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    value=np.array([0], dtype=np.int32),
                )
            )

        # --- SAMPLE AND CUT THE TIME-SERIES ---

        chain.append(
            # because of how the forking decoder works, every time step
            # in context is used for splitting, which is why we use the TestSplitSampler
            ForkingSequenceSplitter(
                train_sampler=TestSplitSampler(),
                enc_len=self.context_length,
                dec_len=self.prediction_length,
                num_forking=self.num_forking,
                encoder_series_fields=[
                    FieldName.OBSERVED_VALUES,
                    # RTS with past and future values which is never empty because added dummy constant variable
                    FieldName.FEAT_DYNAMIC,
                ]
                + (
                    # RTS with only past values are only used by the encoder
                    [FieldName.PAST_FEAT_DYNAMIC_REAL]
                    if self.use_past_feat_dynamic_real
                    else []
                ),
                encoder_disabled_fields=(
                    [FieldName.FEAT_DYNAMIC]
                    if not self.enable_encoder_dynamic_feature
                    else []
                )
                + (
                    [FieldName.PAST_FEAT_DYNAMIC_REAL]
                    if not self.enable_encoder_dynamic_feature
                    and self.use_past_feat_dynamic_real
                    else []
                ),
                decoder_series_fields=[
                    FieldName.OBSERVED_VALUES,
                    # Decoder will use all fields under FEAT_DYNAMIC which are the RTS with past and future values
                    FieldName.FEAT_DYNAMIC,
                ],
                decoder_disabled_fields=(
                    [FieldName.FEAT_DYNAMIC]
                    if not self.enable_decoder_dynamic_feature
                    else []
                ),
                prediction_time_decoder_exclude=[FieldName.OBSERVED_VALUES],
            )
        )

        # past_feat_dynamic features generated above in ForkingSequenceSplitter from those under feat_dynamic - we need
        # to stack with the other short related time series from the system labeled as past_past_feat_dynamic_real.
        # The system labels them as past_feat_dynamic_real and the additional past_ is added to the string
        # in the ForkingSequenceSplitter
        if self.use_past_feat_dynamic_real:
            # Stack features from ForkingSequenceSplitter horizontally since they were transposed
            # so shape is now (enc_len, num_past_feature_dynamic)
            chain.append(
                VstackFeatures(
                    output_field=FieldName.PAST_FEAT_DYNAMIC,
                    input_fields=[
                        "past_" + FieldName.PAST_FEAT_DYNAMIC_REAL,
                        FieldName.PAST_FEAT_DYNAMIC,
                    ],
                    h_stack=True,
                )
            )

        return Chain(chain)
    def create_transformation(self) -> Transformation:
        chain = []
        dynamic_feat_fields = []
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]

        # --- GENERAL TRANSFORMATION CHAIN ---

        # determine unused input
        if not self.use_past_feat_dynamic_real:
            remove_field_names.append(FieldName.PAST_FEAT_DYNAMIC_REAL)
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)
        if not self.use_feat_static_cat:
            remove_field_names.append(FieldName.FEAT_STATIC_CAT)

        chain.extend(
            [
                RemoveFields(field_names=remove_field_names),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                    dtype=self.dtype,
                ),
            ]
        )

        # --- TRANSFORMATION CHAIN FOR DYNAMIC FEATURES ---

        if self.add_time_feature:
            chain.append(
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=time_features_from_frequency_str(self.freq),
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_TIME)

        if self.add_age_feature:
            chain.append(
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_AGE)

        if self.use_feat_dynamic_real:
            # Backwards compatibility:
            chain.append(
                RenameFields({"dynamic_feat": FieldName.FEAT_DYNAMIC_REAL})
            )
            dynamic_feat_fields.append(FieldName.FEAT_DYNAMIC_REAL)

        # we need to make sure that there is always some dynamic input
        # we will however disregard it in the hybrid forward.
        # the time feature is empty for yearly freq so also adding a dummy feature
        # in the case that the time feature is the only one on
        if len(dynamic_feat_fields) == 0 or (
            not self.add_age_feature
            and not self.use_feat_dynamic_real
            and self.freq == "Y"
        ):
            chain.append(
                AddConstFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_CONST,
                    pred_length=self.prediction_length,
                    const=0.0,  # For consistency in case with no dynamic features
                    dtype=self.dtype,
                )
            )
            dynamic_feat_fields.append(FieldName.FEAT_CONST)

        # now we map all the dynamic input of length context_length + prediction_length onto FieldName.FEAT_DYNAMIC
        # we exclude past_feat_dynamic_real since its length is only context_length
        if len(dynamic_feat_fields) > 1:
            chain.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_DYNAMIC,
                    input_fields=dynamic_feat_fields,
                )
            )
        elif len(dynamic_feat_fields) == 1:
            chain.append(
                RenameFields({dynamic_feat_fields[0]: FieldName.FEAT_DYNAMIC})
            )

        # --- TRANSFORMATION CHAIN FOR STATIC FEATURES ---

        if not self.use_feat_static_cat:
            chain.append(
                SetField(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    value=np.array([0], dtype=np.int32),
                )
            )

        return Chain(chain)
Beispiel #17
0
    def create_transformation(self) -> Transformation:
        def use_marginal_transformation(
            marginal_transformation: bool, ) -> Transformation:
            if marginal_transformation:
                return CDFtoGaussianTransform(
                    target_field=FieldName.TARGET,
                    observed_values_field=FieldName.OBSERVED_VALUES,
                    max_context_length=self.conditioning_length,
                    target_dim=self.target_dim,
                )
            else:
                return RenameFields({
                    f"past_{FieldName.TARGET}":
                    f"past_{FieldName.TARGET}_cdf",
                    f"future_{FieldName.TARGET}":
                    f"future_{FieldName.TARGET}_cdf",
                })

        return Chain([
            AsNumpyArray(
                field=FieldName.TARGET,
                expected_ndim=1 + len(self.distr_output.event_shape),
            ),
            # maps the target to (1, T) if the target data is uni
            # dimensional
            ExpandDimArray(
                field=FieldName.TARGET,
                axis=0 if self.distr_output.event_shape[0] == 1 else None,
            ),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=self.time_features,
                pred_length=self.prediction_length,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_TIME,
                input_fields=[FieldName.FEAT_TIME],
            ),
            SetFieldIfNotPresent(field=FieldName.FEAT_STATIC_CAT, value=[0.0]),
            TargetDimIndicator(
                field_name=FieldName.TARGET_DIM_INDICATOR,
                target_field=FieldName.TARGET,
            ),
            AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
            InstanceSplitter(
                target_field=FieldName.TARGET,
                is_pad_field=FieldName.IS_PAD,
                start_field=FieldName.START,
                forecast_start_field=FieldName.FORECAST_START,
                train_sampler=ExpectedNumInstanceSampler(num_instances=1),
                past_length=self.history_length,
                future_length=self.prediction_length,
                time_series_fields=[
                    FieldName.FEAT_TIME,
                    FieldName.OBSERVED_VALUES,
                ],
                pick_incomplete=self.pick_incomplete,
            ),
            use_marginal_transformation(self.use_marginal_transformation),
            SampleTargetDim(
                field_name=FieldName.TARGET_DIM_INDICATOR,
                target_field=FieldName.TARGET + "_cdf",
                observed_values_field=FieldName.OBSERVED_VALUES,
                num_samples=self.target_dim_sample,
                shuffle=self.shuffle_target_dim,
            ),
        ])
Beispiel #18
0
    def create_transformation(self) -> Transformation:
        transforms = []
        if self.use_feat_dynamic_real:
            transforms.append(
                AsNumpyArray(
                    field=FieldName.FEAT_DYNAMIC_REAL,
                    expected_ndim=2,
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_DYNAMIC_REAL,
                    value=[[]] *
                    (self.context_length + self.prediction_length),
                ),
                AsNumpyArray(
                    field=FieldName.FEAT_DYNAMIC_REAL,
                    expected_ndim=2,
                ),
                # SwapAxes(input_fields=[FieldName.FEAT_DYNAMIC_REAL], axes=(0,1)),
            ])
        if self.use_feat_dynamic_cat:
            transforms.append(
                AsNumpyArray(
                    field=FieldName.FEAT_DYNAMIC_CAT,
                    expected_ndim=2,
                ))
        else:
            # Manually set dummy dynamic categorical features and split by time
            # Unknown issue in dataloader if leave splitting to InstanceSplitter
            transforms.extend([
                SetField(
                    output_field="past_" + FieldName.FEAT_DYNAMIC_CAT,
                    value=[[]] * self.context_length,
                ),
                AsNumpyArray(
                    field="past_" + FieldName.FEAT_DYNAMIC_CAT,
                    expected_ndim=2,
                ),
                SetField(
                    output_field="future_" + FieldName.FEAT_DYNAMIC_CAT,
                    value=[[]] * self.prediction_length,
                ),
                AsNumpyArray(
                    field="future_" + FieldName.FEAT_DYNAMIC_CAT,
                    expected_ndim=2,
                ),
            ])
        if self.use_feat_static_real:
            transforms.append(
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_REAL,
                    expected_ndim=1,
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_STATIC_REAL,
                    value=[],
                ),
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_REAL,
                    expected_ndim=1,
                ),
            ])
        if self.use_feat_static_cat:
            transforms.append(
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_CAT,
                    expected_ndim=1,
                ))
        time_series_fields = [FieldName.OBSERVED_VALUES]
        if self.use_feat_dynamic_cat:
            time_series_fields.append(FieldName.FEAT_DYNAMIC_CAT)
        if self.use_feat_dynamic_real or (self.time_features is not None):
            time_series_fields.append(FieldName.FEAT_DYNAMIC_REAL)

        transforms.extend([
            AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=self.time_features,
                pred_length=self.prediction_length,
            ),
            AddAgeFeature(
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_AGE,
                pred_length=self.prediction_length,
                log_scale=True,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_DYNAMIC_REAL,
                input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE] +
                ([FieldName.FEAT_DYNAMIC_REAL]
                 if self.use_feat_dynamic_real else []),
            ),
            InstanceSplitter(
                target_field=FieldName.TARGET,
                is_pad_field=FieldName.IS_PAD,
                start_field=FieldName.START,
                forecast_start_field=FieldName.FORECAST_START,
                train_sampler=self.train_sampler,
                past_length=self.context_length,
                future_length=self.prediction_length,
                time_series_fields=time_series_fields,
                pick_incomplete=True,
            ),
        ])
        return Chain(transforms)
def create_input_transform(
    is_train,
    prediction_length,
    past_length,
    use_feat_static_cat,
    use_feat_dynamic_real,
    freq,
    time_features,
    extract_tail_chunks_for_train: bool = False,
):
    SEASON_INDICATORS_FIELD = "seasonal_indicators"
    remove_field_names = [
        FieldName.FEAT_DYNAMIC_CAT,
        FieldName.FEAT_STATIC_REAL,
    ]
    if not use_feat_dynamic_real:
        remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

    time_features = (
        time_features
        if time_features is not None
        else time_features_from_frequency_str(freq)
    )

    transform = Chain(
        [RemoveFields(field_names=remove_field_names)]
        + (
            [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0])]
            if not use_feat_static_cat
            else []
        )
        + [
            AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
            AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
            # gives target the (1, T) layout
            ExpandDimArray(field=FieldName.TARGET, axis=0),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            # Unnormalized seasonal features
            AddTimeFeatures(
                time_features=CompositeISSM.seasonal_features(freq),
                pred_length=prediction_length,
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=SEASON_INDICATORS_FIELD,
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=time_features,
                pred_length=prediction_length,
            ),
            AddAgeFeature(
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_AGE,
                pred_length=prediction_length,
                log_scale=True,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_TIME,
                input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]
                + (
                    [FieldName.FEAT_DYNAMIC_REAL]
                    if use_feat_dynamic_real
                    else []
                ),
            ),
            CanonicalInstanceSplitter(
                target_field=FieldName.TARGET,
                is_pad_field=FieldName.IS_PAD,
                start_field=FieldName.START,
                forecast_start_field=FieldName.FORECAST_START,
                instance_sampler=ExpectedNumInstanceSampler(num_instances=1),
                time_series_fields=[
                    FieldName.FEAT_TIME,
                    SEASON_INDICATORS_FIELD,
                    FieldName.OBSERVED_VALUES,
                ],
                allow_target_padding=True,
                instance_length=past_length,
                use_prediction_features=True,
                prediction_length=prediction_length,
            )
            if (is_train and not extract_tail_chunks_for_train)
            else CanonicalInstanceSplitter(
                target_field=FieldName.TARGET,
                is_pad_field=FieldName.IS_PAD,
                start_field=FieldName.START,
                forecast_start_field=FieldName.FORECAST_START,
                instance_sampler=TestSplitSampler(),
                time_series_fields=[
                    FieldName.FEAT_TIME,
                    SEASON_INDICATORS_FIELD,
                    FieldName.OBSERVED_VALUES,
                ],
                allow_target_padding=True,
                instance_length=past_length,
                use_prediction_features=True,
                prediction_length=prediction_length,
            ),
        ]
    )
    return transform
Beispiel #20
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [FieldName.FEAT_DYNAMIC_CAT]
        if not self.use_feat_static_real:
            remove_field_names.append(FieldName.FEAT_STATIC_REAL)
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain(
            [RemoveFields(field_names=remove_field_names)]
            + (
                [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0])]
                if not self.use_feat_static_cat
                else []
            )
            + (
                [SetField(output_field=FieldName.FEAT_STATIC_REAL, value=[0.0])]
                if not self.use_feat_static_real
                else []
            )
            + [
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_CAT,
                    expected_ndim=1,
                    dtype=self.dtype,
                ),
                AsNumpyArray(
                    field=FieldName.FEAT_STATIC_REAL,
                    expected_ndim=1,
                    dtype=self.dtype,
                ),
                AsNumpyArray(
                    field=FieldName.TARGET,
                    # in the following line, we add 1 for the time dimension
                    expected_ndim=1 + len(self.distr_output_m.event_shape),
                    dtype=self.dtype,
                ),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                    dtype=self.dtype,
                ),
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=self.time_features,
                    pred_length=self.prediction_length,
                ),
                AddInterDemandPeriodFeature(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.TARGET,  # FieldName.FEAT_TIME FieldName.TARGET #if we want to append to feat time,
                    pred_length=self.prediction_length,
                ),
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    log_scale=True,
                    dtype=self.dtype,
                ),
                VstackFeatures(
                    output_field=FieldName.FEAT_TIME,
                    input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]
                    + (
                        [FieldName.FEAT_DYNAMIC_REAL]
                        if self.use_feat_dynamic_real
                        else []
                    ),
                ),
                # DropNonZeroTarget(
                #     input_fields=[FieldName.FEAT_TIME, FieldName.OBSERVED_VALUES],
                #     target_field=FieldName.TARGET,
                #     pred_length=self.prediction_length,
                # ),
                RenewalInstanceSplitter(
                    target_field=FieldName.TARGET,
                    is_pad_field=FieldName.IS_PAD,
                    start_field=FieldName.START,
                    forecast_start_field=FieldName.FORECAST_START,
                    train_sampler=ExpectedNumInstanceSampler(num_instances=1),
                    past_length=self.history_length,
                    future_length=self.prediction_length,
                    time_series_fields=[FieldName.FEAT_TIME, FieldName.OBSERVED_VALUES],
                    # dummy_value=self.distr_output_m.value_in_support,
                    # pick_incomplete=False
                ),
            ]
        )
Beispiel #21
0
    def create_transformation(self) -> Transformation:
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)

        return Chain(
            [RemoveFields(field_names=remove_field_names)]
            + (
                [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0.0])]
                if not self.use_feat_static_cat
                else []
            )
            + [
                AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
                AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
                # gives target the (1, T) layout
                ExpandDimArray(field=FieldName.TARGET, axis=0),
                AddObservedValuesIndicator(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.OBSERVED_VALUES,
                ),
                # Unnormalized seasonal features
                AddTimeFeatures(
                    time_features=CompositeISSM.seasonal_features(self.freq),
                    pred_length=self.prediction_length,
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=SEASON_INDICATORS_FIELD,
                ),
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=self.time_features,
                    pred_length=self.prediction_length,
                ),
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    log_scale=True,
                ),
                VstackFeatures(
                    output_field=FieldName.FEAT_TIME,
                    input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]
                    + (
                        [FieldName.FEAT_DYNAMIC_REAL]
                        if self.use_feat_dynamic_real
                        else []
                    ),
                ),
                CanonicalInstanceSplitter(
                    target_field=FieldName.TARGET,
                    is_pad_field=FieldName.IS_PAD,
                    start_field=FieldName.START,
                    forecast_start_field=FieldName.FORECAST_START,
                    instance_sampler=TestSplitSampler(),
                    time_series_fields=[
                        FieldName.FEAT_TIME,
                        SEASON_INDICATORS_FIELD,
                        FieldName.OBSERVED_VALUES,
                    ],
                    allow_target_padding=True,
                    instance_length=self.past_length,
                    use_prediction_features=True,
                    prediction_length=self.prediction_length,
                ),
            ]
        )
Beispiel #22
0
		def create_transformation(self):
			# Feature transformation that the model uses for input.
			return AddObservedValuesIndicator(
				target_field=FieldName.TARGET,
				output_field=FieldName.OBSERVED_VALUES,
			)
Beispiel #23
0
    def create_transformation(self) -> Transformation:
        chain = []
        dynamic_feat_fields = []
        remove_field_names = [
            FieldName.FEAT_DYNAMIC_CAT,
            FieldName.FEAT_STATIC_REAL,
        ]

        # --- GENERAL TRANSFORMATION CHAIN ---

        # determine unused input
        if not self.use_feat_dynamic_real:
            remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)
        if not self.use_feat_static_cat:
            remove_field_names.append(FieldName.FEAT_STATIC_CAT)

        chain.extend([
            RemoveFields(field_names=remove_field_names),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
                dtype=self.dtype,
            ),
        ])

        # --- TRANSFORMATION CHAIN FOR DYNAMIC FEATURES ---

        if self.add_time_feature:
            chain.append(
                AddTimeFeatures(
                    start_field=FieldName.START,
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_TIME,
                    time_features=time_features_from_frequency_str(self.freq),
                    pred_length=self.prediction_length,
                ), )
            dynamic_feat_fields.append(FieldName.FEAT_TIME)

        if self.add_age_feature:
            chain.append(
                AddAgeFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_AGE,
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                ), )
            dynamic_feat_fields.append(FieldName.FEAT_AGE)

        if self.use_feat_dynamic_real:
            dynamic_feat_fields.append(FieldName.FEAT_DYNAMIC_REAL)

        # we need to make sure that there is always some dynamic input
        # we will however disregard it in the hybrid forward
        if len(dynamic_feat_fields) == 0:
            chain.append(
                AddConstFeature(
                    target_field=FieldName.TARGET,
                    output_field=FieldName.FEAT_CONST,
                    pred_length=self.prediction_length,
                    dtype=self.dtype,
                ), )
            dynamic_feat_fields.append(FieldName.FEAT_CONST)

        # now we map all the dynamic input onto FieldName.FEAT_DYNAMIC
        if len(dynamic_feat_fields) > 1:
            chain.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_DYNAMIC,
                    input_fields=dynamic_feat_fields,
                ))
        elif len(dynamic_feat_fields) == 1:
            chain.append(
                RenameFields({dynamic_feat_fields[0]: FieldName.FEAT_DYNAMIC}))

        # --- TRANSFORMATION CHAIN FOR STATIC FEATURES ---

        if not self.use_feat_static_cat:
            chain.append(
                SetField(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    value=np.array([0.0]),
                ), )

        # --- SAMPLE AND CUT THE TIME-SERIES ---

        chain.append(
            # because of how the forking decoder works, every time step
            # in context is used for splitting, which is why we use the TestSplitSampler
            ForkingSequenceSplitter(
                train_sampler=TestSplitSampler(),
                enc_len=self.context_length,
                dec_len=self.prediction_length,
                encoder_series_fields=[
                    FieldName.OBSERVED_VALUES,
                    FieldName.FEAT_DYNAMIC,
                ],
                decoder_series_fields=[FieldName.OBSERVED_VALUES] +
                ([FieldName.FEAT_DYNAMIC]
                 if self.enable_decoder_dynamic_feature else []),
                prediction_time_decoder_exclude=[FieldName.OBSERVED_VALUES],
            ), )

        return Chain(chain)
Beispiel #24
0
    def create_transformation(self) -> Transformation:
        transforms = ([AsNumpyArray(field=FieldName.TARGET, expected_ndim=1)] +
                      ([
                          AsNumpyArray(field=name, expected_ndim=1)
                          for name in self.static_cardinalities.keys()
                      ]) + [
                          AsNumpyArray(field=name, expected_ndim=1)
                          for name in chain(
                              self.static_feature_dims.keys(),
                              self.dynamic_cardinalities.keys(),
                          )
                      ] + [
                          AsNumpyArray(field=name, expected_ndim=2)
                          for name in self.dynamic_feature_dims.keys()
                      ] + [
                          AddObservedValuesIndicator(
                              target_field=FieldName.TARGET,
                              output_field=FieldName.OBSERVED_VALUES,
                          ),
                          AddTimeFeatures(
                              start_field=FieldName.START,
                              target_field=FieldName.TARGET,
                              output_field=FieldName.FEAT_TIME,
                              time_features=self.time_features,
                              pred_length=self.prediction_length,
                          ),
                      ])

        if self.static_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    input_fields=list(self.static_cardinalities.keys()),
                    h_stack=True,
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    value=[0.0],
                ),
                AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
            ])

        if self.static_feature_dims:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_STATIC_REAL,
                    input_fields=list(self.static_feature_dims.keys()),
                    h_stack=True,
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_STATIC_REAL,
                    value=[0.0],
                ),
                AsNumpyArray(field=FieldName.FEAT_STATIC_REAL,
                             expected_ndim=1),
            ])

        if self.dynamic_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_DYNAMIC_CAT,
                    input_fields=list(self.dynamic_cardinalities.keys()),
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_DYNAMIC_CAT,
                    value=[[0.0]],
                ),
                AsNumpyArray(
                    field=FieldName.FEAT_DYNAMIC_CAT,
                    expected_ndim=2,
                ),
                BroadcastTo(
                    field=FieldName.FEAT_DYNAMIC_CAT,
                    ext_length=self.prediction_length,
                ),
            ])

        input_fields = [FieldName.FEAT_TIME]
        if self.dynamic_feature_dims:
            input_fields += list(self.dynamic_feature_dims.keys())
        transforms.append(
            VstackFeatures(
                input_fields=input_fields,
                output_field=FieldName.FEAT_DYNAMIC_REAL,
            ))

        if self.past_dynamic_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    input_fields=list(self.past_dynamic_cardinalities.keys()),
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    value=[[0.0]],
                ),
                AsNumpyArray(
                    field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    expected_ndim=2,
                ),
                BroadcastTo(field=FieldName.PAST_FEAT_DYNAMIC + "_cat"),
            ])

        if self.past_dynamic_feature_dims:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                    input_fields=list(self.past_dynamic_feature_dims.keys()),
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                    value=[[0.0]],
                ),
                AsNumpyArray(field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                             expected_ndim=2),
                BroadcastTo(field=FieldName.PAST_FEAT_DYNAMIC_REAL),
            ])

        return Chain(transforms)
Beispiel #25
0
    def transform_data(self):
        # 首先需要把 target
        time_features = time_features_from_frequency_str(self.config.freq)
        self.time_dim = len(time_features) + 1  # 考虑多加了一个 age_features
        seasonal = CompositeISSM.seasonal_features(self.freq)
        self.seasonal_dim = len(seasonal)
        transformation = Chain([
            SwapAxes(
                input_fields=[FieldName.TARGET],
                axes=(0, 1),
            ),
            AddObservedValuesIndicator(
                target_field=FieldName.TARGET,
                output_field=FieldName.OBSERVED_VALUES,
            ),
            # Unnormalized seasonal features
            AddTimeFeatures(
                time_features=seasonal,
                pred_length=self.pred_length,
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field="seasonal_indicators",
            ),
            AddTimeFeatures(
                start_field=FieldName.START,
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_TIME,
                time_features=time_features,
                pred_length=self.pred_length,
            ),
            AddAgeFeature(
                target_field=FieldName.TARGET,
                output_field=FieldName.FEAT_AGE,
                pred_length=self.pred_length,
                log_scale=True,
            ),
            VstackFeatures(
                output_field=FieldName.FEAT_TIME,
                input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE] +
                ([FieldName.FEAT_DYNAMIC_REAL]
                 if self.use_feat_dynamic_real else []),
            ),
            InstanceSplitter(
                target_field=FieldName.TARGET,
                is_pad_field=FieldName.IS_PAD,
                start_field=FieldName.START,
                forecast_start_field=FieldName.FORECAST_START,
                train_sampler=TestSplitSampler(),
                past_length=self.config.past_length,
                future_length=self.config.pred_length,
                output_NTC=True,
                time_series_fields=[
                    FieldName.FEAT_TIME, FieldName.OBSERVED_VALUES,
                    "seasonal_indicators"
                ],
                pick_incomplete=False,
            )
        ])
        print('已设置时间特征~~')
        # 设置环境变量的 dataloader
        target_train_iters = [
            iter(
                TrainDataLoader_OnlyPast(
                    dataset=self.target_data[i].train,
                    transform=transformation,
                    batch_size=self.config.batch_size,
                    num_batches_per_epoch=self.config.num_batches_per_epoch,
                )) for i in range(len(self.target_data))
        ]
        target_test_iters = [
            iter(
                InferenceDataLoader_WithFuture(
                    dataset=self.target_data[i].test,
                    transform=transformation,
                    batch_size=self.config.batch_size,
                )) for i in range(len(self.target_data))
        ]

        self.target_train_loader = stackIterOut(
            target_train_iters,
            fields=[FieldName.OBSERVED_VALUES, FieldName.TARGET],
            dim=0,
            include_future=False)
        self.target_test_loader = stackIterOut(
            target_test_iters,
            fields=[FieldName.OBSERVED_VALUES, FieldName.TARGET],
            dim=0,
            include_future=True)
Beispiel #26
0
}]
ds2 = ListDataset(
    [{
        "start": "2020/01/01",
        "target": [1, 2, 3, np.nan, 5, np.nan, 7, np.nan, np.nan, 10],
    }],
    freq="1D",
)


@pytest.mark.parametrize("ds", [ds1, ds2])
@pytest.mark.parametrize(
    "transform",
    [
        AddObservedValuesIndicator(
            target_field=FieldName.TARGET,
            output_field=FieldName.OBSERVED_VALUES,
        ),
        AddAgeFeature(
            target_field=FieldName.TARGET,
            output_field="age_feature",
            pred_length=1,
        ),
        AddConstFeature(
            target_field=FieldName.TARGET,
            output_field="constant",
            pred_length=1,
        ),
    ],
)
def test_dataset_imutability(ds, transform):
    ds_c = deepcopy(ds)
Beispiel #27
0
    def create_transformation(self) -> Transformation:
        transforms = ([AsNumpyArray(field=FieldName.TARGET, expected_ndim=1)] +
                      ([
                          AsNumpyArray(field=name, expected_ndim=1)
                          for name in self.static_cardinalities.keys()
                      ]) + [
                          AsNumpyArray(field=name, expected_ndim=1)
                          for name in chain(
                              self.static_feature_dims.keys(),
                              self.dynamic_cardinalities.keys(),
                          )
                      ] + [
                          AsNumpyArray(field=name, expected_ndim=2)
                          for name in self.dynamic_feature_dims.keys()
                      ] + [
                          AddObservedValuesIndicator(
                              target_field=FieldName.TARGET,
                              output_field=FieldName.OBSERVED_VALUES,
                          ),
                          AddTimeFeatures(
                              start_field=FieldName.START,
                              target_field=FieldName.TARGET,
                              output_field=FieldName.FEAT_TIME,
                              time_features=self.time_features,
                              pred_length=self.prediction_length,
                          ),
                      ])

        ts_fields = []
        past_ts_fields = []

        if self.static_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    input_fields=list(self.static_cardinalities.keys()),
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_STATIC_CAT,
                    value=[0.0],
                ),
                AsNumpyArray(field=FieldName.FEAT_STATIC_CAT, expected_ndim=1),
            ])

        if self.static_feature_dims:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_STATIC_REAL,
                    input_fields=list(self.static_feature_dims.keys()),
                ))
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_STATIC_REAL,
                    value=[0.0],
                ),
                AsNumpyArray(field=FieldName.FEAT_STATIC_REAL,
                             expected_ndim=1),
            ])

        if self.dynamic_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.FEAT_DYNAMIC_CAT,
                    input_fields=list(self.dynamic_cardinalities.keys()),
                ))
            ts_fields.append(FieldName.FEAT_DYNAMIC_CAT)
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.FEAT_DYNAMIC_CAT,
                    value=[0.0],
                ),
                AsNumpyArray(field=FieldName.FEAT_DYNAMIC_CAT,
                             expected_ndim=1),
            ])

        input_fields = [FieldName.FEAT_TIME]
        if self.dynamic_feature_dims:
            input_fields += list(self.dynamic_feature_dims.keys())
        transforms.append(
            VstackFeatures(
                input_fields=input_fields,
                output_field=FieldName.FEAT_DYNAMIC_REAL,
            ))
        ts_fields.append(FieldName.FEAT_DYNAMIC_REAL)

        if self.past_dynamic_cardinalities:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    input_fields=list(self.past_dynamic_cardinalities.keys()),
                ))
            past_ts_fields.append(FieldName.PAST_FEAT_DYNAMIC + "_cat")
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    value=[0.0],
                ),
                AsNumpyArray(
                    field=FieldName.PAST_FEAT_DYNAMIC + "_cat",
                    expected_ndim=1,
                ),
            ])

        if self.past_dynamic_feature_dims:
            transforms.append(
                VstackFeatures(
                    output_field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                    input_fields=list(self.past_dynamic_feature_dims.keys()),
                ))
            past_ts_fields.append(FieldName.PAST_FEAT_DYNAMIC_REAL)
        else:
            transforms.extend([
                SetField(
                    output_field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                    value=[[0.0]],
                ),
                AsNumpyArray(field=FieldName.PAST_FEAT_DYNAMIC_REAL,
                             expected_ndim=2),
            ])

        transforms.append(
            TFTInstanceSplitter(
                train_sampler=ExpectedNumInstanceSampler(
                    num_instances=self.num_instance_per_series, ),
                past_length=self.context_length,
                future_length=self.prediction_length,
                time_series_fields=ts_fields,
                past_time_series_fields=past_ts_fields,
            ))

        return Chain(transforms)
Beispiel #28
0
 def create_transformation(self) -> Transformation:
     mask_unobserved = AddObservedValuesIndicator(
         target_field=FieldName.TARGET,
         output_field=FieldName.OBSERVED_VALUES,
     )
     return mask_unobserved