code: def predict_proba(self, X, verbose=False):
      if self.model_name[:3] == "XGB":
          ones = [[1] for x in range(X.shape[0])]
          if scipy.sparse.issparse(X):
              # Trying to force XGBoost to play nice with sparse matrices
              X = scipy.sparse.hstack((X, ones))
          else:
              X = np.column_stack([X, ones])
  
      X_predict = X
  
      if (
          self.model_name[:16] == "GradientBoosting"
          or self.model_name[:12] == "DeepLearning"
          or self.model_name
          in [
              "BayesianRidge",
              "LassoLars",
              "OrthogonalMatchingPursuit",
              "ARDRegression",
          ]
      ):
          if scipy.sparse.issparse(X):
              X = X.todense()
          elif isinstance(X, pd.DataFrame):
              X = X.values
      elif (
          self.model_name[:8] == "CatBoost"
          or self.model_name[:4] == "LGBM"
      ):
          if scipy.sparse.issparse(X):
              X = X.toarray()
          elif isinstance(X, pd.DataFrame):
              X = X.values
  
      try:
          if self.model_name[:4] == "LGBM":
              try:
                  best_iteration = self.model.best_iteration
              except AttributeError:
                  best_iteration = self.model.best_iteration_
              predictions = self.model.predict_proba(
                  X, num_iteration=best_iteration
              )
          else:
              predictions = self.model.predict_proba(X)
  
      except AttributeError as e:
          try:
              predictions = self.model.predict(X)
          except TypeError as e:
              if scipy.sparse.issparse(X):
                  X = X.todense()
              predictions = self.model.predict(X)
  
      except TypeError as e:
          if scipy.sparse.issparse(X):
              X = X.todense()
          predictions = self.model.predict_proba(X)
  
      # If this model does not have predict_proba, and we have fallen back on predict, we want to make sure we give results back in the same format the user would expect for predict_proba, namely each prediction is a list of predicted probabilities for each class.
      # Note that this DOES NOT WORK for multi-label problems, or problems that are not reduced to 0,1
      # If this is not an iterable (ignoring strings, which might be iterable), then we will want to turn our predictions into tupled predictions
      if not (
          hasattr(predictions[0], "__iter__")
          and not isinstance(predictions[0], str)
      ):
          tupled_predictions = []
          for prediction in predictions:
              if prediction == 1:
                  tupled_predictions.append([0, 1])
              else:
                  tupled_predictions.append([1, 0])
          predictions = tupled_predictions
  
      # This handles an annoying edge case with libraries like Keras that, for a binary classification problem, with return a single predicted probability in a list, rather than the probability of both classes in a list
      if len(predictions[0]) == 1:
          tupled_predictions = []
          for prediction in predictions:
              tupled_predictions.append(
                  [1 - prediction[0], prediction[0]]
              )
          predictions = tupled_predictions
  
      if X.shape[0] == 1:
          return predictions[0]
      else:
          return predictions
  
imports: from collections import Iterable
  from copy import deepcopy
  import datetime
  import gc
  import os
  import random
  import warnings
  import numpy
  import pandas
  import scipy
  from sklearn.base import BaseEstimator, TransformerMixin
  from sklearn.model_selection import train_test_split
  from sklearn import __version__
  from auto_ml import utils_models
  from auto_ml.utils_models import get_name_from_model
label_desc: Use image node_id 7 for calling the FinalModelATC obj's underlying member method code with example usage: obj.predict_proba(X, verbose) and returns: predictions, predictions