class_docstr: FIGSExt (sum of trees) classifier.
  Fast Interpretable Greedy-Tree Sums (FIGS) is an algorithm for fitting concise rule-based models.
  Specifically, FIGS generalizes CART to simultaneously grow a flexible number of trees in a summation.
  The total number of splits across all the trees can be restricted by a pre-specified threshold, keeping the model interpretable.
  Experiments across a wide array of real-world datasets show that FIGS achieves state-of-the-art prediction performance when restricted to just a few splits (e.g. less than 20).
  https://arxiv.org/abs/2201.11931
code: def _construct_node_with_stump(
      self, X, y, idxs, tree_num, sample_weight=None, max_features=None
  ):
      # array indices
      SPLIT = 0
      LEFT = 1
      RIGHT = 2
  
      # fit stump
      stump = tree.DecisionTreeRegressor(
          max_depth=1, max_features=max_features
      )
      if sample_weight is not None:
          sample_weight = sample_weight[idxs]
      stump.fit(X[idxs], y[idxs], sample_weight=sample_weight)
  
      # these are all arrays, arr[0] is split node
      # note: -2 is dummy
      feature = stump.tree_.feature
      threshold = stump.tree_.threshold
  
      impurity = stump.tree_.impurity
      n_node_samples = stump.tree_.n_node_samples
      value = stump.tree_.value
  
      # no split
      if len(feature) == 1:
          # print('no split found!', idxs.sum(), impurity, feature)
          return Node(
              idxs=idxs,
              value=value[SPLIT],
              tree_num=tree_num,
              feature=feature[SPLIT],
              threshold=threshold[SPLIT],
              impurity_reduction=-1,
              n_samples=n_node_samples,
          )
  
      # split node
      impurity_reduction = (
          impurity[SPLIT]
          - impurity[LEFT]
          * n_node_samples[LEFT]
          / n_node_samples[SPLIT]
          - impurity[RIGHT]
          * n_node_samples[RIGHT]
          / n_node_samples[SPLIT]
      ) * idxs.sum()
  
      node_split = Node(
          idxs=idxs,
          value=value[SPLIT],
          tree_num=tree_num,
          feature=feature[SPLIT],
          threshold=threshold[SPLIT],
          impurity_reduction=impurity_reduction,
          n_samples=n_node_samples,
      )
      # print('\t>>>', node_split, 'impurity', impurity, 'num_pts', idxs.sum(), 'imp_reduc', impurity_reduction)
  
      # manage children
      idxs_split = X[:, feature[SPLIT]] <= threshold[SPLIT]
      idxs_left = idxs_split & idxs
      idxs_right = ~idxs_split & idxs
      node_left = Node(
          idxs=idxs_left, value=value[LEFT], tree_num=tree_num
      )
      node_right = Node(
          idxs=idxs_right, value=value[RIGHT], tree_num=tree_num
      )
      node_split.setattrs(
          left_temp=node_left,
          right_temp=node_right,
      )
      return node_split
  
imports: from copy import deepcopy
  import numpy
  from matplotlib import pyplot
  from sklearn import datasets
  from sklearn import tree
  from sklearn.base import BaseEstimator
  from sklearn.linear_model import RidgeCV, RidgeClassifierCV
  from sklearn.model_selection import train_test_split
  from sklearn.tree import plot_tree
  from sklearn.utils import check_X_y
  from imodels.tree.viz_utils import extract_sklearn_tree_from_figs
label_desc: Use image node_id 5 for calling the FIGSExt obj's underlying member method code with example usage: obj._construct_node_with_stump(X, y, idxs, tree_num, sample_weight, max_features) and returns: node_split, Node