Improve error handling in _mutual_info.py

### Describe the workflow you want to enable

Hi all,

I am currently trying to run the following code:

```python
from sklearn.feature_selection import mutual_info_classif

a = [[1,0,1],[0,1,1]]
b = [0,1]

mutual_info_classif(a,b)
```
Which fails with:

```
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    mutual_info_classif(a,b)
  File "python3.10/site-packages/sklearn/feature_selection/_mutual_info.py", line 465, in mutual_info_classif
    return _estimate_mi(X, y, discrete_features, True, n_neighbors, copy, random_state)
  File "python3.10/site-packages/sklearn/feature_selection/_mutual_info.py", line 301, in _estimate_mi
    mi = [
  File "python3.10/site-packages/sklearn/feature_selection/_mutual_info.py", line 302, in <listcomp>
    _compute_mi(x, y, discrete_feature, discrete_target, n_neighbors)
  File "python3.10/site-packages/sklearn/feature_selection/_mutual_info.py", line 165, in _compute_mi
    return _compute_mi_cd(x, y, n_neighbors)
  File "python3.10/site-packages/sklearn/feature_selection/_mutual_info.py", line 140, in _compute_mi_cd
    kd = KDTree(c)
  File "sklearn/neighbors/_binary_tree.pxi", line 955, in sklearn.neighbors._kd_tree.BinaryTree.__init__
  File "python3.10/site-packages/sklearn/utils/validation.py", line 805, in check_array
    raise ValueError(
ValueError: Found array with 0 sample(s) (shape=(0, 1)) while a minimum of 1 is required.
```

The code does fail because in the file `_mutual_info.py` all instances with a unique label are removed before the KDTree is called:

```python
n_samples = c.shape[0]
c = c.reshape((-1, 1))

radius = np.empty(n_samples)
label_counts = np.empty(n_samples)
k_all = np.empty(n_samples)
nn = NearestNeighbors()
for label in np.unique(d):
    mask = d == label
    count = np.sum(mask)
    if count > 1:
        k = min(n_neighbors, count - 1)
        nn.set_params(n_neighbors=k)
        nn.fit(c[mask])
        r = nn.kneighbors()[0]
        radius[mask] = np.nextafter(r[:, -1], 0)
        k_all[mask] = k
    label_counts[mask] = count

# Ignore points with unique labels.
mask = label_counts > 1
n_samples = np.sum(mask)
label_counts = label_counts[mask]
k_all = k_all[mask]
c = c[mask]
radius = radius[mask]
kd = KDTree(c)
```

I need to understand what the code does before I could debug my test script. A better error would helped here to find the problem faster.

### Describe your proposed solution

I guess the error could be improved here by checking if `c` is empty before calling KDTree:

```python
from ..utils.validation import check_array, check_X_y, _num_samples

...
radius = radius[mask]
if _num_samples(c) == 0:
    raise ValueError(
            "Found array with 0 sample(s) after masking"
            " points with unique labels. Ensure to have at least" 
            " two instances with the same label." 
    )
kd = KDTree(c)
```

### Describe alternatives you've considered, if relevant

_No response_

### Additional context

_No response_

COMMENT:
Thank you for opening the issue! I am happy to update `mutual_info_classif` with better error messages. Do you want to open a PR to improve the message?

Labels: New Feature, module:metrics