docstr: Build KDTrees for each prediction class.
  
  Parameters
  ----------
  X
      Data.
  Y
      Target labels, either one-hot encoded or the actual class label.
  classes
      Number of prediction classes, needs to be provided if `Y` equals the predicted class.
code: def fit(
      self, X: np.ndarray, Y: np.ndarray, classes: Optional[int] = None
  ) -> None:
      """
      Build KDTrees for each prediction class.
  
      Parameters
      ----------
      X
          Data.
      Y
          Target labels, either one-hot encoded or the actual class label.
      classes
          Number of prediction classes, needs to be provided if `Y` equals the predicted class.
      """
      self.classes = classes if classes is not None else Y.shape[1]
      self.kdtrees: Any = [None] * self.classes
      self.X_kdtree: Any = [None] * self.classes
  
      # KDTree and kNeighborsClassifier need 2D data
      if len(X.shape) > 2:
          logger.warning(
              "Reshaping data from {0} to {1} so k-d trees can "
              "be built.".format(
                  X.shape, X.reshape(X.shape[0], -1).shape
              )
          )
          X = X.reshape(X.shape[0], -1)
  
      # make sure Y represents predicted classes, not one-hot encodings
      if len(Y.shape) > 1:
          Y = np.argmax(Y, axis=1)
  
      if self.filter == "probability_knn":
          X_filter, Y_filter = self.filter_by_probability_knn(X, Y)
  
      for c in range(self.classes):
          if self.filter is None:
              X_fit = X[np.where(Y == c)[0]]
          elif self.filter == "distance_knn":
              X_fit = self.filter_by_distance_knn(
                  X[np.where(Y == c)[0]]
              )
          elif self.filter == "probability_knn":
              X_fit = X_filter[np.where(Y_filter == c)[0]]
  
          no_x_fit = len(X_fit) == 0
          if no_x_fit and len(X[np.where(Y == c)[0]]) == 0:
              logger.warning("No instances available for class %s", c)
          elif no_x_fit:
              logger.warning(
                  "Filtered all the instances for class %s. Lower alpha or check data.",
                  c,
              )
  
          self.kdtrees[c] = KDTree(
              X_fit, leaf_size=self.leaf_size, metric=self.metric
          )  # build KDTree for class c
          self.X_kdtree[c] = X_fit
  
file_path: alibi/alibi/confidence/trustscore.py
imports: import logging
  from typing import Any, Optional, Tuple
  import numpy
  from sklearn.neighbors import KDTree, KNeighborsClassifier
label_desc: Use image node_id 4 for calling the TrustScore obj's underlying member method code with example usage: obj.fit(X, Y, classes) without return types