Array API regression in `homogeneity_completeness_v_measure`?

### Describe the bug

When I enable Array API and run `homogeneity_completeness_v_measure`, an error is raised, since within it, a sparse matrix is passed into `mutual_info_score`, which already supports array API ([li. 530-531](https://github.com/scikit-learn/scikit-learn/blob/4cc331fae29e423f2d47d6f653d4f04559fd9d4e/sklearn/metrics/cluster/_supervised.py#L531)): 

```python
contingency = contingency_matrix(labels_true, labels_pred, sparse=True) # <--- we return sparse data
MI = mutual_info_score(None, None, contingency=contingency) #<--- we pass sparse data 
```

I can't wrap my head around it: is this a regression or is this something I need to fix while implementing array API for `homogeneity_completeness_v_measure`?

If I understand correctly: in case of a regression we would need to fix mutual_info_score to convert sparse into dense if array API is enabled, in case it is not a regression, but expected, then we would have to deal with it in `homogeneity_completeness_v_measure` (having a condition here), correct?

ping @adrinjalali, since we have already talked about it.

### Steps/Code to Reproduce

```python
from sklearn.utils._testing import _array_api_for_tests
from sklearn.base import config_context
from sklearn.metrics.cluster import homogeneity_completeness_v_measure

xp = _array_api_for_tests("numpy", device="cpu")
labels_true = xp.asarray([0, 0, 0, 1, 1, 1])
labels_pred = xp.asarray([0, 1, 0, 1, 2, 2])

with config_context(array_api_dispatch=True):
    homogeneity_completeness_v_measure(labels_true, labels_pred)
```

### Expected Results

no error

### Actual Results

```python
Traceback (most recent call last):
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/zzzzz_homogenity_array_api.py", line 10, in <module>
    homogeneity_completeness_v_measure(labels_true, labels_pred)
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/utils/_param_validation.py", line 213, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/metrics/cluster/_supervised.py", line 532, in homogeneity_completeness_v_measure
    MI = mutual_info_score(None, None, contingency=contingency)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/utils/_param_validation.py", line 186, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/metrics/cluster/_supervised.py", line 884, in mutual_info_score
    contingency = check_array(
                  ^^^^^^^^^^^^
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/utils/validation.py", line 841, in check_array
    xp, is_array_api_compliant = get_namespace(array)
                                 ^^^^^^^^^^^^^^^^^^^^
  File "/home/stefanie/code/scikit-learn_dev/scikit-learn/sklearn/utils/_array_api.py", line 553, in get_namespace
    namespace, is_array_api_compliant = array_api_compat.get_namespace(*arrays), True
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stefanie/.pyenv/versions/3.12.2/envs/scikit-learn_dev/lib/python3.12/site-packages/array_api_compat/common/_helpers.py", line 366, in array_namespace
    raise TypeError(f"{type(x).__name__} is not a supported array type")
TypeError: csr_matrix is not a supported array type
```

### Versions

```shell
System:
    python: 3.12.2 (main, Apr 18 2024, 11:14:27) [GCC 13.2.1 20230801]
executable: /home/stefanie/.pyenv/versions/3.12.2/envs/scikit-learn_dev/bin/python
   machine: Linux-6.9.5-arch1-1-x86_64-with-glibc2.39

Python dependencies:
      sklearn: 1.6.dev0
          pip: 24.0
   setuptools: 69.5.1
        numpy: 1.26.4
        scipy: 1.13.0
       Cython: 3.0.10
       pandas: 2.2.2
   matplotlib: 3.8.4
       joblib: 1.4.0
threadpoolctl: 3.4.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 14
         prefix: libopenblas
       filepath: /home/stefanie/.pyenv/versions/3.12.2/envs/scikit-learn_dev/lib/python3.12/site-packages/numpy.libs/libopenblas64_p-r0-0cf96a72.3.23.dev.so
        version: 0.3.23.dev
threading_layer: pthreads
   architecture: Haswell

       user_api: blas
   internal_api: openblas
    num_threads: 14
         prefix: libopenblas
       filepath: /home/stefanie/.pyenv/versions/3.12.2/envs/scikit-learn_dev/lib/python3.12/site-packages/scipy.libs/libopenblasp-r0-24bff013.3.26.dev.so
        version: 0.3.26.dev
threading_layer: pthreads
   architecture: Haswell

       user_api: openmp
   internal_api: openmp
    num_threads: 14
         prefix: libgomp
       filepath: /usr/lib/libgomp.so.1.0.0
        version: None
```

COMMENT:
I agree this is a bug.

> we would need to fix mutual_info_score to convert sparse into dense if array API is enabled

In general we never want to convert sparse arrays/matrices into dense arrays implicitly because it might blow-up memory by allocating memory to store a very large number of zeros. For instance:

```python
>>> import scipy.sparse as sp
>>> A_sparse = sp.random_array((10_000, 10_000), density=0.0001)
>>> (A_sparse.data.nbytes + A_sparse.coords[0].nbytes + A_sparse.coords[1].nbytes) / 1e6
0.24  # MB
>>> A_dense = A_sparse.toarray()
>>> A_dense.nbytes / 1e6
800.0  # MB
```

We should only call `.toarray()` upon a users explicit request or in cases where we know that the resulting dense array will not be arbitrarily large in memory.

Let me look at the code to understand what's going on.

Labels: Bug, Array API