Repository: alteryx/evalml (python)

Issue:
Multiseries prediction interval labels includes target name twice
When generating the prediction interval labels for multiseries pipelines with STL decomposers, a KeyError is generated. This is due to the function trying to find a key that includes the target name twice (e.g. {{target|target|series_a}} instead of {{target|series_a}}). 

Pull request:
Fixed multiseries prediction interval labels
Resolves #4378 

Patch:
diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst
index 3b0cc5ee..4dda45a7 100644
--- a/docs/source/release_notes.rst
+++ b/docs/source/release_notes.rst
@@ -4,6 +4,7 @@ Release Notes
     * Enhancements
     * Fixes
         * Fixed bug in `_downcast_nullable_y` causing woodwork initialization issues :pr:`4369`
+        * Fixed multiseries prediction interval labels :pr:`4377`
     * Changes
         * Pinned scipy version to under 1.12.0 :pr:`4380`
     * Documentation Changes
diff --git a/evalml/pipelines/components/transformers/preprocessing/stl_decomposer.py b/evalml/pipelines/components/transformers/preprocessing/stl_decomposer.py
index 2646db99..76b8f4f3 100644
--- a/evalml/pipelines/components/transformers/preprocessing/stl_decomposer.py
+++ b/evalml/pipelines/components/transformers/preprocessing/stl_decomposer.py
@@ -340,6 +340,7 @@ class STLDecomposer(Decomposer):
         # Convert the list to a DataFrame
         # For multiseries, return tuple[pd.DataFrame, pd.Dataframe] where each column is a series_id
         detrending_df = pd.DataFrame(detrending_list).T
+        detrending_df.columns = y.columns
         return X, detrending_df
 
     def inverse_transform(
diff --git a/evalml/pipelines/time_series_regression_pipeline.py b/evalml/pipelines/time_series_regression_pipeline.py
index 92d0fda8..60a5e61c 100644
--- a/evalml/pipelines/time_series_regression_pipeline.py
+++ b/evalml/pipelines/time_series_regression_pipeline.py
@@ -226,7 +226,6 @@ class TimeSeriesRegressionPipeline(TimeSeriesPipelineBase):
 
             if self.problem_type == ProblemTypes.MULTISERIES_TIME_SERIES_REGRESSION:
                 from evalml.pipelines.utils import (
-                    MULTISERIES_SEPARATOR_SYMBOL,
                     stack_data,
                     unstack_multiseries,
                 )
@@ -271,11 +270,7 @@ class TimeSeriesRegressionPipeline(TimeSeriesPipelineBase):
 
                 # `pred_intervals` are in {series_id: {coverage_label: bound_value}} form
                 for series_id, series_intervals in pred_intervals.items():
-                    series_id_target_name = (
-                        self.input_target_name
-                        + MULTISERIES_SEPARATOR_SYMBOL
-                        + str(series_id)
-                    )
+                    series_id_target_name = str(series_id)
                     series_id_prediction_intervals = _get_series_intervals(
                         series_intervals,
                         residuals[series_id],


Test patch:
diff --git a/evalml/tests/component_tests/decomposer_tests/test_stl_decomposer.py b/evalml/tests/component_tests/decomposer_tests/test_stl_decomposer.py
index 6e17067d..b102dceb 100644
--- a/evalml/tests/component_tests/decomposer_tests/test_stl_decomposer.py
+++ b/evalml/tests/component_tests/decomposer_tests/test_stl_decomposer.py
@@ -148,8 +148,15 @@ def test_stl_fit_transform_in_sample(
 
     stl = STLDecomposer(period=period)
 
+    series_id_columns = ["series_1", "series_2"]
+    if variateness == "multivariate":
+        y.columns = series_id_columns
+
     X_t, y_t = stl.fit_transform(X, y)
 
+    if variateness == "multivariate":
+        assert all(y_t.columns == series_id_columns)
+
     # If y_t is a pd.Series, give it columns
     if isinstance(y_t, pd.Series):
         y_t = y_t.to_frame()
@@ -179,7 +186,11 @@ def test_stl_fit_transform_in_sample(
         # Check the trend to make sure STL worked properly
         pd.testing.assert_series_equal(
             pd.Series(expected_trend),
-            pd.Series(stl.trends[0]),
+            pd.Series(
+                stl.trends["series_1"]
+                if variateness == "multivariate"
+                else stl.trends[0],
+            ),
             check_exact=False,
             check_index=False,
             check_names=False,
diff --git a/evalml/tests/pipeline_tests/regression_pipeline_tests/test_multiseries_regression_pipeline.py b/evalml/tests/pipeline_tests/regression_pipeline_tests/test_multiseries_regression_pipeline.py
index f092da76..e777c539 100644
--- a/evalml/tests/pipeline_tests/regression_pipeline_tests/test_multiseries_regression_pipeline.py
+++ b/evalml/tests/pipeline_tests/regression_pipeline_tests/test_multiseries_regression_pipeline.py
@@ -347,7 +347,7 @@ def test_time_series_pipeline_get_prediction_intervals(
     )
     X_train, y_train = X[:65], y[:65]
     X_validation, y_validation = X[65:], y[65:]
-    mock_X, _ = unstack_multiseries(
+    mock_X, mock_y = unstack_multiseries(
         X_train,
         y_train,
         series_id="series_id",
@@ -356,7 +356,7 @@ def test_time_series_pipeline_get_prediction_intervals(
     )
     mock_transform_return_value = (
         mock_X,
-        pd.DataFrame(np.random.rand(13, 5)),
+        mock_y,
     )
     with patch(
         "evalml.pipelines.components.transformers.preprocessing.stl_decomposer.STLDecomposer.transform",