Repository: sktime/sktime

Issue:
[BUG] `ThetaForecaster` doesn't work inside `ColumnEnsembleForecaster`
**Describe the bug**
`ThetaForecaster` doesn't work with `ColumnEnsembleForecaster`, the forecasting horizon is not picked up correctly in the underlying forecasters inside the `ColumnEnsembleForecaster`.

**To Reproduce**
```python
import numpy as np

from sktime.forecasting.compose import ColumnEnsembleForecaster
from sktime.forecasting.model_selection import temporal_train_test_split
from sktime.forecasting.theta import ThetaForecaster
from sktime.utils._testing.series import _make_series

y = _make_series(n_columns=3)
y_train, y_test = temporal_train_test_split(y)
fh = np.arange(len(y_test)) + 1
f = ColumnEnsembleForecaster(ThetaForecaster(sp=12))
f.fit(y_train)
f.predict(fh=fh)
```

**Expected behavior**
It should produce an array of predictions for each of the columns. It seems that when computing the drift in the underlying theta forecasters it cannot find the forecasting horizon.

**Versions**
System:
    python: 3.8.12

Python dependencies:
          pip: 21.2.2
   setuptools: 58.0.4
      sklearn: 1.0.2
       sktime: 0.11.0
  statsmodels: 0.13.2
        numpy: 1.21.5
        scipy: 1.7.3
       pandas: 1.4.1
   matplotlib: 3.5.1
       joblib: 1.1.0
        numba: 0.55.1
     pmdarima: 1.8.4
      tsfresh: 0.19.0



Discussion:
Yes, I have seen the bug before, and I remember that I had fixed it.

The argument of `_by_columns` should be the outer methods, not the inner methods.

It is weird why this is not on main. Perhaps it is in some PR that got stalled because no one reviewed and I forgot it?

Resolving patch:
diff --git a/sktime/forecasting/compose/_column_ensemble.py b/sktime/forecasting/compose/_column_ensemble.py
--- a/sktime/forecasting/compose/_column_ensemble.py
+++ b/sktime/forecasting/compose/_column_ensemble.py
@@ -196,7 +196,7 @@ def _predict(self, fh=None, X=None):
         y_pred : pd.Series
             Point predictions
         """
-        return self._by_column("_predict", fh=fh, X=X)
+        return self._by_column("predict", fh=fh, X=X)
 
     def _predict_quantiles(self, fh=None, X=None, alpha=None):
         """Compute/return prediction quantiles for a forecast.
@@ -230,7 +230,7 @@ def _predict_quantiles(self, fh=None, X=None, alpha=None):
             Row index is fh. Entries are quantile forecasts, for var in col index,
                 at quantile probability in second-level col index, for each row index.
         """
-        return self._by_column("_predict_quantiles", fh=fh, X=X, alpha=alpha)
+        return self._by_column("predict_quantiles", fh=fh, X=X, alpha=alpha)
 
     def _predict_interval(self, fh=None, X=None, coverage=None):
         """Compute/return prediction quantiles for a forecast.
@@ -268,7 +268,7 @@ def _predict_interval(self, fh=None, X=None, coverage=None):
                 Upper/lower interval end forecasts are equivalent to
                 quantile forecasts at alpha = 0.5 - c/2, 0.5 + c/2 for c in coverage.
         """
-        return self._by_column("_predict_interval", fh=fh, X=X, coverage=coverage)
+        return self._by_column("predict_interval", fh=fh, X=X, coverage=coverage)
 
     def _predict_var(self, fh, X=None, cov=False):
         """Forecast variance at future horizon.
@@ -300,7 +300,7 @@ def _predict_var(self, fh, X=None, cov=False):
                 Entries are (co-)variance forecasts, for var in col index, and
                     covariance between time index in row and col.
         """
-        return self._by_column("_predict_var", fh=fh, X=X, cov=cov)
+        return self._by_column("predict_var", fh=fh, X=X, cov=cov)
 
     def get_params(self, deep=True):
         """Get parameters of estimator in `_forecasters`.


Test patch: