We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ENH] `SARIMAX` - implement `predict_interval` or `predict_quantiles` (for `statsmodels` `SARIMAX` interface)
From discord, Huseyin Aytug:

hi when I want to produce confidence intervals with `SARIMAX`, I get this error:

`NotImplementedError: SARIMAX does not have the capability to return quantile predictions. If you think this estimator should have the capability, please open an issue on sktime.`

However, it should be possible according to the documentation http://www.sktime.net/en/latest/api_reference/auto_generated/sktime.forecasting.sarimax.SARIMAX.html#sktime.forecasting.sarimax.SARIMAX.predict_interval

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sktime/forecasting/sarimax.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # !/usr/bin/env python3 -u
3 # copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
4 """Implements SARIMAX."""
5 
6 __all__ = ["SARIMAX"]
7 __author__ = ["TNTran92"]
8 
9 from sktime.forecasting.base.adapters import _StatsModelsAdapter
10 
11 
12 class SARIMAX(_StatsModelsAdapter):
13     """SARIMAX forecaster.
14 
15     Direct interface for `statsmodels.tsa.api.SARIMAX`.
16 
17     Parameters
18     ----------
19     order : iterable or iterable of iterables, optional, default=(1,0,0)
20         The (p,d,q) order of the model for the number of AR parameters,
21         differences, and MA parameters. `d` must be an integer
22         indicating the integration order of the process, while
23         `p` and `q` may either be an integers indicating the AR and MA
24         orders (so that all lags up to those orders are included) or else
25         iterables giving specific AR and / or MA lags to include. Default is
26         an AR(1) model: (1,0,0).
27     seasonal_order : iterable, optional, default=(0,0,0,0)
28         The (P,D,Q,s) order of the seasonal component of the model for the
29         AR parameters, differences, MA parameters, and periodicity.
30         `D` must be an integer indicating the integration order of the process,
31         while `P` and `Q` may either be an integers indicating the AR and MA
32         orders (so that all lags up to those orders are included) or else
33         iterables giving specific AR and / or MA lags to include. `s` is an
34         integer giving the periodicity (number of periods in season), often it
35         is 4 for quarterly data or 12 for monthly data. Default is no seasonal
36         effect.
37     trend : str{'n','c','t','ct'} or iterable, optional, default="c"
38         Parameter controlling the deterministic trend polynomial :math:`A(t)`.
39         Can be specified as a string where 'c' indicates a constant (i.e. a
40         degree zero component of the trend polynomial), 't' indicates a
41         linear trend with time, and 'ct' is both. Can also be specified as an
42         iterable defining the non-zero polynomial exponents to include, in
43         increasing order. For example, `[1,1,0,1]` denotes
44         :math:`a + bt + ct^3`. Default is to not include a trend component.
45     measurement_error : bool, optional, default=False
46         Whether or not to assume the endogenous observations `endog` were
47         measured with error.
48     time_varying_regression : bool, optional, default=False
49         Used when an explanatory variables, `exog`, are provided
50         to select whether or not coefficients on the exogenous regressors are
51         allowed to vary over time.
52     mle_regression : bool, optional, default=True
53         Whether or not to use estimate the regression coefficients for the
54         exogenous variables as part of maximum likelihood estimation or through
55         the Kalman filter (i.e. recursive least squares). If
56         `time_varying_regression` is True, this must be set to False.
57     simple_differencing : bool, optional, default=False
58         Whether or not to use partially conditional maximum likelihood
59         estimation. If True, differencing is performed prior to estimation,
60         which discards the first :math:`s D + d` initial rows but results in a
61         smaller state-space formulation. See the Notes section for important
62         details about interpreting results when this option is used. If False,
63         the full SARIMAX model is put in state-space form so that all
64         datapoints can be used in estimation.
65     enforce_stationarity : bool, optional, default=True
66         Whether or not to transform the AR parameters to enforce stationarity
67         in the autoregressive component of the model.
68     enforce_invertibility : bool, optional, default=True
69         Whether or not to transform the MA parameters to enforce invertibility
70         in the moving average component of the model.
71     hamilton_representation : bool, optional, default=False
72         Whether or not to use the Hamilton representation of an ARMA process
73         (if True) or the Harvey representation (if False).
74     concentrate_scale : bool, optional, default=False
75         Whether or not to concentrate the scale (variance of the error term)
76         out of the likelihood. This reduces the number of parameters estimated
77         by maximum likelihood by one, but standard errors will then not
78         be available for the scale parameter.
79     trend_offset : int, optional, default=1
80         The offset at which to start time trend values. Default is 1, so that
81         if `trend='t'` the trend is equal to 1, 2, ..., nobs. Typically is only
82         set when the model created by extending a previous dataset.
83     use_exact_diffuse : bool, optional, default=False
84         Whether or not to use exact diffuse initialization for non-stationary
85         states. Default is False (in which case approximate diffuse
86         initialization is used).
87     random_state : int, RandomState instance or None, optional ,
88         default=None – If int, random_state is the seed used by the random
89         number generator; If RandomState instance, random_state is the random
90         number generator; If None, the random number generator is the
91         RandomState instance used by np.random.
92 
93     See Also
94     --------
95     ARIMA
96     AutoARIMA
97     StatsForecastAutoARIMA
98 
99     References
100     ----------
101     .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles
102     and practice. OTexts, 2014.
103 
104     Examples
105     --------
106     >>> from sktime.datasets import load_airline
107     >>> from sktime.forecasting.sarimax import SARIMAX
108     >>> y = load_airline()
109     >>> forecaster = SARIMAX(
110     ...     order=(1, 0, 0), trend="t", seasonal_order=(1, 0, 0, 6))  # doctest: +SKIP
111     ... )
112     >>> forecaster.fit(y)  # doctest: +SKIP
113     SARIMAX(...)
114     >>> y_pred = forecaster.predict(fh=y.index)  # doctest: +SKIP
115     """
116 
117     _tags = {
118         "ignores-exogeneous-X": False,
119     }
120 
121     def __init__(
122         self,
123         order=(1, 0, 0),
124         seasonal_order=(0, 0, 0, 0),
125         trend="c",
126         measurement_error=False,
127         time_varying_regression=False,
128         mle_regression=True,
129         simple_differencing=False,
130         enforce_stationarity=True,
131         enforce_invertibility=True,
132         hamilton_representation=False,
133         concentrate_scale=False,
134         trend_offset=1,
135         use_exact_diffuse=False,
136         dates=None,
137         freq=None,
138         missing="none",
139         validate_specification=True,
140         random_state=None,
141     ):
142 
143         self.order = order
144         self.seasonal_order = seasonal_order
145         self.trend = trend
146         self.measurement_error = measurement_error
147         self.time_varying_regression = time_varying_regression
148         self.mle_regression = mle_regression
149         self.simple_differencing = simple_differencing
150         self.enforce_stationarity = enforce_stationarity
151         self.enforce_invertibility = enforce_invertibility
152         self.hamilton_representation = hamilton_representation
153         self.concentrate_scale = concentrate_scale
154         self.trend_offset = trend_offset
155         self.use_exact_diffuse = use_exact_diffuse
156         self.dates = dates
157         self.freq = freq
158         self.missing = missing
159         self.validate_specification = validate_specification
160 
161         super().__init__(random_state=random_state)
162 
163     def _fit_forecaster(self, y, X=None):
164         from statsmodels.tsa.api import SARIMAX as _SARIMAX
165 
166         self._forecaster = _SARIMAX(
167             endog=y,
168             exog=X,
169             order=self.order,
170             seasonal_order=self.seasonal_order,
171             trend=self.trend,
172             measurement_error=self.measurement_error,
173             time_varying_regression=self.time_varying_regression,
174             mle_regression=self.mle_regression,
175             simple_differencing=self.simple_differencing,
176             enforce_stationarity=self.enforce_stationarity,
177             enforce_invertibility=self.enforce_invertibility,
178             hamilton_representation=self.hamilton_representation,
179             concentrate_scale=self.concentrate_scale,
180             trend_offset=self.trend_offset,
181             use_exact_diffuse=self.use_exact_diffuse,
182             dates=self.dates,
183             freq=self.freq,
184             missing=self.missing,
185             validate_specification=self.validate_specification,
186         )
187         self._fitted_forecaster = self._forecaster.fit()
188 
189     def summary(self):
190         """Get a summary of the fitted forecaster.
191 
192         This is the same as the implementation in statsmodels:
193         https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_structural_harvey_jaeger.html
194         """
195         return self._fitted_forecaster.summary()
196
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sktime/forecasting/sarimax.py b/sktime/forecasting/sarimax.py
--- a/sktime/forecasting/sarimax.py
+++ b/sktime/forecasting/sarimax.py
@@ -4,7 +4,9 @@
 """Implements SARIMAX."""
 
 __all__ = ["SARIMAX"]
-__author__ = ["TNTran92"]
+__author__ = ["TNTran92", "yarnabrina"]
+
+import pandas as pd
 
 from sktime.forecasting.base.adapters import _StatsModelsAdapter
 
@@ -116,6 +118,7 @@
 
     _tags = {
         "ignores-exogeneous-X": False,
+        "capability:pred_int": True,
     }
 
     def __init__(
@@ -193,3 +196,59 @@
         https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_structural_harvey_jaeger.html
         """
         return self._fitted_forecaster.summary()
+
+    def _predict_interval(self, fh, X=None, coverage=0.95):
+        """Compute/return prediction interval forecasts.
+
+        private _predict_interval containing the core logic,
+            called from predict_interval and default _predict_quantiles
+
+        Parameters
+        ----------
+        fh : guaranteed to be ForecastingHorizon
+            The forecasting horizon with the steps ahead to to predict.
+        X : optional (default=None)
+            guaranteed to be of a type in self.get_tag("X_inner_mtype")
+            Exogeneous time series to predict from.
+        coverage : float or list of float, optional (default=0.95)
+           nominal coverage(s) of predictive interval(s)
+
+        Returns
+        -------
+        pred_int : pd.DataFrame
+            Column has multi-index: first level is variable name from y in fit,
+                second level coverage fractions for which intervals were computed.
+                    in the same order as in input `coverage`.
+                Third level is string "lower" or "upper", for lower/upper interval end.
+            Row index is fh, with additional (upper) levels equal to instance levels,
+                from y seen in fit, if y_inner_mtype is Panel or Hierarchical.
+            Entries are forecasts of lower/upper interval end,
+                for var in col index, at nominal coverage in second col index,
+                lower/upper depending on third col index, for the row index.
+                Upper/lower interval end forecasts are equivalent to
+                quantile forecasts at alpha = 0.5 - c/2, 0.5 + c/2 for c in coverage.
+        """
+        start, end = fh.to_absolute_int(self._y.index[0], self.cutoff)[[0, -1]]
+        valid_indices = fh.to_absolute(self.cutoff).to_pandas()
+
+        prediction_results = self._fitted_forecaster.get_prediction(
+            start=start, end=end, exog=X
+        )
+
+        columns = pd.MultiIndex.from_product(
+            [["Coverage"], coverage, ["lower", "upper"]]
+        )
+        pred_int = pd.DataFrame(index=valid_indices, columns=columns)
+
+        for c in coverage:
+            pred_statsmodels = prediction_results.conf_int(alpha=(1 - c))
+            pred_statsmodels.columns = ["lower", "upper"]
+
+            pred_int[("Coverage", c, "lower")] = pred_statsmodels.loc[
+                valid_indices, "lower"
+            ]
+            pred_int[("Coverage", c, "upper")] = pred_statsmodels.loc[
+                valid_indices, "upper"
+            ]
+
+        return pred_int

{"golden_diff": "diff --git a/sktime/forecasting/sarimax.py b/sktime/forecasting/sarimax.py\n--- a/sktime/forecasting/sarimax.py\n+++ b/sktime/forecasting/sarimax.py\n@@ -4,7 +4,9 @@\n \"\"\"Implements SARIMAX.\"\"\"\n \n __all__ = [\"SARIMAX\"]\n-__author__ = [\"TNTran92\"]\n+__author__ = [\"TNTran92\", \"yarnabrina\"]\n+\n+import pandas as pd\n \n from sktime.forecasting.base.adapters import _StatsModelsAdapter\n \n@@ -116,6 +118,7 @@\n \n     _tags = {\n         \"ignores-exogeneous-X\": False,\n+        \"capability:pred_int\": True,\n     }\n \n     def __init__(\n@@ -193,3 +196,59 @@\n         https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_structural_harvey_jaeger.html\n         \"\"\"\n         return self._fitted_forecaster.summary()\n+\n+    def _predict_interval(self, fh, X=None, coverage=0.95):\n+        \"\"\"Compute/return prediction interval forecasts.\n+\n+        private _predict_interval containing the core logic,\n+            called from predict_interval and default _predict_quantiles\n+\n+        Parameters\n+        ----------\n+        fh : guaranteed to be ForecastingHorizon\n+            The forecasting horizon with the steps ahead to to predict.\n+        X : optional (default=None)\n+            guaranteed to be of a type in self.get_tag(\"X_inner_mtype\")\n+            Exogeneous time series to predict from.\n+        coverage : float or list of float, optional (default=0.95)\n+           nominal coverage(s) of predictive interval(s)\n+\n+        Returns\n+        -------\n+        pred_int : pd.DataFrame\n+            Column has multi-index: first level is variable name from y in fit,\n+                second level coverage fractions for which intervals were computed.\n+                    in the same order as in input `coverage`.\n+                Third level is string \"lower\" or \"upper\", for lower/upper interval end.\n+            Row index is fh, with additional (upper) levels equal to instance levels,\n+                from y seen in fit, if y_inner_mtype is Panel or Hierarchical.\n+            Entries are forecasts of lower/upper interval end,\n+                for var in col index, at nominal coverage in second col index,\n+                lower/upper depending on third col index, for the row index.\n+                Upper/lower interval end forecasts are equivalent to\n+                quantile forecasts at alpha = 0.5 - c/2, 0.5 + c/2 for c in coverage.\n+        \"\"\"\n+        start, end = fh.to_absolute_int(self._y.index[0], self.cutoff)[[0, -1]]\n+        valid_indices = fh.to_absolute(self.cutoff).to_pandas()\n+\n+        prediction_results = self._fitted_forecaster.get_prediction(\n+            start=start, end=end, exog=X\n+        )\n+\n+        columns = pd.MultiIndex.from_product(\n+            [[\"Coverage\"], coverage, [\"lower\", \"upper\"]]\n+        )\n+        pred_int = pd.DataFrame(index=valid_indices, columns=columns)\n+\n+        for c in coverage:\n+            pred_statsmodels = prediction_results.conf_int(alpha=(1 - c))\n+            pred_statsmodels.columns = [\"lower\", \"upper\"]\n+\n+            pred_int[(\"Coverage\", c, \"lower\")] = pred_statsmodels.loc[\n+                valid_indices, \"lower\"\n+            ]\n+            pred_int[(\"Coverage\", c, \"upper\")] = pred_statsmodels.loc[\n+                valid_indices, \"upper\"\n+            ]\n+\n+        return pred_int\n", "issue": "[ENH] `SARIMAX` - implement `predict_interval` or `predict_quantiles` (for `statsmodels` `SARIMAX` interface)\nFrom discord, Huseyin Aytug:\r\n\r\nhi when I want to produce confidence intervals with `SARIMAX`, I get this error:\r\n\r\n`NotImplementedError: SARIMAX does not have the capability to return quantile predictions. If you think this estimator should have the capability, please open an issue on sktime.`\r\n\r\nHowever, it should be possible according to the documentation http://www.sktime.net/en/latest/api_reference/auto_generated/sktime.forecasting.sarimax.SARIMAX.html#sktime.forecasting.sarimax.SARIMAX.predict_interval\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# !/usr/bin/env python3 -u\n# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)\n\"\"\"Implements SARIMAX.\"\"\"\n\n__all__ = [\"SARIMAX\"]\n__author__ = [\"TNTran92\"]\n\nfrom sktime.forecasting.base.adapters import _StatsModelsAdapter\n\n\nclass SARIMAX(_StatsModelsAdapter):\n    \"\"\"SARIMAX forecaster.\n\n    Direct interface for `statsmodels.tsa.api.SARIMAX`.\n\n    Parameters\n    ----------\n    order : iterable or iterable of iterables, optional, default=(1,0,0)\n        The (p,d,q) order of the model for the number of AR parameters,\n        differences, and MA parameters. `d` must be an integer\n        indicating the integration order of the process, while\n        `p` and `q` may either be an integers indicating the AR and MA\n        orders (so that all lags up to those orders are included) or else\n        iterables giving specific AR and / or MA lags to include. Default is\n        an AR(1) model: (1,0,0).\n    seasonal_order : iterable, optional, default=(0,0,0,0)\n        The (P,D,Q,s) order of the seasonal component of the model for the\n        AR parameters, differences, MA parameters, and periodicity.\n        `D` must be an integer indicating the integration order of the process,\n        while `P` and `Q` may either be an integers indicating the AR and MA\n        orders (so that all lags up to those orders are included) or else\n        iterables giving specific AR and / or MA lags to include. `s` is an\n        integer giving the periodicity (number of periods in season), often it\n        is 4 for quarterly data or 12 for monthly data. Default is no seasonal\n        effect.\n    trend : str{'n','c','t','ct'} or iterable, optional, default=\"c\"\n        Parameter controlling the deterministic trend polynomial :math:`A(t)`.\n        Can be specified as a string where 'c' indicates a constant (i.e. a\n        degree zero component of the trend polynomial), 't' indicates a\n        linear trend with time, and 'ct' is both. Can also be specified as an\n        iterable defining the non-zero polynomial exponents to include, in\n        increasing order. For example, `[1,1,0,1]` denotes\n        :math:`a + bt + ct^3`. Default is to not include a trend component.\n    measurement_error : bool, optional, default=False\n        Whether or not to assume the endogenous observations `endog` were\n        measured with error.\n    time_varying_regression : bool, optional, default=False\n        Used when an explanatory variables, `exog`, are provided\n        to select whether or not coefficients on the exogenous regressors are\n        allowed to vary over time.\n    mle_regression : bool, optional, default=True\n        Whether or not to use estimate the regression coefficients for the\n        exogenous variables as part of maximum likelihood estimation or through\n        the Kalman filter (i.e. recursive least squares). If\n        `time_varying_regression` is True, this must be set to False.\n    simple_differencing : bool, optional, default=False\n        Whether or not to use partially conditional maximum likelihood\n        estimation. If True, differencing is performed prior to estimation,\n        which discards the first :math:`s D + d` initial rows but results in a\n        smaller state-space formulation. See the Notes section for important\n        details about interpreting results when this option is used. If False,\n        the full SARIMAX model is put in state-space form so that all\n        datapoints can be used in estimation.\n    enforce_stationarity : bool, optional, default=True\n        Whether or not to transform the AR parameters to enforce stationarity\n        in the autoregressive component of the model.\n    enforce_invertibility : bool, optional, default=True\n        Whether or not to transform the MA parameters to enforce invertibility\n        in the moving average component of the model.\n    hamilton_representation : bool, optional, default=False\n        Whether or not to use the Hamilton representation of an ARMA process\n        (if True) or the Harvey representation (if False).\n    concentrate_scale : bool, optional, default=False\n        Whether or not to concentrate the scale (variance of the error term)\n        out of the likelihood. This reduces the number of parameters estimated\n        by maximum likelihood by one, but standard errors will then not\n        be available for the scale parameter.\n    trend_offset : int, optional, default=1\n        The offset at which to start time trend values. Default is 1, so that\n        if `trend='t'` the trend is equal to 1, 2, ..., nobs. Typically is only\n        set when the model created by extending a previous dataset.\n    use_exact_diffuse : bool, optional, default=False\n        Whether or not to use exact diffuse initialization for non-stationary\n        states. Default is False (in which case approximate diffuse\n        initialization is used).\n    random_state : int, RandomState instance or None, optional ,\n        default=None \u2013 If int, random_state is the seed used by the random\n        number generator; If RandomState instance, random_state is the random\n        number generator; If None, the random number generator is the\n        RandomState instance used by np.random.\n\n    See Also\n    --------\n    ARIMA\n    AutoARIMA\n    StatsForecastAutoARIMA\n\n    References\n    ----------\n    .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles\n    and practice. OTexts, 2014.\n\n    Examples\n    --------\n    >>> from sktime.datasets import load_airline\n    >>> from sktime.forecasting.sarimax import SARIMAX\n    >>> y = load_airline()\n    >>> forecaster = SARIMAX(\n    ...     order=(1, 0, 0), trend=\"t\", seasonal_order=(1, 0, 0, 6))  # doctest: +SKIP\n    ... )\n    >>> forecaster.fit(y)  # doctest: +SKIP\n    SARIMAX(...)\n    >>> y_pred = forecaster.predict(fh=y.index)  # doctest: +SKIP\n    \"\"\"\n\n    _tags = {\n        \"ignores-exogeneous-X\": False,\n    }\n\n    def __init__(\n        self,\n        order=(1, 0, 0),\n        seasonal_order=(0, 0, 0, 0),\n        trend=\"c\",\n        measurement_error=False,\n        time_varying_regression=False,\n        mle_regression=True,\n        simple_differencing=False,\n        enforce_stationarity=True,\n        enforce_invertibility=True,\n        hamilton_representation=False,\n        concentrate_scale=False,\n        trend_offset=1,\n        use_exact_diffuse=False,\n        dates=None,\n        freq=None,\n        missing=\"none\",\n        validate_specification=True,\n        random_state=None,\n    ):\n\n        self.order = order\n        self.seasonal_order = seasonal_order\n        self.trend = trend\n        self.measurement_error = measurement_error\n        self.time_varying_regression = time_varying_regression\n        self.mle_regression = mle_regression\n        self.simple_differencing = simple_differencing\n        self.enforce_stationarity = enforce_stationarity\n        self.enforce_invertibility = enforce_invertibility\n        self.hamilton_representation = hamilton_representation\n        self.concentrate_scale = concentrate_scale\n        self.trend_offset = trend_offset\n        self.use_exact_diffuse = use_exact_diffuse\n        self.dates = dates\n        self.freq = freq\n        self.missing = missing\n        self.validate_specification = validate_specification\n\n        super().__init__(random_state=random_state)\n\n    def _fit_forecaster(self, y, X=None):\n        from statsmodels.tsa.api import SARIMAX as _SARIMAX\n\n        self._forecaster = _SARIMAX(\n            endog=y,\n            exog=X,\n            order=self.order,\n            seasonal_order=self.seasonal_order,\n            trend=self.trend,\n            measurement_error=self.measurement_error,\n            time_varying_regression=self.time_varying_regression,\n            mle_regression=self.mle_regression,\n            simple_differencing=self.simple_differencing,\n            enforce_stationarity=self.enforce_stationarity,\n            enforce_invertibility=self.enforce_invertibility,\n            hamilton_representation=self.hamilton_representation,\n            concentrate_scale=self.concentrate_scale,\n            trend_offset=self.trend_offset,\n            use_exact_diffuse=self.use_exact_diffuse,\n            dates=self.dates,\n            freq=self.freq,\n            missing=self.missing,\n            validate_specification=self.validate_specification,\n        )\n        self._fitted_forecaster = self._forecaster.fit()\n\n    def summary(self):\n        \"\"\"Get a summary of the fitted forecaster.\n\n        This is the same as the implementation in statsmodels:\n        https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_structural_harvey_jaeger.html\n        \"\"\"\n        return self._fitted_forecaster.summary()\n", "path": "sktime/forecasting/sarimax.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# !/usr/bin/env python3 -u\n# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)\n\"\"\"Implements SARIMAX.\"\"\"\n\n__all__ = [\"SARIMAX\"]\n__author__ = [\"TNTran92\", \"yarnabrina\"]\n\nimport pandas as pd\n\nfrom sktime.forecasting.base.adapters import _StatsModelsAdapter\n\n\nclass SARIMAX(_StatsModelsAdapter):\n    \"\"\"SARIMAX forecaster.\n\n    Direct interface for `statsmodels.tsa.api.SARIMAX`.\n\n    Parameters\n    ----------\n    order : iterable or iterable of iterables, optional, default=(1,0,0)\n        The (p,d,q) order of the model for the number of AR parameters,\n        differences, and MA parameters. `d` must be an integer\n        indicating the integration order of the process, while\n        `p` and `q` may either be an integers indicating the AR and MA\n        orders (so that all lags up to those orders are included) or else\n        iterables giving specific AR and / or MA lags to include. Default is\n        an AR(1) model: (1,0,0).\n    seasonal_order : iterable, optional, default=(0,0,0,0)\n        The (P,D,Q,s) order of the seasonal component of the model for the\n        AR parameters, differences, MA parameters, and periodicity.\n        `D` must be an integer indicating the integration order of the process,\n        while `P` and `Q` may either be an integers indicating the AR and MA\n        orders (so that all lags up to those orders are included) or else\n        iterables giving specific AR and / or MA lags to include. `s` is an\n        integer giving the periodicity (number of periods in season), often it\n        is 4 for quarterly data or 12 for monthly data. Default is no seasonal\n        effect.\n    trend : str{'n','c','t','ct'} or iterable, optional, default=\"c\"\n        Parameter controlling the deterministic trend polynomial :math:`A(t)`.\n        Can be specified as a string where 'c' indicates a constant (i.e. a\n        degree zero component of the trend polynomial), 't' indicates a\n        linear trend with time, and 'ct' is both. Can also be specified as an\n        iterable defining the non-zero polynomial exponents to include, in\n        increasing order. For example, `[1,1,0,1]` denotes\n        :math:`a + bt + ct^3`. Default is to not include a trend component.\n    measurement_error : bool, optional, default=False\n        Whether or not to assume the endogenous observations `endog` were\n        measured with error.\n    time_varying_regression : bool, optional, default=False\n        Used when an explanatory variables, `exog`, are provided\n        to select whether or not coefficients on the exogenous regressors are\n        allowed to vary over time.\n    mle_regression : bool, optional, default=True\n        Whether or not to use estimate the regression coefficients for the\n        exogenous variables as part of maximum likelihood estimation or through\n        the Kalman filter (i.e. recursive least squares). If\n        `time_varying_regression` is True, this must be set to False.\n    simple_differencing : bool, optional, default=False\n        Whether or not to use partially conditional maximum likelihood\n        estimation. If True, differencing is performed prior to estimation,\n        which discards the first :math:`s D + d` initial rows but results in a\n        smaller state-space formulation. See the Notes section for important\n        details about interpreting results when this option is used. If False,\n        the full SARIMAX model is put in state-space form so that all\n        datapoints can be used in estimation.\n    enforce_stationarity : bool, optional, default=True\n        Whether or not to transform the AR parameters to enforce stationarity\n        in the autoregressive component of the model.\n    enforce_invertibility : bool, optional, default=True\n        Whether or not to transform the MA parameters to enforce invertibility\n        in the moving average component of the model.\n    hamilton_representation : bool, optional, default=False\n        Whether or not to use the Hamilton representation of an ARMA process\n        (if True) or the Harvey representation (if False).\n    concentrate_scale : bool, optional, default=False\n        Whether or not to concentrate the scale (variance of the error term)\n        out of the likelihood. This reduces the number of parameters estimated\n        by maximum likelihood by one, but standard errors will then not\n        be available for the scale parameter.\n    trend_offset : int, optional, default=1\n        The offset at which to start time trend values. Default is 1, so that\n        if `trend='t'` the trend is equal to 1, 2, ..., nobs. Typically is only\n        set when the model created by extending a previous dataset.\n    use_exact_diffuse : bool, optional, default=False\n        Whether or not to use exact diffuse initialization for non-stationary\n        states. Default is False (in which case approximate diffuse\n        initialization is used).\n    random_state : int, RandomState instance or None, optional ,\n        default=None \u2013 If int, random_state is the seed used by the random\n        number generator; If RandomState instance, random_state is the random\n        number generator; If None, the random number generator is the\n        RandomState instance used by np.random.\n\n    See Also\n    --------\n    ARIMA\n    AutoARIMA\n    StatsForecastAutoARIMA\n\n    References\n    ----------\n    .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles\n    and practice. OTexts, 2014.\n\n    Examples\n    --------\n    >>> from sktime.datasets import load_airline\n    >>> from sktime.forecasting.sarimax import SARIMAX\n    >>> y = load_airline()\n    >>> forecaster = SARIMAX(\n    ...     order=(1, 0, 0), trend=\"t\", seasonal_order=(1, 0, 0, 6))  # doctest: +SKIP\n    ... )\n    >>> forecaster.fit(y)  # doctest: +SKIP\n    SARIMAX(...)\n    >>> y_pred = forecaster.predict(fh=y.index)  # doctest: +SKIP\n    \"\"\"\n\n    _tags = {\n        \"ignores-exogeneous-X\": False,\n        \"capability:pred_int\": True,\n    }\n\n    def __init__(\n        self,\n        order=(1, 0, 0),\n        seasonal_order=(0, 0, 0, 0),\n        trend=\"c\",\n        measurement_error=False,\n        time_varying_regression=False,\n        mle_regression=True,\n        simple_differencing=False,\n        enforce_stationarity=True,\n        enforce_invertibility=True,\n        hamilton_representation=False,\n        concentrate_scale=False,\n        trend_offset=1,\n        use_exact_diffuse=False,\n        dates=None,\n        freq=None,\n        missing=\"none\",\n        validate_specification=True,\n        random_state=None,\n    ):\n\n        self.order = order\n        self.seasonal_order = seasonal_order\n        self.trend = trend\n        self.measurement_error = measurement_error\n        self.time_varying_regression = time_varying_regression\n        self.mle_regression = mle_regression\n        self.simple_differencing = simple_differencing\n        self.enforce_stationarity = enforce_stationarity\n        self.enforce_invertibility = enforce_invertibility\n        self.hamilton_representation = hamilton_representation\n        self.concentrate_scale = concentrate_scale\n        self.trend_offset = trend_offset\n        self.use_exact_diffuse = use_exact_diffuse\n        self.dates = dates\n        self.freq = freq\n        self.missing = missing\n        self.validate_specification = validate_specification\n\n        super().__init__(random_state=random_state)\n\n    def _fit_forecaster(self, y, X=None):\n        from statsmodels.tsa.api import SARIMAX as _SARIMAX\n\n        self._forecaster = _SARIMAX(\n            endog=y,\n            exog=X,\n            order=self.order,\n            seasonal_order=self.seasonal_order,\n            trend=self.trend,\n            measurement_error=self.measurement_error,\n            time_varying_regression=self.time_varying_regression,\n            mle_regression=self.mle_regression,\n            simple_differencing=self.simple_differencing,\n            enforce_stationarity=self.enforce_stationarity,\n            enforce_invertibility=self.enforce_invertibility,\n            hamilton_representation=self.hamilton_representation,\n            concentrate_scale=self.concentrate_scale,\n            trend_offset=self.trend_offset,\n            use_exact_diffuse=self.use_exact_diffuse,\n            dates=self.dates,\n            freq=self.freq,\n            missing=self.missing,\n            validate_specification=self.validate_specification,\n        )\n        self._fitted_forecaster = self._forecaster.fit()\n\n    def summary(self):\n        \"\"\"Get a summary of the fitted forecaster.\n\n        This is the same as the implementation in statsmodels:\n        https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_structural_harvey_jaeger.html\n        \"\"\"\n        return self._fitted_forecaster.summary()\n\n    def _predict_interval(self, fh, X=None, coverage=0.95):\n        \"\"\"Compute/return prediction interval forecasts.\n\n        private _predict_interval containing the core logic,\n            called from predict_interval and default _predict_quantiles\n\n        Parameters\n        ----------\n        fh : guaranteed to be ForecastingHorizon\n            The forecasting horizon with the steps ahead to to predict.\n        X : optional (default=None)\n            guaranteed to be of a type in self.get_tag(\"X_inner_mtype\")\n            Exogeneous time series to predict from.\n        coverage : float or list of float, optional (default=0.95)\n           nominal coverage(s) of predictive interval(s)\n\n        Returns\n        -------\n        pred_int : pd.DataFrame\n            Column has multi-index: first level is variable name from y in fit,\n                second level coverage fractions for which intervals were computed.\n                    in the same order as in input `coverage`.\n                Third level is string \"lower\" or \"upper\", for lower/upper interval end.\n            Row index is fh, with additional (upper) levels equal to instance levels,\n                from y seen in fit, if y_inner_mtype is Panel or Hierarchical.\n            Entries are forecasts of lower/upper interval end,\n                for var in col index, at nominal coverage in second col index,\n                lower/upper depending on third col index, for the row index.\n                Upper/lower interval end forecasts are equivalent to\n                quantile forecasts at alpha = 0.5 - c/2, 0.5 + c/2 for c in coverage.\n        \"\"\"\n        start, end = fh.to_absolute_int(self._y.index[0], self.cutoff)[[0, -1]]\n        valid_indices = fh.to_absolute(self.cutoff).to_pandas()\n\n        prediction_results = self._fitted_forecaster.get_prediction(\n            start=start, end=end, exog=X\n        )\n\n        columns = pd.MultiIndex.from_product(\n            [[\"Coverage\"], coverage, [\"lower\", \"upper\"]]\n        )\n        pred_int = pd.DataFrame(index=valid_indices, columns=columns)\n\n        for c in coverage:\n            pred_statsmodels = prediction_results.conf_int(alpha=(1 - c))\n            pred_statsmodels.columns = [\"lower\", \"upper\"]\n\n            pred_int[(\"Coverage\", c, \"lower\")] = pred_statsmodels.loc[\n                valid_indices, \"lower\"\n            ]\n            pred_int[(\"Coverage\", c, \"upper\")] = pred_statsmodels.loc[\n                valid_indices, \"upper\"\n            ]\n\n        return pred_int\n", "path": "sktime/forecasting/sarimax.py"}]}