docstr: Train model with train data and validate data.
  
  Parameters
  ----------
  ctx: Context
      FATE Context object
  train_data: DataFrame
      Train data used to fit model.
  validate_data: DataFrame, optional
      Validate data used to evaluate model performance during training process.
docstr_tok: ["Train","model","with","train","data","and","validate","data",".","Parameters","--","--","--","--","--","ctx",":","Context","FATE","Context","object","train_data",":","DataFrame","Train","data","used","to","fit","model",".","validate_data",":","DataFrame",",","optional","Validate","data","used","to","evaluate","model","performance","during","training","process","."]
code: def fit(
      self,
      ctx: Context,
      train_data: DataFrame,
      validate_data: DataFrame = None,
  ) -> None:
      """
      Train model with train data and validate data.
  
      Parameters
      ----------
      ctx: Context
          FATE Context object
      train_data: DataFrame
          Train data used to fit model.
      validate_data: DataFrame, optional
          Validate data used to evaluate model performance during training process.
      """
  
      # data binning
      bin_info = binning(train_data, max_bin=self.max_bin)
      bin_data: DataFrame = train_data.bucketize(boundaries=bin_info)
      self._check_label(bin_data.label)
      self._get_fid_name_mapping(train_data)
  
      # tree dimension
      self._set_tree_dim(ctx)
  
      # init loss func & scores
      self._loss_func = _get_loss_func(self.objective, self.num_class)
      label = bin_data.label
      self._init_sample_scores(ctx, label, train_data)
  
      # init encryption kit
      self._encrypt_kit = self._check_encrypt_kit(ctx)
  
      # start tree fitting
      for iter_dix, tree_ctx in ctx.on_iterations.ctxs_range(
          len(self._trees), len(self._trees) + self.num_trees
      ):
          # compute gh of current iter
          gh = _compute_gh(
              bin_data, self._accumulate_scores, self._loss_func
          )
          tree_mode = ALL_FEAT
          if iter_dix < self._complete_secure:
              tree_mode = GUEST_FEAT_ONLY
          for tree_dim, tree_ctx_ in tree_ctx.on_iterations.ctxs_range(
              self._tree_dim
          ):
              logger.info("start to fit a guest tree")
              if self.objective == MULTI_CE:
                  target_gh = _select_gh_by_tree_dim(gh, tree_dim)
              else:
                  target_gh = gh
              tree = HeteroDecisionTreeGuest(
                  max_depth=self.max_depth,
                  l2=self.l2,
                  l1=self.l1,
                  min_impurity_split=self.min_impurity_split,
                  min_sample_split=self.min_sample_split,
                  min_leaf_node=self.min_leaf_node,
                  min_child_weight=self.min_child_weight,
                  objective=self.objective,
                  gh_pack=self._gh_pack,
                  split_info_pack=self._split_info_pack,
                  hist_sub=self._hist_sub,
                  tree_mode=tree_mode,
              )
              tree.set_encrypt_kit(self._encrypt_kit)
  
              if self.goss:
                  if iter_dix >= self.goss_start_iter:
                      target_gh = goss_sample(
                          target_gh,
                          self.top_rate,
                          self.other_rate,
                          self.random_seed,
                      )
                      logger.debug(
                          "goss sample done, got {} samples".format(
                              len(target_gh)
                          )
                      )
  
              tree.booster_fit(tree_ctx_, bin_data, target_gh, bin_info)
              # accumulate scores of cur boosting round
              scores = tree.get_sample_predict_weights()
              assert len(scores) == len(
                  self._accumulate_scores
              ), f"tree predict scores length {len(scores)} not equal to accumulate scores length {len(self._accumulate_scores)}."
              self._accumulate_scores = _accumulate_scores(
                  self._accumulate_scores,
                  scores,
                  self.learning_rate,
                  self.objective == MULTI_CE,
                  class_num=self.num_class,
                  dim=tree_dim,
              )
              self._trees.append(tree)
              self._saved_tree.append(tree.get_model())
              self._update_feature_importance(
                  tree.get_feature_importance()
              )
              logger.info(
                  "fitting guest decision tree iter {}, dim {} done".format(
                      iter_dix, tree_dim
                  )
              )
  
          # compute loss
          iter_loss = self._loss_func.compute_loss(
              train_data.label,
              self._loss_func.predict(self._accumulate_scores),
          )
          iter_loss = float(iter_loss.iloc[0])
          self._loss_history.append(iter_loss)
          tree_ctx.metrics.log_loss("sbt_loss", iter_loss)
  
      # compute train predict using cache scores
      train_predict: DataFrame = self._loss_func.predict(
          self._accumulate_scores
      )
      train_predict = train_predict.loc(
          train_data.get_indexer(target="sample_id"),
          preserve_order=True,
      )
      train_predict.label = train_data.label
      task_type, classes = self.get_task_info()
      train_predict.rename(columns={"score": PREDICT_SCORE})
      self._train_predict = compute_predict_details(
          train_predict, task_type, classes
      )
  
imports: import numpy
  import pandas
  from typing import Optional, Union
  from fate.arch import Context
  from fate.arch.dataframe import DataFrame
  from fate.ml.ensemble.algo.secureboost.hetero._base import HeteroBoostingTree
  from fate.ml.ensemble.learner.decision_tree.hetero.guest import HeteroDecisionTreeGuest
  from fate.ml.ensemble.utils.binning import binning
  from fate.ml.ensemble.learner.decision_tree.tree_core.loss import OBJECTIVE, get_task_info, MULTI_CE, BINARY_BCE, REGRESSION_L2
  from fate.ml.ensemble.algo.secureboost.common.predict import predict_leaf_guest
  from fate.ml.utils.predict_tools import compute_predict_details, PREDICT_SCORE, BINARY, MULTI, REGRESSION
  from fate.ml.ensemble.learner.decision_tree.tree_core.decision_tree import GUEST_FEAT_ONLY, ALL_FEAT
  from fate.ml.ensemble.utils.sample import goss_sample
  import logging
label_desc: Use image node_id 9 for calling the HeteroSecureBoostGuest obj's underlying member method code with example usage: obj.fit(ctx, train_data, validate_data) without return types