class_docstr: Manages issues related to underperforming group examples.
  
  Note: The `min_cluster_samples` argument should not be confused with the
  `min_samples` argument of sklearn.cluster.DBSCAN.
  
  Examples
  --------
  >>> from cleanlab import Datalab
  >>> import numpy as np
  >>> X = np.random.normal(size=(50, 2))
  >>> y = np.random.randint(2, size=50)
  >>> pred_probs = X / X.sum(axis=1, keepdims=True)
  >>> data = {"X": X, "y": y}
  >>> lab = Datalab(data, label_name="y")
  >>> issue_types={"underperforming_group": {"clustering_kwargs": {"eps": 0.5}}}
  >>> lab.find_issues(pred_probs=pred_probs, features=X, issue_types=issue_types)
class_docstr_tok: ["Manages","issues","related","to","underperforming","group","examples",".","Note",":","The","`","min_cluster_samples","`","argument","should","not","be","confused","with","the","`","min_samples","`","argument","of","sklearn.cluster.DBSCAN",".","Examples","--","--","--","--",">",">",">","from","cleanlab","import","Datalab",">",">",">","import","numpy","as","np",">",">",">","X","=","np.random.normal","(","size=","(","50",",","2",")",")",">",">",">","y","=","np.random.randint","(","2",",","size=50",")",">",">",">","pred_probs","=","X","\/","X.sum","(","axis=1",",","keepdims=True",")",">",">",">","data","=","{","``","X","''",":","X",",","``","y","''",":","y","}",">",">",">","lab","=","Datalab","(","data",",","label_name=","''","y","''",")",">",">",">","issue_types=","{","``","underperforming_group","''",":","{","``","clustering_kwargs","''",":","{","``","eps","''",":","0.5","}","}","}",">",">",">","lab.find_issues","(","pred_probs=pred_probs",",","features=X",",","issue_types=issue_types",")"]
code: def set_knn_graph(
      self, features: npt.NDArray, find_issues_kwargs: Dict[str, Any]
  ) -> csr_matrix:
      knn_graph = self._process_knn_graph_from_inputs(
          find_issues_kwargs
      )
      old_knn_metric = self.datalab.get_info("statistics").get(
          "knn_metric"
      )
      metric_changes = self.metric and self.metric != old_knn_metric
  
      if knn_graph is None or metric_changes:
          if features is None:
              raise ValueError(
                  "If a knn_graph is not provided, features must be provided to fit a new knn."
              )
          if self.metric is None:
              self.metric = (
                  "cosine" if features.shape[1] > 3 else "euclidean"
              )
          knn = NearestNeighbors(n_neighbors=self.k, metric=self.metric)
  
          if self.metric and self.metric != knn.metric:
              warnings.warn(
                  f"Metric {self.metric} does not match metric {knn.metric} used to fit knn. "
                  "Most likely an existing NearestNeighbors object was passed in, but a different "
                  "metric was specified."
              )
          self.metric = knn.metric
  
          try:
              check_is_fitted(knn)
          except NotFittedError:
              knn.fit(features)
          knn_graph = knn.kneighbors_graph(mode="distance")
      return knn_graph
  
imports: from __future__ import annotations
  from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union, Tuple
  import warnings
  import inspect
  import numpy
  import pandas
  from scipy.sparse import csr_matrix
  from sklearn.neighbors import NearestNeighbors
  from sklearn.exceptions import NotFittedError
  from sklearn.utils.validation import check_is_fitted
  from sklearn.cluster import DBSCAN
  from cleanlab.datalab.internal.issue_manager import IssueManager
  from cleanlab.rank import get_self_confidence_for_each_label
label_desc: Use image node_id 3 for calling the UnderperformingGroupIssueManager obj's underlying member method code with example usage: obj.set_knn_graph(features, find_issues_kwargs) and returns: knn_graph