class_docstr: Mixin for k-neighbors searches
class_docstr_tok: ["Mixin","for","k-neighbors","searches"]
docstr: Finds the K-neighbors of a point.
  Returns indices of and distances to the neighbors of each point.
  
  Parameters
  ----------
  X : array-like, shape (n_query, n_features),                 or (n_query, n_indexed) if metric == 'precomputed'
      The query point or points.
      If not provided, neighbors of each indexed point are returned.
      In this case, the query point is not considered its own neighbor.
  
  n_neighbors : int
      Number of neighbors to get (default is the value
      passed to the constructor).
  
  return_distance : boolean, optional. Defaults to True.
      If False, distances will not be returned
  
  Returns
  -------
  dist : Tensor
      Array representing the lengths to points, only present if
      return_distance=True
  
  ind : Tensor
      Indices of the nearest points in the population matrix.
  
  Examples
  --------
  In the following example, we construct a NeighborsClassifier
  class from a tensor representing our data set and ask who's
  the closest point to [1,1,1]
  
  >>> samples = [[0., 0., 0.], [0., .5, 0.], [1., 1., .5]]
  >>> from mars.learn.neighbors import NearestNeighbors
  >>> neigh = NearestNeighbors(n_neighbors=1)
  >>> neigh.fit(samples) # doctest: +ELLIPSIS
  NearestNeighbors(algorithm='auto', leaf_size=30, ...)
  >>> print(neigh.kneighbors([[1., 1., 1.]])) # doctest: +ELLIPSIS
  (array([[0.5]]), array([[2]]))
  
  As you can see, it returns [[0.5]], and [[2]], which means that the
  element is at distance 0.5 and is the third element of samples
  (indexes start at 0). You can also query for multiple points:
  
  >>> X = [[0., 1., 0.], [1., 0., 1.]]
  >>> neigh.kneighbors(X, return_distance=False) # doctest: +ELLIPSIS
  array([[1],
         [2]]...)
docstr_tok: ["Finds","the","K-neighbors","of","a","point",".","Returns","indices","of","and","distances","to","the","neighbors","of","each","point",".","Parameters","--","--","--","--","--","X",":","array-like",",","shape","(","n_query",",","n_features",")",",","or","(","n_query",",","n_indexed",")","if","metric","==","'precomputed'","The","query","point","or","points",".","If","not","provided",",","neighbors","of","each","indexed","point","are","returned",".","In","this","case",",","the","query","point","is","not","considered","its","own","neighbor",".","n_neighbors",":","int","Number","of","neighbors","to","get","(","default","is","the","value","passed","to","the","constructor",")",".","return_distance",":","boolean",",","optional",".","Defaults","to","True",".","If","False",",","distances","will","not","be","returned","Returns","--","--","--","-","dist",":","Tensor","Array","representing","the","lengths","to","points",",","only","present","if","return_distance=True","ind",":","Tensor","Indices","of","the","nearest","points","in","the","population","matrix",".","Examples","--","--","--","--","In","the","following","example",",","we","construct","a","NeighborsClassifier","class","from","a","tensor","representing","our","data","set","and","ask","who's","the","closest","point","to","[","1,1,1","]",">",">",">","samples","=","[","[","0.",",","0.",",","0",".","]",",","[","0.",",",".5",",","0",".","]",",","[","1.",",","1.",",",".5","]","]",">",">",">","from","mars.learn.neighbors","import","NearestNeighbors",">",">",">","neigh","=","NearestNeighbors","(","n_neighbors=1",")",">",">",">","neigh.fit","(","samples",")","#","doctest",":","+ELLIPSIS","NearestNeighbors","(","algorithm='auto","'",",","leaf_size=30",",","...",")",">",">",">","print","(","neigh.kneighbors","(","[","[","1.",",","1.",",","1",".","]","]",")",")","#","doctest",":","+ELLIPSIS","(","array","(","[","[","0.5","]","]",")",",","array","(","[","[","2","]","]",")",")","As","you","can","see",",","it","returns","[","[","0.5","]","]",",","and","[","[","2","]","]",",","which","means","that","the","element","is","at","distance","0.5","and","is","the","third","element","of","samples","(","indexes","start","at","0",")",".","You","can","also","query","for","multiple","points",":",">",">",">","X","=","[","[","0.",",","1.",",","0",".","]",",","[","1.",",","0.",",","1",".","]","]",">",">",">","neigh.kneighbors","(","X",",","return_distance=False",")","#","doctest",":","+ELLIPSIS","array","(","[","[","1","]",",","[","2","]","]","...",")"]
code: def kneighbors(
      self,
      X=None,
      n_neighbors=None,
      return_distance=True,
      session=None,
      run_kwargs=None,
      **kw,
  ):
      """Finds the K-neighbors of a point.
          Returns indices of and distances to the neighbors of each point.
  
          Parameters
          ----------
          X : array-like, shape (n_query, n_features), \
                  or (n_query, n_indexed) if metric == 'precomputed'
              The query point or points.
              If not provided, neighbors of each indexed point are returned.
              In this case, the query point is not considered its own neighbor.
  
          n_neighbors : int
              Number of neighbors to get (default is the value
              passed to the constructor).
  
          return_distance : boolean, optional. Defaults to True.
              If False, distances will not be returned
  
          Returns
          -------
          dist : Tensor
              Array representing the lengths to points, only present if
              return_distance=True
  
          ind : Tensor
              Indices of the nearest points in the population matrix.
  
          Examples
          --------
          In the following example, we construct a NeighborsClassifier
          class from a tensor representing our data set and ask who's
          the closest point to [1,1,1]
  
          >>> samples = [[0., 0., 0.], [0., .5, 0.], [1., 1., .5]]
          >>> from mars.learn.neighbors import NearestNeighbors
          >>> neigh = NearestNeighbors(n_neighbors=1)
          >>> neigh.fit(samples) # doctest: +ELLIPSIS
          NearestNeighbors(algorithm='auto', leaf_size=30, ...)
          >>> print(neigh.kneighbors([[1., 1., 1.]])) # doctest: +ELLIPSIS
          (array([[0.5]]), array([[2]]))
  
          As you can see, it returns [[0.5]], and [[2]], which means that the
          element is at distance 0.5 and is the third element of samples
          (indexes start at 0). You can also query for multiple points:
  
          >>> X = [[0., 1., 0.], [1., 0., 1.]]
          >>> neigh.kneighbors(X, return_distance=False) # doctest: +ELLIPSIS
          array([[1],
                 [2]]...)
  
          """
      check_is_fitted(self, ["_fit_method", "_fit_X"], all_or_any=any)
  
      if n_neighbors is None:
          n_neighbors = self.n_neighbors
      elif n_neighbors <= 0:
          raise ValueError(
              f"Expected n_neighbors > 0. Got {n_neighbors}"
          )
      else:
          if not np.issubdtype(type(n_neighbors), np.integer):
              raise TypeError(
                  f"n_neighbors does not take {type(n_neighbors)} value, "
                  "enter integer value"
              )
  
      if X is not None:
          query_is_train = False
          X = check_array(X, accept_sparse=True)
      else:
          query_is_train = True
          X = self._fit_X
          # Include an extra neighbor to account for the sample itself being
          # returned, which is removed later
          n_neighbors += 1
  
      if X.key == self._fit_X.key and X is not self._fit_X:
          X = self._fit_X
      if np.isnan(X.size):
          # has unknown size, execute first
          X.execute(session=session, **(run_kwargs or dict()))
  
      train_size = self._fit_X.shape[0]
      if n_neighbors > train_size:
          raise ValueError(
              "Expected n_neighbors <= n_samples, "
              f"but n_samples = {train_size}, n_neighbors = {n_neighbors}"
          )
      n_samples, _ = X.shape
      sample_range = mt.arange(n_samples)[:, None]
  
      if self._fit_method == "brute":
          # for efficiency, use squared euclidean distances
          kwds = (
              {"squared": True}
              if self.effective_metric_ == "euclidean"
              else self.effective_metric_params_
          )
  
          neigh_dist, neigh_ind = pairwise_distances_topk(
              X,
              self._fit_X,
              k=n_neighbors,
              metric=self.effective_metric_,
              **kwds,
          )
          if return_distance:
              if self.effective_metric_ == "euclidean":
                  result = mt.sqrt(neigh_dist), neigh_ind
              else:
                  result = neigh_dist, neigh_ind
          else:
              result = neigh_ind
      elif self._fit_method in ["ball_tree", "kd_tree"]:
          if X.issparse():
              raise ValueError(
                  f"{self._fit_method} does not work with sparse matrices. "
                  "Densify the data, or set algorithm='brute'"
              )
  
          query = (
              ball_tree_query
              if self._fit_method == "ball_tree"
              else kd_tree_query
          )
          result = query(self._tree, X, n_neighbors, return_distance)
      elif self._fit_method == "faiss":
          if X.issparse():
              raise ValueError(
                  f"{self._fit_method} does not work with sparse matrices. "
                  "Densify the data, or set algorithm='brute'"
              )
          result = faiss_query(
              self._faiss_index, X, n_neighbors, return_distance, **kw
          )
      elif self._fit_method == "proxima":  # pragma: no cover
          if X.issparse():
              raise ValueError(
                  f"{self._fit_method} does not work with sparse matrices. "
                  "Densify the data, or set algorithm='brute'"
              )
          ind, dis = proxima_query(
              X, n_neighbors, index=self._proxima_index, run=False, **kw
          )
          if not return_distance:
              result = ind
          else:
              result = (dis, ind)
      else:  # pragma: no cover
          raise ValueError("internal: _fit_method not recognized")
  
      if not query_is_train:
          if isinstance(result, (tuple, list)):
              result = mt.ExecutableTuple(result)
          result.execute(session=session, **(run_kwargs or dict()))
          return result
      else:
          # If the query data is the same as the indexed data, we would like
          # to ignore the first nearest neighbor of every sample, i.e
          # the sample itself.
          if return_distance:
              dist, neigh_ind = result
          else:
              neigh_ind = result
  
          sample_mask = neigh_ind != sample_range
  
          # Corner case: When the number of duplicates are more
          # than the number of neighbors, the first NN will not
          # be the sample, but a duplicate.
          # In that case mask the first duplicate.
          dup_gr_nbrs = mt.all(sample_mask, axis=1)
          sample_mask[:, 0] = mt.where(
              dup_gr_nbrs, False, sample_mask[:, 0]
          )
  
          neigh_ind = reshape_unchecked(
              neigh_ind[sample_mask], (n_samples, n_neighbors - 1)
          )
  
          if return_distance:
              dist = reshape_unchecked(
                  dist[sample_mask], (n_samples, n_neighbors - 1)
              )
              ret = mt.ExecutableTuple([dist, neigh_ind])
              ret.execute(session=session, **(run_kwargs or dict()))
              return ret
          neigh_ind.execute(session=session, **(run_kwargs or dict()))
          return neigh_ind
  
imports: import warnings
  from abc import ABCMeta, abstractmethod
  import numpy
  from sklearn.base import BaseEstimator, MultiOutputMixin
  from ...None import tensor
  from ...tensor.reshape.reshape import _reshape
  from ..metrics.pairwise import PAIRWISE_DISTANCE_FUNCTIONS
  from ..metrics import pairwise_distances_topk
  from ..utils import check_array
  from ..utils.validation import check_is_fitted
  from ._ball_tree import create_ball_tree, ball_tree_query, SklearnBallTree
  from ._kd_tree import create_kd_tree, kd_tree_query, SklearnKDTree
  from ._faiss import build_faiss_index, faiss_query, METRIC_TO_FAISS_METRIC_TYPE
  from ._proxima import build_proxima_index, proxima_query, METRIC_TO_PROXIMA_METRIC_TYPE
  from ._kneighbors_graph import KNeighborsGraph
label_desc: Use image node_id 1 for calling the KNeighborsMixin obj's underlying member method code with example usage: obj.kneighbors(X, n_neighbors, return_distance, session, run_kwargs) and returns: result, neigh_ind, ret