code: def build(self):
      data, k = self.data, self.k
  
      timer = utils.Timer(
          f"Finding {k} nearest neighbors using exact search using "
          f"{self.metric} distance...",
          verbose=self.verbose,
      )
      timer.__enter__()
  
      if self.metric == "cosine":
          # The nearest neighbor ranking for cosine distance is the same as
          # for euclidean distance on normalized data
          effective_metric = "euclidean"
          effective_data = data.copy()
          effective_data = (
              effective_data
              / np.linalg.norm(effective_data, axis=1)[:, None]
          )
          # In order to properly compute cosine distances when querying the
          # index, we need to store the original data
          self.__data = data
      else:
          effective_metric = self.metric
          effective_data = data
  
      self.index = neighbors.NearestNeighbors(
          algorithm="auto",
          metric=effective_metric,
          metric_params=self.metric_params,
          n_jobs=self.n_jobs,
      )
      self.index.fit(effective_data)
  
      # Return the nearest neighbors in the training set
      distances, indices = self.index.kneighbors(n_neighbors=k)
  
      # If using cosine distance, the computed distances will be wrong and
      # need to be recomputed
      if self.metric == "cosine":
          distances = np.vstack(
              [
                  cdist(np.atleast_2d(x), data[idx], metric="cosine")
                  for x, idx in zip(data, indices)
              ]
          )
  
      timer.__exit__()
  
      return indices, distances
  
imports: import logging
  import os
  import warnings
  import numpy
  from scipy.spatial.distance import cdist
  from sklearn import neighbors
  from sklearn.utils import check_random_state
  from openTSNE import utils
label_desc: Use image node_id 2 for calling the Sklearn obj's underlying member method code with example usage: obj.build() and returns: indices,  distances