code: def r2_null_model_score(
      y_true,
      y_pred,
      y_pred_null=None,
      y_train=None,
      loss_func=mean_squared_error,
  ):
      """Calculates improvement in the loss function compared
      to the predictions of a null model. Can be used to evaluate
      model quality with respect to a simple baseline model.
  
      The score is defined as::
  
          R2_null_model_score = 1.0 - loss_func(y_true, y_pred) / loss_func(y_true, y_pred_null)
  
      Parameters
      ----------
      y_true : `list` [`float`] or `numpy.array`
          Observed response (usually on a test set).
      y_pred : `list` [`float`] or `numpy.array`
          Model predictions (usually on a test set).
      y_pred_null : `list` [`float`] or `numpy.array` or None
          A baseline prediction model to compare against.
          If None, derived from ``y_train`` or ``y_true``.
      y_train : `list` [`float`] or `numpy.array` or None
          Response values in the training data.
          If ``y_pred_null`` is None, then ``y_pred_null`` is set to the mean of ``y_train``.
          If ``y_train`` is also None, then ``y_pred_null`` is set to the mean of ``y_true``.
      loss_func : callable, default `sklearn.metrics.mean_squared_error`
          The error loss function with signature (true_values, predicted_values).
  
      Returns
      -------
      r2_null_model : `float`
          A value within (-\\infty, 1.0]. Higher scores are better.
          Can be interpreted as the improvement in the loss function
          compared to the predictions of the null model.
          For example, a score of 0.74 means the loss is 74% lower
          than for the null model.
  
      Notes
      -----
      There is a connection between ``R2_null_model_score`` and ``R2``.
      ``R2_null_model_score`` can be interpreted as the additional improvement in the
      coefficient of determination (i.e. ``R2``, see `sklearn.metrics.r2_score`) with
      respect to a null model.
  
      Under the default settings of this function, where ``loss_func`` is
      mean squared error and ``y_pred_null`` is the average of
      ``y_true``, the scores are equivalent::
  
          # simplified definition of R2_score, where SSE is sum of squared error
          y_true_avg = np.repeat(np.average(y_true), y_true.shape[0])
          R2_score := 1.0 - SSE(y_true, y_pred) / SSE(y_true, y_true_avg)
          R2_score := 1.0 - MSE(y_true, y_pred) / VAR(y_true)  # equivalent definition
  
          r2_null_model_score(y_true, y_pred) == r2_score(y_true, y_pred)
  
      ``r2_score`` is 0 if simply predicting the mean (y_pred = y_true_avg).
  
      If ``y_pred_null`` is passed, and if ``loss_func`` is mean squared error
      and ``y_true`` has nonzero variance, this function measures how much "r2_score of the
      predictions (``y_pred``)" closes the gap between "r2_score of the null model (``y_pred``)"
      and the "r2_score of the best possible model (``y_true``)", which is 1.0::
  
          R2_pred = r2_score(y_true, y_pred)       # R2 of predictions
          R2_null = r2_score(y_pred_null, y_pred)  # R2 of null model
          r2_null_model_score(y_true, y_pred, y_pred_null) == (R2_pred - R2_null) / (1.0 - R2_null)
  
      When ``y_pred_null=y_true_avg``, ``R2_null`` is 0 and this reduces to the formula above.
  
      Summary (for ``loss_func=mean_squared_error``):
  
          - If ``R2_null>0`` (good null model), then ``R2_null_model_score < R2_score``
          - If ``R2_null=0`` (uninformative null model), then ``R2_null_model_score = R2_score``
          - If ``R2_null<0`` (poor null model), then ``R2_null_model_score > R2_score``
  
      For other loss functions, ``r2_null_model_score`` has the same connection to pseudo R2.
      """
      (
          y_true,
          y_pred,
          y_train,
          y_pred_null,
      ) = valid_elements_for_evaluation(
          reference_arrays=[y_true],
          arrays=[y_pred, y_train, y_pred_null],
          reference_array_names="y_true",
          drop_leading_only=False,
          keep_inf=False,
      )
      r2_null_model = None
  
      if len(y_true) > 0:
          # determines null model
          if (
              y_pred_null is None and y_train is not None
          ):  # from training data
              y_pred_null = np.repeat(y_train.mean(), len(y_true))
          elif y_pred_null is None:  # from test data
              y_pred_null = np.repeat(y_true.mean(), len(y_true))
          elif isinstance(
              y_pred_null, (float, int, np.float32)
          ):  # constant null model
              y_pred_null = np.repeat(y_pred_null, len(y_true))
          # otherwise, y_pred_null is an array, used directly
  
          model_loss = loss_func(y_true, y_pred)
          null_loss = loss_func(y_true, y_pred_null)
  
          if null_loss > 0.0:
              r2_null_model = 1.0 - (model_loss / null_loss)
      return r2_null_model
  
imports: import math
  import warnings
  from collections import namedtuple
  from enum import Enum
  from functools import partial
  from typing import List
  from typing import Optional
  from typing import Union
  import numpy
  import pandas
  from scipy.stats import pearsonr
  from sklearn.metrics import mean_absolute_error
  from sklearn.metrics import mean_squared_error
  from sklearn.metrics import median_absolute_error
  from sklearn.metrics import r2_score
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import COVERAGE_VS_INTENDED_DIFF
  from greykite.common.constants import LOWER_BAND_COVERAGE
  from greykite.common.constants import PREDICTED_COL
  from greykite.common.constants import PREDICTED_LOWER_COL
  from greykite.common.constants import PREDICTED_UPPER_COL
  from greykite.common.constants import PREDICTION_BAND_COVERAGE
  from greykite.common.constants import PREDICTION_BAND_WIDTH
  from greykite.common.constants import UPPER_BAND_COVERAGE
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
label_desc: Use image node_id 6 for calling a global function with example usage: r2_null_model_score(y_true, y_pred, y_pred_null, y_train, loss_func) and returns: r2_null_model