class_docstr: Leaf Node of the Stochastic Gradient Trees (SGT).
  
  There is only one type of leaf in SGTs. It handles only gradient and hessian
  information about the target. The tree handles target transformation and encoding.
  
  Parameters
  ----------
  prediction
      The initial prediction of the leaf.
  depth
      The depth of the leaf in the tree.
  split_params
      Parameters passed to the feature quantizers.
class_docstr_tok: ["Leaf","Node","of","the","Stochastic","Gradient","Trees","(","SGT",")",".","There","is","only","one","type","of","leaf","in","SGTs",".","It","handles","only","gradient","and","hessian","information","about","the","target",".","The","tree","handles","target","transformation","and","encoding",".","Parameters","--","--","--","--","--","prediction","The","initial","prediction","of","the","leaf",".","depth","The","depth","of","the","leaf","in","the","tree",".","split_params","Parameters","passed","to","the","feature","quantizers","."]
code: def find_best_split(self, sgt) -> BranchFactory:
      best_split = BranchFactory()
      best_split.merit = GradHessMerit()  # type: ignore
  
      # Null split: update the prediction using the new gradient information
      best_split.merit.delta_pred = self.delta_prediction(  # type: ignore
          self._update_stats.mean, sgt.lambda_value
      )
      dlms = self._update_stats.delta_loss_mean_var(best_split.merit.delta_pred)  # type: ignore
      best_split.merit.loss_mean = dlms.mean.get()  # type: ignore
      best_split.merit.loss_var = dlms.get()  # type: ignore
  
      for feature_idx in self._split_stats:  # type: ignore
          candidate = BranchFactory()
          candidate.merit = GradHessMerit()  # type: ignore
          candidate.feature = feature_idx
  
          if feature_idx in sgt.nominal_attributes:
              candidate, skip_candidate = self._eval_categorical_splits(
                  feature_idx, candidate, sgt
              )
          else:  # Numerical features
              candidate, skip_candidate = self._eval_numerical_splits(
                  feature_idx, candidate, sgt
              )
  
          if skip_candidate:
              continue
  
          if candidate.merit.loss_mean < best_split.merit.loss_mean:  # type: ignore
              best_split = candidate
  
      return best_split
  
imports: from __future__ import annotations
  import collections
  import math
  import numbers
  import sys
  from collections.abc import Hashable
  from river import stats
  from river.base.typing import FeatureName
  from ..base import Leaf
  from ..splitter.sgt_quantizer import DynamicQuantizer, StaticQuantizer
  from ..utils import BranchFactory, GradHess, GradHessMerit, GradHessStats
  from .branch import NominalMultiwayBranch, NumericBinaryBranch
label_desc: Use image node_id 8 for calling the SGTLeaf obj's underlying member method code with example usage: obj.find_best_split(sgt) and returns: best_split