class_docstr: This loads an XGBoost model directly from a raw memory dump.
  
  We can't use the JSON dump because due to numerical precision issues those
  tree can actually be wrong when feature values land almost on a threshold.
class_docstr_tok: ["This","loads","an","XGBoost","model","directly","from","a","raw","memory","dump",".","We","ca","n't","use","the","JSON","dump","because","due","to","numerical","precision","issues","those","tree","can","actually","be","wrong","when","feature","values","land","almost","on","a","threshold","."]
code: def __init__(self, xgb_model):
      # new in XGBoost 1.1, 'binf' is appended to the buffer
      self.buf = xgb_model.save_raw()
      if self.buf.startswith(b"binf"):
          self.buf = self.buf[4:]
      self.pos = 0
  
      # load the model parameters
      self.base_score = self.read("f")
      self.num_feature = self.read("I")
      self.num_class = self.read("i")
      self.contain_extra_attrs = self.read("i")
      self.contain_eval_metrics = self.read("i")
      self.read_arr("i", 29)  # reserved
      self.name_obj_len = self.read("Q")
      self.name_obj = self.read_str(self.name_obj_len)
      self.name_gbm_len = self.read("Q")
      self.name_gbm = self.read_str(self.name_gbm_len)
  
      # new in XGBoost 1.0 is that the base_score is saved untransformed (https://github.com/dmlc/xgboost/pull/5101)
      # so we have to transform it depending on the objective
      import xgboost
  
      if version.parse(xgboost.__version__).major >= 1:
          if self.name_obj in ["binary:logistic", "reg:logistic"]:
              self.base_score = scipy.special.logit(self.base_score)
  
      assert self.name_gbm == "gbtree", (
          "Only the 'gbtree' model type is supported, not '%s'!"
          % self.name_gbm
      )
  
      # load the gbtree specific parameters
      self.num_trees = self.read("i")
      self.num_roots = self.read("i")
      self.num_feature = self.read("i")
      self.pad_32bit = self.read("i")
      self.num_pbuffer_deprecated = self.read("Q")
      self.num_output_group = self.read("i")
      self.size_leaf_vector = self.read("i")
      self.read_arr("i", 32)  # reserved
  
      # load each tree
      self.num_roots = np.zeros(self.num_trees, dtype=np.int32)
      self.num_nodes = np.zeros(self.num_trees, dtype=np.int32)
      self.num_deleted = np.zeros(self.num_trees, dtype=np.int32)
      self.max_depth = np.zeros(self.num_trees, dtype=np.int32)
      self.num_feature = np.zeros(self.num_trees, dtype=np.int32)
      self.size_leaf_vector = np.zeros(self.num_trees, dtype=np.int32)
      self.node_parents = []
      self.node_cleft = []
      self.node_cright = []
      self.node_sindex = []
      self.node_info = []
      self.loss_chg = []
      self.sum_hess = []
      self.base_weight = []
      self.leaf_child_cnt = []
      for i in range(self.num_trees):
          # load the per-tree params
          self.num_roots[i] = self.read("i")
          self.num_nodes[i] = self.read("i")
          self.num_deleted[i] = self.read("i")
          self.max_depth[i] = self.read("i")
          self.num_feature[i] = self.read("i")
          self.size_leaf_vector[i] = self.read("i")
  
          # load the nodes
          self.read_arr("i", 31)  # reserved
          self.node_parents.append(
              np.zeros(self.num_nodes[i], dtype=np.int32)
          )
          self.node_cleft.append(
              np.zeros(self.num_nodes[i], dtype=np.int32)
          )
          self.node_cright.append(
              np.zeros(self.num_nodes[i], dtype=np.int32)
          )
          self.node_sindex.append(
              np.zeros(self.num_nodes[i], dtype=np.uint32)
          )
          self.node_info.append(
              np.zeros(self.num_nodes[i], dtype=np.float32)
          )
          for j in range(self.num_nodes[i]):
              self.node_parents[-1][j] = self.read("i")
              self.node_cleft[-1][j] = self.read("i")
              self.node_cright[-1][j] = self.read("i")
              self.node_sindex[-1][j] = self.read("I")
              self.node_info[-1][j] = self.read("f")
  
          # load the stat nodes
          self.loss_chg.append(
              np.zeros(self.num_nodes[i], dtype=np.float32)
          )
          self.sum_hess.append(
              np.zeros(self.num_nodes[i], dtype=np.float64)
          )
          self.base_weight.append(
              np.zeros(self.num_nodes[i], dtype=np.float32)
          )
          self.leaf_child_cnt.append(
              np.zeros(self.num_nodes[i], dtype=int)
          )
          for j in range(self.num_nodes[i]):
              self.loss_chg[-1][j] = self.read("f")
              self.sum_hess[-1][j] = self.read("f")
              self.base_weight[-1][j] = self.read("f")
              self.leaf_child_cnt[-1][j] = self.read("i")
  
imports: import json
  import os
  import struct
  import time
  import warnings
  import numpy
  import pandas
  import scipy.sparse
  import scipy.special
  from packaging import version
  from ..None import maskers
  from .._explanation import Explanation
  from ..utils import assert_import, record_import_error, safe_isinstance
  from ..utils._exceptions import DimensionError, ExplainerError, InvalidFeaturePerturbationError, InvalidMaskerError, InvalidModelError
  from ..utils._legacy import DenseData
  from ._explainer import Explainer
label_desc: Use image node_id 1 to create a new XGBTreeModelLoader object  with example: obj = XGBTreeModelLoader(xgb_model)