Repository: sktime/sktime

Issue:
[BUG] ConformalIntervals wrapped ARIMA/AutoARIMA breaks with default parameters
### Discussed in https://github.com/alan-turing-institute/sktime/discussions/2869

<div type='discussions-op-text'>

<sup>Originally posted by **linaamic** June 26, 2022</sup>
Hi everyone, I am currently trying out the ConformalIntervals feature from sktime.forecasting. However, I can't get it to work for both ARIMA and AutoARIMA. Is there an inherent difference between ARIMA forecasters and others? Do I have to call or wrap them differently or is ConformalPrediction not possible with ARIMA?
With other forecasters I have no issues.

This is the error I get:
File "...\site-packages\statsmodels\tsa\statespace\sarimax.py", line 843, in _conditional_sum_squares
    Y = endog[r:]
IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed

Code:
```python
from sktime.datasets import load_airline
from sktime.forecasting.arima import AutoARIMA, ARIMA
from sktime.forecasting.conformal import ConformalIntervals

y = load_airline()
trial_forecaster = AutoARIMA()
conformal_forecaster = ConformalIntervals(trial_forecaster, method="conformal")
conformal_forecaster.fit(y, fh=[1,2,3])
```

Any help is much appreciated! </div>


Discussion:

Resolving patch:
diff --git a/sktime/forecasting/conformal.py b/sktime/forecasting/conformal.py
--- a/sktime/forecasting/conformal.py
+++ b/sktime/forecasting/conformal.py
@@ -8,6 +8,7 @@
 __all__ = ["ConformalIntervals"]
 __author__ = ["fkiraly", "bethrice44"]
 
+from math import floor
 from warnings import warn
 
 import numpy as np
@@ -53,8 +54,12 @@ class ConformalIntervals(BaseForecaster):
             Caveat: this does not give frequentist but conformal predictive intervals
         "conformal": as in Stankeviciute et al, but with H=1,
             i.e., no Bonferroni correction under number of indices in the horizon
-    initial_window : int, optional, default=1
-        number of minimum initial indices to use for fitting when computing residuals
+    initial_window : float, int or None, optional (default=max(10, 0.1*len(y)))
+        Defines the size of the initial training window
+        If float, should be between 0.0 and 1.0 and represent the proportion
+        of the dataset to include for the initial window for the train split.
+        If int, represents the relative number of train samples in the initial window.
+        If None, the value is set to the larger of 0.1*len(y) and 10
     sample_frac : float, optional, default=None
         value in range (0,1) corresponding to fraction of y index to calculate
         residuals matrix values for (for speeding up calculation)
@@ -273,6 +278,39 @@ def _predict_quantiles(self, fh, X, alpha):
 
         return pred_int
 
+    def _parse_initial_window(self, y, initial_window=None):
+
+        n_samples = len(y)
+
+        if initial_window is None:
+            initial_window = max(10, 0.1 * n_samples)
+
+        initial_window_type = np.asarray(initial_window).dtype.kind
+
+        if (
+            initial_window_type == "i"
+            and (initial_window >= n_samples or initial_window <= 0)
+            or initial_window_type == "f"
+            and (initial_window <= 0 or initial_window >= 1)
+        ):
+            raise ValueError(
+                "initial_window={0} should be either positive and smaller"
+                " than the number of samples {1} or a float in the "
+                "(0, 1) range".format(initial_window, n_samples)
+            )
+
+        if initial_window is not None and initial_window_type not in ("i", "f"):
+            raise ValueError(
+                "Invalid value for initial_window: {}".format(initial_window)
+            )
+
+        if initial_window_type == "f":
+            n_initial_window = int(floor(initial_window * n_samples))
+        elif initial_window_type == "i":
+            n_initial_window = int(initial_window)
+
+        return n_initial_window
+
     def _compute_sliding_residuals(self, y, X, forecaster, initial_window, sample_frac):
         """Compute sliding residuals used in uncertainty estimates.
 
@@ -284,10 +322,15 @@ def _compute_sliding_residuals(self, y, X, forecaster, initial_window, sample_fr
             sktime compatible exogeneous time series to use in forecasts
         forecaster : sktime compatible forecaster
             forecaster to use in computing the sliding residuals
-        initial_window : int
-            minimum length of initial window to use in fitting
+        initial_window : float, int or None, optional (default=max(10, 0.1*len(y)))
+            Defines the size of the initial training window
+            If float, should be between 0.0 and 1.0 and represent the proportion
+            of the dataset to include for the initial window for the train split.
+            If int, represents the relative number of train samples in the
+            initial window.
+            If None, the value is set to the larger of 0.1*len(y) and 10
         sample_frac : float
-            for speeding up computing of residuals matrix.
+            For speeding up computing of residuals matrix.
             sample value in range (0, 1) to obtain a fraction of y indices to
             compute residuals matrix for
         Returns
@@ -300,7 +343,9 @@ def _compute_sliding_residuals(self, y, X, forecaster, initial_window, sample_fr
         """
         y = convert_to(y, "pd.Series")
 
-        y_index = y.index[initial_window:]
+        n_initial_window = self._parse_initial_window(y, initial_window=initial_window)
+
+        y_index = y.iloc[n_initial_window:].index
 
         residuals_matrix = pd.DataFrame(columns=y_index, index=y_index, dtype="float")
 


Test patch: