code: def test_forecast_breakdown(daily_data):
      """Tests ``forecast_breakdown``."""
      model = BaseSilverkiteEstimator()
      train_df = daily_data["train_df"]
      test_df = daily_data["test_df"]
  
      uncertainty_dict = {
          "uncertainty_method": "simple_conditional_residuals",
          "params": {
              "conditional_cols": ["dow_hr"],
              "quantiles": [0.025, 0.975],
              "quantile_estimation_method": "normal_fit",
              "sample_size_thresh": 20,
              "small_sample_size_method": "std_quantiles",
              "small_sample_size_quantile": 0.98,
          },
      }
  
      model.fit(
          X=train_df, time_col=cst.TIME_COL, value_col=cst.VALUE_COL
      )
  
      silverkite = SilverkiteForecast()
      model.model_dict = silverkite.forecast(
          df=train_df,
          time_col=cst.TIME_COL,
          value_col=cst.VALUE_COL,
          origin_for_time_vars=None,
          extra_pred_cols=["ct1", "ct2", "month", "dow"],
          train_test_thresh=None,
          training_fraction=None,
          fit_algorithm="linear",
          fit_algorithm_params=None,
          daily_event_df_dict=None,
          changepoints_dict=None,
          fs_components_df=None,
          autoreg_dict=None,
          min_admissible_value=None,
          max_admissible_value=None,
          uncertainty_dict=uncertainty_dict,
      )
      model.finish_fit()
      coef = model.model_dict["ml_model"].coef_
      assert len(coef) == 5
  
      pred_df = model.predict(test_df)
      cols = [
          cst.TIME_COL,
          cst.QUANTILE_SUMMARY_COL,
          cst.ERR_STD_COL,
          cst.PREDICTED_LOWER_COL,
          cst.PREDICTED_UPPER_COL,
      ]
      assert_equal(model.forecast[cols], pred_df[cols])
      assert (
          model.forecast["y"].values == pred_df["forecast"].values
      ).all()
  
      forecast_x_mat = model.forecast_x_mat
      assert list(forecast_x_mat.columns) == [
          "Intercept",
          "ct1",
          "ct2",
          "month",
          "dow",
      ]
      assert len(forecast_x_mat) == len(pred_df)
  
      grouping_regex_patterns_dict = {
          "seasonality": ".*month.*|dow",
          "growth": "ct1|ct2",
      }
  
      # applies to estimator with original forecasts
      breakdown_result = model.forecast_breakdown(
          grouping_regex_patterns_dict=grouping_regex_patterns_dict
      )
  
      column_grouping_result = breakdown_result[
          "column_grouping_result"
      ]
      breakdown_df = breakdown_result["breakdown_df"]
      breakdown_fig = breakdown_result["breakdown_fig"]
      assert breakdown_df.shape == (len(forecast_x_mat), 3)
      assert breakdown_fig.layout.title.text == "breakdown of forecasts"
      assert len(breakdown_fig.data) == 3
      assert list(breakdown_df.columns) == [
          "Intercept",
          "seasonality",
          "growth",
      ]
      assert column_grouping_result == {
          "str_groups": [["month", "dow"], ["ct1", "ct2"]],
          "remainder": [],
      }
  
      # Applies to estimator with passed ``forecast_x_mat``
      # In this case, we do not pass the time values
      # Therefore a generic index (0 to n) will be used in creating the figure
      breakdown_result = model.forecast_breakdown(
          grouping_regex_patterns_dict=grouping_regex_patterns_dict,
          forecast_x_mat=forecast_x_mat.head(10),
      )
  
      breakdown_df = breakdown_result["breakdown_df"]
      column_grouping_result = breakdown_result[
          "column_grouping_result"
      ]
      breakdown_df = breakdown_result["breakdown_df"]
      breakdown_fig = breakdown_result["breakdown_fig"]
      assert breakdown_df.shape == (10, 3)
      assert breakdown_fig.layout.title.text == "breakdown of forecasts"
      assert len(breakdown_fig.data) == 3
      assert list(breakdown_df.columns) == [
          "Intercept",
          "seasonality",
          "growth",
      ]
      assert column_grouping_result == {
          "str_groups": [["month", "dow"], ["ct1", "ct2"]],
          "remainder": [],
      }
  
      # Makes sure ``forecast_x_mat`` is not over-written
      # as a result of applying ``forecast_breakdown``
      forecast_x_mat = model.forecast_x_mat
      assert len(forecast_x_mat) == len(pred_df)
  
      # Applies to estimator with passed ``forecast_x_mat``
      # We pass the appropriate timestamps too by extracting from ``pred_df``
      breakdown_result = model.forecast_breakdown(
          grouping_regex_patterns_dict=grouping_regex_patterns_dict,
          forecast_x_mat=forecast_x_mat.head(10),
          time_values=pred_df.head(10)[cst.TIME_COL],
      )
  
      breakdown_df = breakdown_result["breakdown_df"]
      column_grouping_result = breakdown_result[
          "column_grouping_result"
      ]
      breakdown_df = breakdown_result["breakdown_df"]
      breakdown_fig = breakdown_result["breakdown_fig"]
      assert breakdown_df.shape == (10, 3)
      assert breakdown_fig.layout.title.text == "breakdown of forecasts"
      assert len(breakdown_fig.data) == 3
      assert list(breakdown_df.columns) == [
          "Intercept",
          "seasonality",
          "growth",
      ]
      assert column_grouping_result == {
          "str_groups": [["month", "dow"], ["ct1", "ct2"]],
          "remainder": [],
      }
  
imports: import datetime
  import numpy
  import pandas
  import pytest
  from sklearn.exceptions import NotFittedError
  from sklearn.metrics import mean_absolute_error
  from sklearn.metrics import mean_squared_error
  from testfixtures import LogCapture
  import greykite.common.constants
  from greykite.algo.forecast.silverkite.forecast_silverkite import SilverkiteForecast
  from greykite.common.data_loader import DataLoader
  from greykite.common.features.timeseries_features import convert_date_to_continuous_time
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import daily_data_reg
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
  from greykite.sklearn.estimator.base_silverkite_estimator import BaseSilverkiteEstimator
  from greykite.sklearn.estimator.testing_utils import params_component_breakdowns
  from greykite.sklearn.estimator.testing_utils import params_components
label_desc: Use image node_id 23 for calling a global function with example usage: test_forecast_breakdown(daily_data) without return types