예제 #1
0
 def _set_model_instance(self):
     try:
         self.model_instance = hts_models.MODEL_MAPPING[self.model]
     except KeyError:
         raise InvalidArgumentException(
             f'Model {self.model} not valid. Pick one of: {" ".join(ModelT.names())}'
         )
예제 #2
0
    def __init_hts(
        self,
        nodes: Optional[NodesT] = None,
        df: Optional[pandas.DataFrame] = None,
        tree: Optional[HierarchyTree] = None,
        root: str = "root",
        exogenous: Optional[List[str]] = None,
    ):

        if not nodes and not df:
            if not tree:
                raise InvalidArgumentException(
                    "Either nodes and df must be passed, or a pre-built hierarchy tree"
                )
            else:
                self.nodes = tree
        else:
            self.nodes = HierarchyTree.from_nodes(nodes=nodes,
                                                  df=df,
                                                  exogenous=exogenous,
                                                  root=root)
        self.exogenous = exogenous
        self.sum_mat, sum_mat_labels = to_sum_mat(self.nodes)
        self._set_model_instance()
        self._init_revision()
예제 #3
0
def groupify(root_node,
             df,
             freq='1H',
             nodes=None,
             min_count=0.1,
             total=None) -> NAryTreeT:
    """

    Parameters
    ----------
    fillna
    root_node : NAryTreeT
    df : pandas.DataFrame
    freq : str
        resample frequency
    nodes : tuple
        Hierarchy node
    min_count : int or float
        Minimum number of observations for a node to be used. If float, it represents a
        fraction of values that need to be non NaNs and must be between 0 and 1
    total : pandas.DataFrame:
        Name of root node

    Returns
    -------

    """

    child_group = nodes[0]  # city
    children = df[child_group].unique()  # berlin, munich, ...

    # add first level children
    for child in children:
        sub_df = df[df[child_group] == child]
        resampled = resample_count(sub_df, freq, child)
        root_node.add_child(key=child, item=resampled, exogenous=None)

    # add the rest
    for node in nodes[1:]:
        parent_group = child_group
        child_group = node  # hex_index_6
        children = df[child_group].unique()  # abcccc, abccf, ...

        for child in children:
            sub_df = df[df[child_group] == child]
            if isinstance(min_count, float):
                allowance = len(total) * min_count
            elif isinstance(min_count, int):
                allowance = min_count
            else:
                raise InvalidArgumentException(
                    f'min_count must be either float or integer')
            if len(sub_df) < allowance:
                continue
            parent_name = sub_df[parent_group].value_counts().index[0]
            resampled = resample_count(sub_df, freq, child)
            for c in root_node.traversal_level():
                if c.key == parent_name:
                    c.add_child(key=child, item=resampled, exogenous=None)
    return root_node
예제 #4
0
    def __init__(
        self, kind: str, node: HierarchyTree, transform: TransformT = False, **kwargs
    ):
        """
        Parameters
        ----------
        kind : str
            One of `prophet`, `sarimax`, `auto-arima`, `holt-winters`
        node : HierarchyTree
            Node
        transform : Bool or NamedTuple
        kwargs
            Keyword arguments to be passed to the model instantiation. See the documentation
            of each of the actual model implementations for a more comprehensive treatment
        """

        if kind not in ModelT.names():
            raise InvalidArgumentException(
                f'Model {kind} not valid. Pick one of: {" ".join(ModelT.names())}'
            )

        self.kind = kind
        self.node = node
        self.transform_function = self._set_transform(transform=transform)
        self.model = self.create_model(**kwargs)
        self.forecast = None
        self.residual = None
        self.mse = None
예제 #5
0
    def revise(self, forecasts=None, mse=None, nodes=None):
        """


        Parameters
        ----------
        forecasts
        mse
        nodes

        Returns
        -------

        """
        if self.name == MethodsT.NONE.name:
            return y_hat_matrix(forecasts=forecasts)

        if self.name in [
                MethodsT.OLS.name, MethodsT.WLSS.name, MethodsT.WLSV.name
        ]:
            return optimal_combination(forecasts=forecasts,
                                       sum_mat=self.sum_mat,
                                       method=MethodsT.OLS.name,
                                       mse=mse)

        elif self.name == MethodsT.BU.name:
            print("Name:::" + str(self.name))
            print(list(forecasts.keys()))
            y_hat = self._y_hat_matrix(forecasts)
            return self._new_mat(y_hat)

        elif self.name in [MethodsT.AHP.name, MethodsT.PHA.name]:
            if self.transformer:
                for node in make_iterable(nodes, prop=None):
                    node.item[node.key] = self.transformer.inverse_transform(
                        node.item[node.key])
            y_hat = proportions(nodes=nodes,
                                forecasts=forecasts,
                                sum_mat=self.sum_mat,
                                method=self.name)
            return self._new_mat(y_hat)

        elif self.name == MethodsT.FP.name:
            return forecast_proportions(forecasts, nodes)

        else:
            raise InvalidArgumentException('Revision model name is invalid')