code: def ts_model_validation(model_results):
      """
      Once you have built a time series model, how to validate it. This utility attempts to.
      This is only done on SARIMAX models from statsmodels. Don't try it on other models.
      The input is model_results which is the variable assigned to the model.fit() method.
      """
      het_method = "breakvar"
      norm_method = "jarquebera"
      sercor_method = "ljungbox"
      ########################
      (het_stat, het_p) = model_results.test_heteroskedasticity(
          het_method
      )[0]
      norm_stat, norm_p, skew, kurtosis = model_results.test_normality(
          norm_method
      )[0]
      sercor_stat, sercor_p = model_results.test_serial_correlation(
          method=sercor_method
      )[0]
      sercor_stat = sercor_stat[-1]  # last number for the largest lag
      sercor_p = sercor_p[-1]  # last number for the largest lag
  
      # Run Durbin-Watson test on the standardized residuals.
      # The statistic is approximately equal to 2*(1-r), where r is the sample autocorrelation of the residuals.
      # Thus, for r == 0, indicating no serial correlation, the test statistic equals 2.
      # This statistic will always be between 0 and 4. The closer to 0 the statistic,
      # the more evidence for positive serial correlation. The closer to 4,
      # the more evidence for negative serial correlation.
      # Essentially, below 1 or above 3 is bad.
  
      # TODO: Checdk statsmodel is not loaded as sm.
      dw = sm.stats.stattools.durbin_watson(
          model_results.filter_results.standardized_forecasts_error[
              0, model_results.loglikelihood_burn :
          ]
      )
  
      # check whether roots are outside the unit circle (we want them to be);
      # will be True when AR is not used (i.e., AR order = 0)
      arroots_outside_unit_circle = np.all(
          np.abs(model_results.arroots) > 1
      )
      # will be True when MA is not used (i.e., MA order = 0)
      maroots_outside_unit_circle = np.all(
          np.abs(model_results.maroots) > 1
      )
  
      print(
          "Test heteroskedasticity of residuals ({}): stat={:.3f}, p={:.3f}".format(
              het_method, het_stat, het_p
          )
      )
      print(
          "\nTest normality of residuals ({}): stat={:.3f}, p={:.3f}".format(
              norm_method, norm_stat, norm_p
          )
      )
      print(
          "\nTest serial correlation of residuals ({}): stat={:.3f}, p={:.3f}".format(
              sercor_method, sercor_stat, sercor_p
          )
      )
      print(
          "\nDurbin-Watson test on residuals: d={:.2f}\n\t(NB: 2 means no serial correlation, 0=pos, 4=neg)".format(
              dw
          )
      )
      print(
          "\nTest for all AR roots outside unit circle (>1): {}".format(
              arroots_outside_unit_circle
          )
      )
      print(
          "\nTest for all MA roots outside unit circle (>1): {}".format(
              maroots_outside_unit_circle
          )
      )
  
file_path: Auto_TS/auto_ts/utils/val.py
imports: import numpy
  import pandas
  import matplotlib.pyplot
  import seaborn
  from sklearn.model_selection import TimeSeriesSplit
  from sklearn.model_selection import GridSearchCV
  import pdb
label_desc: Use image node_id 3 for calling a global function with example usage: ts_model_validation(model_results) without return types