Potential Problem in the Computation of Adjusted Mutual Info Score

### Describe the bug

It seems to me that for clusters of size 2 and 4, the AMI yields unexpected results of 0 instead of 1, if all items belong to different clusters. 



### Steps/Code to Reproduce

Sample Code to Reproduce:

```python
>>> from sklearn.metrics.cluster import adjusted_mutual_info_score
>>> print(adjusted_mutual_info_score([1, 2], [3, 4])
0.0
>>> print(adjusted_mutual_info_score([1, 2, 3, 4], [5, 6, 7, 8])
0.0
>>> print(adjusted_mutual_info_score([1, 2, 3, 4, 5], [6, 7, 8, 9, 10])
1.0
```

### Expected Results

As the clusters are identical in all cases, I'd expect the result to be 1.0 in all cases. This happens with version 1.6.1.

### Actual Results

So we have the strange behavior that the code outputs for lists containing different labels with 2 items and with 4 items the value 0, while we deal with identical partitions. I tested until 1000 items, it only occurs with 2 and 4.

### Versions

```shell
System:
    python: 3.13.1 (main, Dec  4 2024, 18:05:56) [GCC 14.2.1 20240910]
executable: /home/mattis/.envs/lexi/bin/python
   machine: Linux-6.12.10-arch1-1-x86_64-with-glibc2.41

Python dependencies:
      sklearn: 1.6.1
          pip: 24.3.1
   setuptools: 75.8.0
        numpy: 2.2.2
        scipy: 1.15.2
       Cython: None
       pandas: None
   matplotlib: None
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 20
         prefix: libscipy_openblas
       filepath: /home/mattis/.envs/lexi/lib/python3.13/site-packages/numpy.libs/libscipy_openblas64_-6bb31eeb.so
        version: 0.3.28
threading_layer: pthreads
   architecture: Haswell

       user_api: blas
   internal_api: openblas
    num_threads: 20
         prefix: libscipy_openblas
       filepath: /home/mattis/.envs/lexi/lib/python3.13/site-packages/scipy.libs/libscipy_openblas-68440149.so
        version: 0.3.28
threading_layer: pthreads
   architecture: Haswell

       user_api: openmp
   internal_api: openmp
    num_threads: 20
         prefix: libgomp
       filepath: /home/mattis/.envs/lexi/lib/python3.13/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
```

COMMENT:
Hello,

first of all, I see that the bug is reproducible even with the same clusterings:

```
>>> from sklearn.metrics.cluster import adjusted_mutual_info_score

>>> print(adjusted_mutual_info_score([0, 1], [0, 1]))
0.0
>>> print(adjusted_mutual_info_score([1, 2, 3], [1, 2, 3]))
1.0
>>> print(adjusted_mutual_info_score([1, 2, 3, 4], [1, 2, 3, 4]))
0.0
>>> print(adjusted_mutual_info_score([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]))
1.0
```

This is part of the source code of `adjust_mutual_info_score`. 

```
    contingency = contingency_matrix(labels_true, labels_pred, sparse=True)

    # Calculate the MI for the two clusterings
    mi = mutual_info_score(labels_true, labels_pred, contingency=contingency)

    # Calculate the expected value for the mutual information
    emi = expected_mutual_information(contingency, n_samples)

    # Calculate entropy for each labeling
    h_true, h_pred = entropy(labels_true), entropy(labels_pred)
    normalizer = _generalized_average(h_true, h_pred, average_method)
    denominator = normalizer - emi

    # Avoid 0.0 / 0.0 when expectation equals maximum, i.e. a perfect match.
    # normalizer should always be >= emi, but because of floating-point
    # representation, sometimes emi is slightly larger. Correct this
    # by preserving the sign.
    if denominator < 0:
        denominator = min(denominator, -np.finfo("float64").eps)
    else:
        denominator = max(denominator, np.finfo("float64").eps)
    ami = (mi - emi) / denominator
    return float(ami)
```

It seems that the issue arises from the fact that `mi` is exactly equal to `emi` for the cases of 2 and 4 labels, so eventually `ami=0`. 

- for `adjusted_mutual_info_score([0, 1], [0, 1])` , `mi = emi =0.6931471805599453`
- for `adjusted_mutual_info_score([1, 2, 3], [1, 2, 3])` , `mi =1.0986122886681096`  and `emi =1.0986122886681098`


Perhaps this is a numerical issue as for the case of size 3 `mi` and `emi` differ only at the last digit.

Labels: Bug