U
    Kvf]H                     @   sf  d dl mZmZ d dlZd dlmZmZmZm	Z	 d dl
Zd dlZd dlmZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZmZ d d	lmZmZ d d
lm Z  e	e!e"ejej#ej$f Z%eej&Z'e'(dedddg e'(dedddg e')ddddddddddddddgZ*eej+j&Z'e')ddgZ,eee*dd G d!d" d"Z-G d#d$ d$Z.dS )%    )Substitutionis_int_indexN)AnyDictOptionalUnion)
PandasData)SimpleTableSummary)	Docstring	Parameterindent)PredictionResults)get_index_locget_prediction_index)STLDecomposeResult)_check_dynamicendogmodelZModelzQThe model used to forecast endog after the seasonality has been removed using STLmodel_kwargszDict[str, Any]zuAny additional arguments needed to initialized the model using the residuals produced by subtracting the seasonality.periodseasonaltrendlow_passseasonal_deg	trend_deglow_pass_degrobustseasonal_jump
trend_jumplow_pass_jump
inner_iter
outer_iterz    )Zstl_forecast_paramsc                   @   sV   e Zd ZdZdddddddddddddddZeeed	d
ddddddZdS )STLForecasta  
    Model-based forecasting using STL to remove seasonality

    Forecasts are produced by first subtracting the seasonality
    estimated using STL, then forecasting the deseasonalized
    data using a time-series model, for example, ARIMA.

    Parameters
    ----------
%(stl_forecast_params)s

    See Also
    --------
    statsmodels.tsa.arima.model.ARIMA
        ARIMA modeling.
    statsmodels.tsa.ar_model.AutoReg
        Autoregressive modeling supporting complex deterministics.
    statsmodels.tsa.exponential_smoothing.ets.ETSModel
        Additive and multiplicative exponential smoothing with trend.
    statsmodels.tsa.statespace.exponential_smoothing.ExponentialSmoothing
        Additive exponential smoothing with trend.

    Notes
    -----
    If :math:`\hat{S}_t` is the seasonal component, then the deseasonalize
    series is constructed as

    .. math::

        Y_t - \hat{S}_t

    The trend component is not removed, and so the time series model should
    be capable of adequately fitting and forecasting the trend if present. The
    out-of-sample forecasts of the seasonal component are produced as

    .. math::

        \hat{S}_{T + h} = \hat{S}_{T - k}

    where :math:`k = m - h + m \lfloor (h-1)/m \rfloor` tracks the period
    offset in the full cycle of 1, 2, ..., m where m is the period length.

    This class is mostly a convenience wrapper around ``STL`` and a
    user-specified model. The model is assumed to follow the standard
    statsmodels pattern:

    * ``fit`` is used to estimate parameters and returns a results instance,
      ``results``.
    * ``results`` must exposes a method ``forecast(steps, **kwargs)`` that
      produces out-of-sample forecasts.
    * ``results`` may also exposes a method ``get_prediction`` that produces
      both in- and out-of-sample predictions.

    See the notebook `Seasonal Decomposition
    <../examples/notebooks/generated/stl_decomposition.html>`__ for an
    overview.

    Examples
    --------
    >>> import numpy as np
    >>> import pandas as pd
    >>> from statsmodels.tsa.api import STLForecast
    >>> from statsmodels.tsa.arima.model import ARIMA
    >>> from statsmodels.datasets import macrodata
    >>> ds = macrodata.load_pandas()
    >>> data = np.log(ds.data.m1)
    >>> base_date = f"{int(ds.data.year[0])}-{3*int(ds.data.quarter[0])+1}-1"
    >>> data.index = pd.date_range(base_date, periods=data.shape[0], freq="QS")

    Generate forecasts from an ARIMA

    >>> stlf = STLForecast(data, ARIMA, model_kwargs={"order": (2, 1, 0)})
    >>> res = stlf.fit()
    >>> forecasts = res.forecast(12)

    Generate forecasts from an Exponential Smoothing model with trend

    >>> from statsmodels.tsa.statespace import exponential_smoothing
    >>> ES = exponential_smoothing.ExponentialSmoothing
    >>> config = {"trend": True}
    >>> stlf = STLForecast(data, ES, model_kwargs=config)
    >>> res = stlf.fit()
    >>> forecasts = res.forecast(12)
    N      F)r   r   r   r   r   r   r   r   r   r   r    r!   c                C   sT   || _ t||||||	|
||||d| _|| _|d kr8i n|| _t|dsPtdd S )N)r   r   r   r   r   r   r   r   r   r    r!   fitz$model must expose a ``fit``  method.)_endogdict_stl_kwargs_model_model_kwargshasattrAttributeError)selfr   r   r   r   r   r   r   r   r   r   r   r   r    r!    r0   C/tmp/pip-unpacked-wheel-2v6byqio/statsmodels/tsa/forecasting/stl.py__init__   s$    
zSTLForecast.__init__z        )Z
fit_params)r"   r#   
fit_kwargsc          	      C   sz   |dkri n|}t | jf| j}|j||d}|j|j }| j|f| j}|jf |}t|dsht	dt
||||| jS )a  
        Estimate STL and forecasting model parameters.

        Parameters
        ----------
%(fit_params)s
        fit_kwargs : Dict[str, Any]
            Any additional keyword arguments to pass to ``model``'s ``fit``
            method when estimating the model on the decomposed residuals.

        Returns
        -------
        STLForecastResults
            Results with forecasting methods.
        N)r"   r#   forecastz5The model's result must expose a ``forecast`` method.)r   r(   r*   r'   r   Zresidr+   r,   r-   r.   STLForecastResults)	r/   r"   r#   r3   stlZstl_fitZmodel_endogmodresr0   r0   r1   r'      s     
zSTLForecast.fit)	__name__
__module____qualname____doc__r2   r   r   _fit_paramsr'   r0   r0   r0   r1   r$   A   s    Z%r$   c                   @   s,  e Zd ZdZeeddddZeedddZ	eedd	d
Z
eedddZeedddZeedddZedddZee ee eeef ejdddZd!eeej eejejf dddZd"eeeef eejejf dddZd#ee ee eeef eeef ddd ZdS )$r5   a  
    Results for forecasting using STL to remove seasonality

    Parameters
    ----------
    stl : STL
        The STL instance used to decompose the data.
    result : DecomposeResult
        The result of applying STL to the data.
    model : Model
        The time series model used to model the non-seasonal dynamics.
    model_result : Results
        Model results instance supporting, at a minimum, ``forecast``.
    N)r6   resultreturnc                 C   s   || _ || _|| _|| _t|| _| jjd | _t	|dt
| j| _t| jt
jt
jfst| jszt
| j| _W n" tk
r   t
| j| _Y nX d S )Nr   index)_stl_resultr+   _model_resultnpasarrayr(   shape_nobsgetattrpdZ
RangeIndex_index
isinstanceZDatetimeIndexZPeriodIndexr   Zto_datetime
ValueError)r/   r6   r>   r   model_resultr   r0   r0   r1   r2      s    zSTLForecastResults.__init__)r?   c                 C   s   | j jS )z$The period of the seasonal component)rA   r   r/   r0   r0   r1   r      s    zSTLForecastResults.periodc                 C   s   | j S )z2The STL instance used to decompose the time series)rA   rN   r0   r0   r1   r6     s    zSTLForecastResults.stlc                 C   s   | j S )z&The result of applying STL to the data)rB   rN   r0   r0   r1   r>   	  s    zSTLForecastResults.resultc                 C   s   | j S )z3The model fit to the additively deseasonalized data)r+   rN   r0   r0   r1   r     s    zSTLForecastResults.modelc                 C   s   | j S )z)The result class from the estimated model)rC   rN   r0   r0   r1   rM     s    zSTLForecastResults.model_resultc                    s2  t | jdstd| j }t|ts0tdd|jd j |jd _| j	j
}d}g }g }g }g }|D ]   }|dd}|d	kr|d
7 }t fdd|D }	|d7 }|d}
t|  d}|	r||
 ||g qh|d|
  ||g qht|t|dd}|t||d |j| |S )aJ  
        Summary of both the STL decomposition and the model fit.

        Returns
        -------
        Summary
            The summary of the model fit and the STL decomposition.

        Notes
        -----
        Requires that the model's result class supports ``summary`` and
        returns a ``Summary`` object.
        summaryz3The model result does not have a summary attribute.z3The model result's summary is not a Summary object.zSTL Decomposition and r   )r   r   r   _ )ZTrendzLow Passz Lengthc                 3   s   | ]}  |V  qd S )N)
startswith).0valkeyr0   r1   	<genexpr>=  s     z-STLForecastResults.summary.<locals>.<genexpr>:z<23sz>13sz      zSTL Configuration)stubstitle)rY   )r-   rC   r.   rO   rK   r
   	TypeErrorZtablesrZ   rA   config
capitalizereplaceanystrappendr	   tupleZextend_right)r/   rO   r\   Z	left_keysZ	left_dataZ
left_stubsZ
right_dataZright_stubsnewZis_leftZstubrT   tabr0   rU   r1   rO     sN    



  zSTLForecastResults.summary)startenddynamicr?   c                 C   sD  t t| j| jd}|dkr"d}t||| j| j|d\}}}}t|tt	j
tjfrpt|| j\}}}|| }n|dkr~d}n|dkrd}| j}t||||\}}|dkr|d n|}	t| jj}
|
||	 }td}|dk	r|| d | }| j|d|d	}n,|r2| |d}t|| d}||d }tj||f }|S )
a  
        Get STLs seasonal in- and out-of-sample predictions

        Parameters
        ----------
        start : int, str, or datetime, optional
            Zero-indexed observation number at which to start forecasting,
            i.e., the first forecast is start. Can also be a date string to
            parse or a datetime type. Default is the the zeroth observation.
        end : int, str, or datetime, optional
            Zero-indexed observation number at which to end forecasting, i.e.,
            the last forecast is end. Can also be a date string to
            parse or a datetime type. However, if the dates index does not
            have a fixed frequency, end must be an integer index if you
            want out of sample prediction. Default is the last observation in
            the sample.
        dynamic : bool, int, str, or datetime, optional
            Integer offset relative to `start` at which to begin dynamic
            prediction. Can also be an absolute date string to parse or a
            datetime type (these are not interpreted as offsets).
            Prior to this observation, true endogenous values will be used for
            prediction; starting with this observation and continuing through
            the end of prediction, forecasted endogenous values will be used
            instead.

        Returns
        -------
        ndarray
            Array containing the seasibak predictions.
        r@   Nr   )dataTFr&   )r   )offset)r   rI   Seriesr(   rJ   r   rG   rK   r`   dtdatetime	Timestampr   r   rD   rE   rB   r   empty_seasonal_forecastmaxZr_)r/   re   rf   rg   ri   Zout_of_sampleZprediction_indexrP   ZnobsZin_sample_endr   ZpredictionsZoosnumZ	oos_startr0   r0   r1   _get_seasonal_predictionN  s@    $    


z+STLForecastResults._get_seasonal_prediction)stepsr@   r?   c                 C   sx   | j }t| jj}|dkr"| jn|}||| | }t||| || dk }|d| }|dk	rttj||d}|S )a  
        Get the seasonal component of the forecast

        Parameters
        ----------
        steps : int
            The number of steps required.
        index : pd.Index
            A pandas index to use. If None, returns an ndarray.
        offset : int
            The index of the first out-of-sample observation. If None, uses
            nobs.

        Returns
        -------
        seasonal : {ndarray, Series}
            The seasonal component.
        Nr   rh   )	r   rD   rE   rB   r   rG   ZtilerI   rk   )r/   rt   r@   rj   r   r   r0   r0   r1   rp     s    z%STLForecastResults._seasonal_forecastr&   )rt   kwargsr?   c                 K   s<   | j jf d|i|}t|tjr(|jnd}|| || S )a  
        Out-of-sample forecasts

        Parameters
        ----------
        steps : int, str, or datetime, optional
            If an integer, the number of steps to forecast from the end of the
            sample. Can also be a date string to parse or a datetime type.
            However, if the dates index does not have a fixed frequency, steps
            must be an integer. Default
        **kwargs
            Additional arguments may required for forecasting beyond the end
            of the sample. These arguments are passed into the time series
            model results' ``forecast`` method.

        Returns
        -------
        forecast : {ndarray, Series}
            Out of sample forecasts
        rt   N)rC   r4   rK   rI   rk   r@   rp   )r/   rt   ru   r4   r@   r0   r0   r1   r4     s    zSTLForecastResults.forecastF)re   rf   rg   ru   c           
   	   K   s   | j jf |||d|}| |||}|j| }z
|j}W nL ttfk
r   ddl}	|	jd| j	j
j dtdd tj|  }Y nX t||d|jd	S )
a  
        In-sample prediction and out-of-sample forecasting

        Parameters
        ----------
        start : int, str, or datetime, optional
            Zero-indexed observation number at which to start forecasting,
            i.e., the first forecast is start. Can also be a date string to
            parse or a datetime type. Default is the the zeroth observation.
        end : int, str, or datetime, optional
            Zero-indexed observation number at which to end forecasting, i.e.,
            the last forecast is end. Can also be a date string to
            parse or a datetime type. However, if the dates index does not
            have a fixed frequency, end must be an integer index if you
            want out of sample prediction. Default is the last observation in
            the sample.
        dynamic : bool, int, str, or datetime, optional
            Integer offset relative to `start` at which to begin dynamic
            prediction. Can also be an absolute date string to parse or a
            datetime type (these are not interpreted as offsets).
            Prior to this observation, true endogenous values will be used for
            prediction; starting with this observation and continuing through
            the end of prediction, forecasted endogenous values will be used
            instead.
        **kwargs
            Additional arguments may required for forecasting beyond the end
            of the sample. These arguments are passed into the time series
            model results' ``get_prediction`` method.

        Returns
        -------
        PredictionResults
            PredictionResults instance containing in-sample predictions,
            out-of-sample forecasts, and prediction intervals.
        )re   rf   rg   r   Nz>The variance of the predicted mean is not available using the z model class.   )
stacklevelZnorm)dist
row_labels)rC   get_predictionrs   Zpredicted_meanvar_pred_meanr.   NotImplementedErrorwarningswarnr   	__class__r9   UserWarningrD   nancopyr   ry   )
r/   re   rf   rg   ru   predZseasonal_predictionZmeanr{   r}   r0   r0   r1   rz     s:    *    

   z!STLForecastResults.get_prediction)N)r&   )NNF) r9   r:   r;   r<   r   r   r2   propertyintr   r6   r>   r   r   rM   r
   rO   r   DateLiker   boolrD   Zndarrayrs   rI   ZIndexrk   rp   r   r`   r4   rz   r0   r0   r0   r1   r5      sT    8
D  !  
   

r5   )/Zstatsmodels.compat.pandasr   r   rm   rl   typingr   r   r   r   ZnumpyrD   ZpandasrI   Zstatsmodels.base.datar   Zstatsmodels.iolib.summaryr	   r
   Zstatsmodels.tools.docstringr   r   r   Zstatsmodels.tsa.base.predictionr   Zstatsmodels.tsa.base.tsa_modelr   r   Zstatsmodels.tsa.seasonalr   r   Z(statsmodels.tsa.statespace.kalman_filterr   r   r`   rn   Z
datetime64r   r<   ZdsZinsert_parametersZextract_parametersZ_stl_forecast_paramsr'   r=   r$   r5   r0   r0   r0   r1   <module>   sl   
 