code: def chi2(X, y):
      """Compute chi-squared stats between each non-negative feature and class.
  
      This score can be used to select the `n_features` features with the
      highest values for the test chi-squared statistic from X, which must
      contain only **non-negative features** such as booleans or frequencies
      (e.g., term counts in document classification), relative to the classes.
  
      Recall that the chi-square test measures dependence between stochastic
      variables, so using this function "weeds out" the features that are the
      most likely to be independent of class and therefore irrelevant for
      classification.
  
      Read more in the :ref:`User Guide <univariate_feature_selection>`.
  
      Parameters
      ----------
      X : {array-like, sparse matrix} of shape (n_samples, n_features)
          Sample vectors.
  
      y : array-like of shape (n_samples,)
          Target vector (class labels).
  
      Returns
      -------
      chi2 : ndarray of shape (n_features,)
          Chi2 statistics for each feature.
  
      p_values : ndarray of shape (n_features,)
          P-values for each feature.
  
      See Also
      --------
      f_classif : ANOVA F-value between label/feature for classification tasks.
      f_regression : F-value between label/feature for regression tasks.
  
      Notes
      -----
      Complexity of this algorithm is O(n_classes * n_features).
      """
  
      # XXX: we might want to do some of the following in logspace instead for
      # numerical stability.
      # Converting X to float allows getting better performance for the
      # safe_sparse_dot call made below.
      X = check_array(
          X, accept_sparse="csr", dtype=(np.float64, np.float32)
      )
      if np.any((X.data if issparse(X) else X) < 0):
          raise ValueError("Input X must be non-negative.")
  
      # Use a sparse representation for Y by default to reduce memory usage when
      # y has many unique classes.
      Y = LabelBinarizer(sparse_output=True).fit_transform(y)
      if Y.shape[1] == 1:
          Y = Y.toarray()
          Y = np.append(1 - Y, Y, axis=1)
  
      observed = safe_sparse_dot(Y.T, X)  # n_classes * n_features
  
      if issparse(observed):
          # convert back to a dense array before calling _chisquare
          # XXX: could _chisquare be reimplement to accept sparse matrices for
          # cases where both n_classes and n_features are large (and X is
          # sparse)?
          observed = observed.toarray()
  
      feature_count = X.sum(axis=0).reshape(1, -1)
      class_prob = Y.mean(axis=0).reshape(1, -1)
      expected = np.dot(class_prob.T, feature_count)
  
      return _chisquare(observed, expected)
  
imports: import warnings
  from numbers import Integral, Real
  import numpy
  from scipy import special, stats
  from scipy.sparse import issparse
  from ..base import BaseEstimator, _fit_context
  from ..preprocessing import LabelBinarizer
  from ..utils import as_float_array, check_array, check_X_y, safe_mask, safe_sqr
  from ..utils._param_validation import Interval, StrOptions, validate_params
  from ..utils.extmath import row_norms, safe_sparse_dot
  from ..utils.validation import check_is_fitted
  from ._base import SelectorMixin
label_desc: Use image node_id 5 for calling a global function with example usage: chi2(X, y) and returns: _chisquare