code: def py_rmsle(dtrain: xgb.DMatrix, dtest: xgb.DMatrix) -> Dict:
      """Train using Python implementation of Squared Log Error."""
  
      def gradient(
          predt: np.ndarray, dtrain: xgb.DMatrix
      ) -> np.ndarray:
          """Compute the gradient squared log error."""
          y = dtrain.get_label()
          return (np.log1p(predt) - np.log1p(y)) / (predt + 1)
  
      def hessian(predt: np.ndarray, dtrain: xgb.DMatrix) -> np.ndarray:
          """Compute the hessian for squared log error."""
          y = dtrain.get_label()
          return (-np.log1p(predt) + np.log1p(y) + 1) / np.power(
              predt + 1, 2
          )
  
      def squared_log(
          predt: np.ndarray, dtrain: xgb.DMatrix
      ) -> Tuple[np.ndarray, np.ndarray]:
          """Squared Log Error objective. A simplified version for RMSLE used as
          objective function.
  
          :math:`\frac{1}{2}[log(pred + 1) - log(label + 1)]^2`
  
          """
          predt[predt < -1] = -1 + 1e-6
          grad = gradient(predt, dtrain)
          hess = hessian(predt, dtrain)
          return grad, hess
  
      def rmsle(
          predt: np.ndarray, dtrain: xgb.DMatrix
      ) -> Tuple[str, float]:
          """Root mean squared log error metric.
  
          :math:`\sqrt{\frac{1}{N}[log(pred + 1) - log(label + 1)]^2}`
          """
          y = dtrain.get_label()
          predt[predt < -1] = -1 + 1e-6
          elements = np.power(np.log1p(y) - np.log1p(predt), 2)
          return "PyRMSLE", float(np.sqrt(np.sum(elements) / len(y)))
  
      results: Dict[str, Dict[str, List[float]]] = {}
      xgb.train(
          {
              "tree_method": "hist",
              "seed": kSeed,
              "disable_default_eval_metric": 1,
          },
          dtrain=dtrain,
          num_boost_round=kBoostRound,
          obj=squared_log,
          custom_metric=rmsle,
          evals=[(dtrain, "dtrain"), (dtest, "dtest")],
          evals_result=results,
      )
  
      return results
  
file_path: xgboost/demo/guide-python/custom_rmsle.py
imports: import argparse
  from time import time
  from typing import Dict, List, Tuple
  import matplotlib
  import numpy
  from matplotlib import pyplot
  import xgboost
label_desc: Use image node_id 4 for calling a global function with example usage: py_rmsle(dtrain, dtest) and returns: results, unknown, unknown, grad,  hess, str,  float