class_docstr: Construct a COP estimator for temporal hierarchies.
  
  Parameters
  ----------
  freq
  prediction_length
  base_estimator_name
      Currently only `DeepAREstimator`
  base_estimator_hps
  do_reconciliation
      Flag to indicate if the samples at different aggregated levels should be reconciled. Useful for ablation study.
      Set this to False and check just learning multiple related tasks at the same time affects the accuracy at the
      bottom level; this is without doing any reconciliation.
  loss_function
      Training loss function to be used. Currently one of `crps_univariate` and `mse`.
  distr_output
  trainer
  lag_ub
  num_samples_for_loss
  dtype
class_docstr_tok: ["Construct","a","COP","estimator","for","temporal","hierarchies",".","Parameters","--","--","--","--","--","freq","prediction_length","base_estimator_name","Currently","only","`","DeepAREstimator","`","base_estimator_hps","do_reconciliation","Flag","to","indicate","if","the","samples","at","different","aggregated","levels","should","be","reconciled",".","Useful","for","ablation","study",".","Set","this","to","False","and","check","just","learning","multiple","related","tasks","at","the","same","time","affects","the","accuracy","at","the","bottom","level",";","this","is","without","doing","any","reconciliation",".","loss_function","Training","loss","function","to","be","used",".","Currently","one","of","`","crps_univariate","`","and","`","mse","`",".","distr_output","trainer","lag_ub","num_samples_for_loss","dtype"]
code: def __init__(
      self,
      freq: str,
      prediction_length: int,
      base_estimator_name: str,
      base_estimator_hps: dict,
      use_gnn: bool = True,
      use_mlp: bool = True,
      adj_mat_option: str = "hierarchical",
      non_negative: bool = False,
      do_reconciliation: bool = True,
      loss_function: str = "crps_univariate",
      warmstart_epoch_frac: float = 0.5,
      trainer: Trainer = Trainer(hybridize=False),
      lag_ub: int = 1200,
      num_samples_for_loss: int = 200,
      return_forecasts_at_all_levels: bool = False,
      naive_reconciliation: bool = False,
      dtype: Type = np.float32,
      impute_missing_values: bool = False,
      imputation_method: Optional[MissingValueImputation] = None,
      num_imputation_samples: int = 1,
  ) -> None:
      super().__init__(trainer=trainer, dtype=dtype)
  
      self.use_gnn = use_gnn
      self.use_mlp = use_mlp
      self.adj_mat_option = adj_mat_option
      self.do_reconciliation = do_reconciliation
      self.non_negative = non_negative
      self.warmstart_epoch_frac = warmstart_epoch_frac
      self.lag_ub = lag_ub
      self.num_samples_for_loss = num_samples_for_loss
      self.return_forecasts_at_all_levels = (
          return_forecasts_at_all_levels
      )
      self.naive_reconciliation = naive_reconciliation
  
      assert loss_function in LOSS_FUNCTIONS
      self.loss_function = loss_function
  
      self.context_length = base_estimator_hps.pop(
          "context_length", prediction_length
      )
      self.prediction_length = base_estimator_hps.pop(
          "prediction_length", prediction_length
      )
      self.freq = base_estimator_hps.pop("freq", freq)
      self.dtype = dtype
  
      self.temporal_hierarchy = TEMPORAL_HIERARCHIES[self.freq]
      self.base_estimator_type = eval(base_estimator_name)
  
      assert self.base_estimator_type == DeepAREstimatorForCOP
  
      base_estimator_hps.setdefault("distr_output", GaussianOutput())
  
      print(
          f"Distribution output: {base_estimator_hps['distr_output']}"
      )
  
      base_estimator_hps.setdefault(
          "impute_missing_values", impute_missing_values
      )
  
      base_estimator_hps.setdefault(
          "imputation_method", imputation_method
      )
  
      base_estimator_hps.setdefault(
          "num_imputation_samples", num_imputation_samples
      )
  
      self.estimators = []
      for agg_multiple, freq_str in zip(
          self.temporal_hierarchy.agg_multiples,
          self.temporal_hierarchy.freq_strs,
      ):
          base_estimator_hps_agg = deepcopy(base_estimator_hps)
          # Following is a hack because gluonts does not allow setting lag_ub from outside!
          lags_seq = get_lags_for_frequency(
              freq_str=freq_str,
              lag_ub=lag_ub // agg_multiple,
          )
  
          # Remove lags that will not be available for reconciliation during inference.
          num_nodes = self.temporal_hierarchy.num_leaves // agg_multiple
          lags_seq = [lag for lag in lags_seq if lag >= num_nodes]
  
          # adapt window_length if RollingMeanValueImputation is used
          if isinstance(imputation_method, RollingMeanValueImputation):
              base_estimator_hps_agg[
                  "imputation_method"
              ] = RollingMeanValueImputation(
                  window_size=imputation_method.window_size
                  // agg_multiple
              )
  
          # Hack to enforce correct serialization of lags_seq and history length
          # (only works when set in constructor).
          if agg_multiple != 1:
              estimator = self.base_estimator_type(
                  freq=freq_str,
                  context_length=self.context_length // agg_multiple,
                  lags_seq=lags_seq,
                  prediction_length=self.prediction_length
                  // agg_multiple,
                  **base_estimator_hps_agg,
              )
          else:
              estimator = self.base_estimator_type(
                  freq=freq_str,
                  context_length=self.context_length // agg_multiple,
                  lags_seq=lags_seq,
                  prediction_length=self.prediction_length
                  // agg_multiple,
                  **base_estimator_hps_agg,
                  # Load more data at the bottom level so that enough lags are available for the aggregated levels.
                  history_length=(
                      (self.context_length // agg_multiple)
                      + max(lags_seq)
                  )
                  * 2,
              )
  
          self.estimators.append(estimator)
  
      self.agg_estimators = self.estimators[:-1]
      self.base_estimator = self.estimators[-1]
  
      self.agg_feature_adder = AddTimeFeaturesAtAggregateLevels(
          agg_multiples=self.temporal_hierarchy.agg_multiples[:-1],
          agg_estimators=self.agg_estimators,
      )
  
imports: from copy import deepcopy
  from functools import partial
  from typing import List, Tuple, Optional
  from mxnet.gluon import HybridBlock
  import numpy
  import pandas
  from gluonts.core.component import Type, validated
  from gluonts.dataset.common import DataEntry, Dataset
  from gluonts.dataset.field_names import FieldName
  from gluonts.dataset.loader import DataLoader, TrainDataLoader, ValidationDataLoader
  from gluonts.model.predictor import Predictor
  from gluonts.mx.distribution import GaussianOutput
  from gluonts.mx.model.estimator import GluonEstimator
  from gluonts.mx.trainer import Trainer
  from gluonts.mx.util import get_hybrid_forward_input_names
  from gluonts.mx.util import copy_parameters
  from gluonts.time_feature import get_lags_for_frequency, time_features_from_frequency_str
  from gluonts.transform import SelectFields, SimpleTransformation, Transformation, MissingValueImputation, RollingMeanValueImputation
  from gluonts.nursery.temporal_hierarchical_forecasting.model.cop_deepar.gluonts_fixes import batchify_with_dict, DeepAREstimatorForCOP, LOSS_FUNCTIONS, RepresentableBlockPredictorBatchifyWithDict
  from gluonts.nursery.temporal_hierarchical_forecasting.utils.common import TEMPORAL_HIERARCHIES
  from gluonts.nursery.temporal_hierarchical_forecasting.model.cop_deepar._network import COPDeepARTrainingNetwork, COPDeepARPredictionNetwork
label_desc: Use image node_id 1 to create a new COPDeepAREstimator object from inherited base classes: GluonEstimator with example: obj = COPDeepAREstimator(freq, prediction_length, base_estimator_name, base_estimator_hps, use_gnn, use_mlp, adj_mat_option, non_negative, do_reconciliation, loss_function, warmstart_epoch_frac, trainer, lag_ub, num_samples_for_loss, return_forecasts_at_all_levels, naive_reconciliation, dtype, impute_missing_values, imputation_method, num_imputation_samples)