code: def test_fit_ml_model():
      """Tests ``fit_ml_model``"""
      data = generate_test_data_for_fitting()
      df = data["df"]
      model_formula_str = data["model_formula_str"]
      y_test = data["y_test"]
      df_test = data["df_test"]
      y_col = "y"
  
      trained_model = fit_ml_model(
          df=df,
          model_formula_str=model_formula_str,
          fit_algorithm="sgd",
          fit_algorithm_params={"alpha": 0.1},
      )
  
      assert list(trained_model.keys()) == [
          "y",
          "y_mean",
          "y_std",
          "x_design_info",
          "ml_model",
          "uncertainty_model",
          "ml_model_summary",
          "y_col",
          "x_mat",
          "min_admissible_value",
          "max_admissible_value",
          "normalize_df_func",
          "regression_weight_col",
          "drop_intercept_col",
          "alpha",
          "h_mat",
          "p_effective",
          "sigma_scaler",
          "x_mean",
          "fitted_df",
      ]
  
      assert (trained_model["y"] == df["y"]).all()
      assert trained_model["y_mean"] == np.mean(df["y"])
      assert trained_model["y_std"] == np.std(df["y"])
  
      pred_res = predict_ml(fut_df=df_test, trained_model=trained_model)
  
      pred_df = pred_res["fut_df"]
  
      input_cols = ["x1", "x2", "x3", "x4", "x1_categ"]
      assert_frame_equal(
          pred_df[input_cols].reset_index(drop=True),
          df_test[input_cols].reset_index(drop=True),
      )
  
      y_test_pred = pred_df[y_col]
  
      assert trained_model["ml_model"].alpha == 0.1
  
      err = calc_pred_err(y_test, y_test_pred)
      enum = EvaluationMetricEnum.MeanAbsoluteError
      assert round(err[enum.get_metric_name()]) == 6.0
      enum = EvaluationMetricEnum.RootMeanSquaredError
      assert round(err[enum.get_metric_name()]) == 7.0
      enum = EvaluationMetricEnum.Correlation
      assert err[enum.get_metric_name()] > 0.5
  
      # Tests if ``fitted_df`` returned is correct
      pred_res = predict_ml(fut_df=df, trained_model=trained_model)
  
      fitted_df_via_predict = pred_res["fut_df"]
      x_mat_via_predict = pred_res["x_mat"]
  
      assert trained_model["fitted_df"].equals(fitted_df_via_predict)
      # Tests if the design matrix in the prediction time is correct
      # by comparing to the ``x_mat`` from fit phase using training data
      assert (
          trained_model["x_mat"]
          .reset_index(drop=True)
          .equals(x_mat_via_predict.reset_index(drop=True))
      )
  
      ml_model = trained_model["ml_model"]
      ml_model_coef = ml_model.coef_
      intercept = ml_model.intercept_
      x_mat_via_predict_weighted = x_mat_via_predict * ml_model_coef
      # Checks to see if the manually calculated forecast is consistent
      # Note that intercept from the regression based ML model needs to be aded
      calculated_pred = (
          x_mat_via_predict_weighted.sum(axis=1) + intercept
      )
      assert (
          max(abs(calculated_pred - fitted_df_via_predict["y"])) < 1e-5
      )
  
      # Tests actual values for a smaller set
      y_test_pred = predict_ml(
          fut_df=df_test[:10], trained_model=trained_model
      )["fut_df"][y_col]
  
      expected_values = [
          9.0,
          9.0,
          7.0,
          10.0,
          10.0,
          10.0,
          11.0,
          9.0,
          8.0,
          6.0,
      ]
      assert list(y_test_pred.round()) == expected_values
  
      ml_model_summary = trained_model["ml_model_summary"].round(2)
      assert list(ml_model_summary["variable"].values) == [
          "Intercept",
          "x1",
          "x2",
          "x3",
          "x4",
      ]
      assert list(ml_model_summary["coef"].round().values) == [
          -0.0,
          -0.0,
          2.0,
          1.0,
          10.0,
      ]
  
      # Testing the summary returned from statsmodels.
      # The summary in this case is very informative with several tables.
      # `table[1]` inlcudes the cofficients and p-values.
      # Parameters without p-values are available directly
      # through `trained_model["ml_model"].params` (names and coefficients).
      # However `summary` does include more information (eg p-values) which is desirable.
      # Here we test those values even though it is harder to get them through `summary`.
      trained_model = fit_ml_model(
          df=df,
          model_formula_str=model_formula_str,
          fit_algorithm="statsmodels_ols",
          fit_algorithm_params={"alpha": 0.1},
      )
  
      ml_model_summary = trained_model["ml_model_summary"]
      ml_model_summary_table = ml_model_summary.tables[1]
      assert ml_model_summary_table[0].data == (
          ["", "coef", "std err", "t", "P>|t|", "[0.025", "0.975]"]
      )
      assert ml_model_summary_table[1].data == (
          [
              "Intercept",
              "  -26.5445",
              "    0.456",
              "  -58.197",
              " 0.000",
              "  -27.440",
              "  -25.649",
          ]
      )
      assert ml_model_summary_table[2].data == (
          [
              "x1",
              "    0.5335",
              "    0.409",
              "    1.304",
              " 0.192",
              "   -0.269",
              "    1.336",
          ]
      )
  
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 15 for calling a global function with example usage: test_fit_ml_model() without return types