Repository: sktime/sktime

Issue:
[BUG] NaiveForecaster fails when sp>1 and fh is combination of in-sample and out-sample
**Describe the bug**
Exception:
```python
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_1832\2346858064.py in <module>
     11 forecaster = NaiveForecaster(sp=2)
     12 forecaster.fit(y_train)
---> 13 forecaster.predict(fh=fh)

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_base.py in predict(self, fh, X, return_pred_int, alpha, keep_old_return_type)
    203         # this is how it is supposed to be after the refactor is complete and effective
    204         if not return_pred_int:
--> 205             y_pred = self._predict(fh=fh, X=X_inner)
    206 
    207             # convert to output mtype, identical with last y mtype seen

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\naive.py in _predict(self, fh, X, return_pred_int, alpha)
    340         """
    341         y_pred = self._forecaster.predict(
--> 342             fh=fh, X=X, return_pred_int=return_pred_int, alpha=alpha
    343         )
    344 

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_base.py in predict(self, fh, X, return_pred_int, alpha, keep_old_return_type)
    203         # this is how it is supposed to be after the refactor is complete and effective
    204         if not return_pred_int:
--> 205             y_pred = self._predict(fh=fh, X=X_inner)
    206 
    207             # convert to output mtype, identical with last y mtype seen

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\compose\_column_ensemble.py in _predict(self, fh, X, return_pred_int, alpha)
    149         y_pred = np.zeros((len(fh), len(self.forecasters_)))
    150         for (_, forecaster, index) in self.forecasters_:
--> 151             y_pred[:, index] = forecaster.predict(fh)
    152 
    153         y_pred = pd.DataFrame(data=y_pred, columns=self.y_columns)

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_base.py in predict(self, fh, X, return_pred_int, alpha, keep_old_return_type)
    203         # this is how it is supposed to be after the refactor is complete and effective
    204         if not return_pred_int:
--> 205             y_pred = self._predict(fh=fh, X=X_inner)
    206 
    207             # convert to output mtype, identical with last y mtype seen

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_sktime.py in _predict(self, fh, X, return_pred_int, alpha)
     86         # both in-sample and out-of-sample values
     87         else:
---> 88             y_ins = self._predict_in_sample(fh.to_in_sample(self.cutoff), **kwargs)
     89             y_oos = self._predict_fixed_cutoff(
     90                 fh.to_out_of_sample(self.cutoff), **kwargs

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_sktime.py in _predict_in_sample(self, fh, X, return_pred_int, alpha)
    145             update_params=False,
    146             return_pred_int=return_pred_int,
--> 147             alpha=alpha,
    148         )
    149 

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_base.py in _predict_moving_cutoff(self, y, cv, X, update_params, return_pred_int, alpha)
   1454                     update_params=update_params,
   1455                     return_pred_int=return_pred_int,
-> 1456                     alpha=alpha,
   1457                 )
   1458                 y_preds.append(y_pred)

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_sktime.py in _update_predict_single(self, y, fh, X, update_params, return_pred_int, alpha)
    217             raise NotImplementedError()
    218         self.update(y, X, update_params=update_params)
--> 219         return self._predict(fh, X, return_pred_int=return_pred_int, alpha=alpha)
    220 
    221 

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_sktime.py in _predict(self, fh, X, return_pred_int, alpha)
     77         if fh.is_all_out_of_sample(self.cutoff):
     78             return self._predict_fixed_cutoff(
---> 79                 fh.to_out_of_sample(self.cutoff), **kwargs
     80             )
     81 

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\base\_sktime.py in _predict_fixed_cutoff(self, fh, X, return_pred_int, alpha)
    111         # assert all(fh > 0)
    112         y_pred = self._predict_last_window(
--> 113             fh, X, return_pred_int=return_pred_int, alpha=alpha
    114         )
    115         index = fh.to_absolute(self.cutoff)

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\naive.py in _predict_last_window(self, fh, X, return_pred_int, alpha)
    131             else:
    132                 # reshape last window, one column per season
--> 133                 last_window = self._reshape_last_window_for_sp(last_window)
    134 
    135                 # select last non-NaN row for every column

C:/Users/X/Desktop/sktime/sktime\sktime\forecasting\naive.py in _reshape_last_window_for_sp(self, last_window)
    202         # reshape last window, one column per season
    203         last_window = last_window.reshape(
--> 204             int(np.ceil(self.window_length_ / self.sp_)), self.sp_
    205         )
    206 

ValueError: cannot reshape array of size 46 into shape (25,2)
```
**To Reproduce**

```python
from sktime.forecasting.naive import NaiveForecaster
from sktime.utils._testing.series import _make_series
from sktime.utils._testing.forecasting import _make_fh
import numpy as np

y_train = _make_series(
    n_columns=1, index_type="period", n_timepoints=50
)
fh = _make_fh(cutoff=y_train.index[-1], steps=np.array([-3, 2]), fh_type="period", is_relative=False)

forecaster = NaiveForecaster(sp=2)
forecaster.fit(y_train)
forecaster.predict(fh=fh)
```

**Expected behavior**
<!--
A clear and concise description of what you expected to happen.
-->

**Additional context**
Bug revealed in #1963 . Bug seems to exist for relative as well as absolute `fh`.

**Versions**
`main`

</details>

<!-- Thanks for contributing! -->



Discussion:
one more bug for the list "bugs that were not detected since only one parameter setting per estimator was tested". Working on upgrading the forecasting tests to avoid this in the future.
In-sample for Naive should be the equivalent of a one-step forecasting horizon, no matter what the out of sample horizon is,  right? 
i.e. *Yt = Yt-1* or *Yt = Yt-m* for seasonal.
yes, for the "last" strategy. Similar for the other strategies.

Resolving patch:
diff --git a/sktime/forecasting/naive.py b/sktime/forecasting/naive.py
--- a/sktime/forecasting/naive.py
+++ b/sktime/forecasting/naive.py
@@ -197,6 +197,9 @@ def _reshape_last_window_for_sp(self, last_window):
             pad_width = self.sp_ - remainder
         else:
             pad_width = 0
+
+        pad_width += self.window_length_ - len(last_window)
+
         last_window = np.hstack([np.full(pad_width, np.nan), last_window])
 
         # reshape last window, one column per season


Test patch: