code: def test_fit_ml_model_with_uncertainty_heteroscedastic():
      """Testing the uncertainty model fits using homoscedastic
      and heteroscedastic"""
      data = generate_test_data_for_fitting(
          n=1000, seed=41, heteroscedastic=True
      )
  
      df = data["df"]
      model_formula_str = data["model_formula_str"]
      df_test = data["df_test"].reset_index(drop=True)
      fut_df = df_test.copy()
      fut_df["y"] = None
  
      def ci_width_and_coverage(conditional_cols, df, fut_df):
          """Fits two types of uncertainty model depending
          on the input of conditional_cols"""
          trained_model = fit_ml_model(
              df=df,
              model_formula_str=model_formula_str,
              uncertainty_dict={
                  "uncertainty_method": "simple_conditional_residuals",
                  "params": {
                      "conditional_cols": conditional_cols,
                      "quantiles": [0.025, 0.975],
                      "quantile_estimation_method": "normal_fit",
                      "sample_size_thresh": 50,
                      "small_sample_size_method": "std_quantiles",
                      "small_sample_size_quantile": 0.95,
                  },
              },
          )
  
          pred_res = predict_ml_with_uncertainty(
              fut_df=fut_df, trained_model=trained_model
          )
          fut_df = pred_res["fut_df"]
          y_test_pred = fut_df["y"]
  
          # testing actual values for a small set
          ind = [1, 300, 500, 700, 950]
          expected_values = [11.01, 9.88, 14.32, 17.68, 10.88]
          assert (
              list(y_test_pred.iloc[ind].round(2)) == expected_values
          ), "predicted values are not as expected."
  
          # calculate coverage of the CI
          # first add true values to fut_df
          fut_df["y_true"] = df_test["y"]
          fut_df["inside_95_ci"] = fut_df.apply(
              lambda row: (
                  (row["y_true"] <= row[QUANTILE_SUMMARY_COL][1])
                  and (row["y_true"] >= row[QUANTILE_SUMMARY_COL][0])
              ),
              axis=1,
          )
  
          fut_df["ci_width"] = fut_df.apply(
              lambda row: (
                  (
                      row[QUANTILE_SUMMARY_COL][1]
                      - row[QUANTILE_SUMMARY_COL][0]
                  )
              ),
              axis=1,
          )
          ci_width_avg = fut_df["ci_width"].mean()
  
          fut_df[QUANTILE_SUMMARY_COL] = fut_df[
              QUANTILE_SUMMARY_COL
          ].apply(lambda x: tuple(round(e, 2) for e in x))
          ci_coverage = 100.0 * fut_df["inside_95_ci"].mean()
  
          return {
              "ci_width_avg": ci_width_avg,
              "ci_coverage": ci_coverage,
          }
  
      # fitting homoscedastic (without conditioning) uncertainty model
      ci_info = ci_width_and_coverage(
          conditional_cols=None, df=df, fut_df=fut_df
      )
      ci_coverage = ci_info["ci_coverage"]
      ci_width_avg = ci_info["ci_width_avg"]
      assert (
          round(ci_coverage, 1) == 94.7
      ), "95 percent CI coverage is not as expected"
      assert (
          round(ci_width_avg, 1) == 22.6
      ), "95 percent CI coverage average width is not as expected"
  
      # fitting heteroscedastic (with conditioning) uncertainty model
      ci_info = ci_width_and_coverage(
          conditional_cols=["x1_categ"], df=df, fut_df=fut_df
      )
      ci_coverage = ci_info["ci_coverage"]
      ci_width_avg = ci_info["ci_width_avg"]
      # we observe better coverage is higher and ci width is narrower with
      # heteroscedastic model than before
      assert (
          round(ci_coverage, 1) == 96.5
      ), "95 percent CI coverage is not as expected"
      assert (
          round(ci_width_avg, 1) == 20.5
      ), "95 percent CI coverage average width is not as expected"
  
imports: import warnings
  import numpy
  import pandas
  import pytest
  import scipy
  from pandas.testing import assert_frame_equal
  from patsy import dmatrices
  from greykite.algo.common.ml_models import breakdown_regression_based_prediction
  from greykite.algo.common.ml_models import design_mat_from_formula
  from greykite.algo.common.ml_models import fit_ml_model
  from greykite.algo.common.ml_models import fit_ml_model_with_evaluation
  from greykite.algo.common.ml_models import fit_model_via_design_matrix
  from greykite.algo.common.ml_models import get_h_mat
  from greykite.algo.common.ml_models import get_intercept_col_from_design_mat
  from greykite.algo.common.ml_models import predict_ml
  from greykite.algo.common.ml_models import predict_ml_with_uncertainty
  from greykite.algo.uncertainty.conditional.conf_interval import predict_ci
  from greykite.common.constants import ERR_STD_COL
  from greykite.common.constants import QUANTILE_SUMMARY_COL
  from greykite.common.constants import TimeFeaturesEnum
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.evaluation import calc_pred_err
  from greykite.common.features.timeseries_features import build_time_features_df
  from greykite.common.features.timeseries_features import fourier_series_multi_fcn
  from greykite.common.features.timeseries_features import get_fourier_col_name
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import gen_sliced_df
label_desc: Use image node_id 19 for calling a global function with example usage: test_fit_ml_model_with_uncertainty_heteroscedastic() and returns: dict