Talip7/scikit-learn-issues-multilabel huggingface dataset:
Case when y_test contains a single class and y_test == y_pred.

### Describe the bug

It shows wrong output when we call this function
So all The issue related to precision, recall , F1_score, confusion_matrix , class_likelihood_ratios is trigged
Case when y_test contains a single class and y_test == y_pred

### Steps/Code to Reproduce

y_true = np.array([1, 1])
y_pred = np.array([1, 1])
print(confusion_matrix(y_true, y_pred))

### Expected Results

[[2,0],
[0,0]]

### Actual Results

[[2]]

### Versions

```shell
System:
    python: 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0]
executable: /usr/bin/python
   machine: Linux-5.19.0-50-generic-x86_64-with-glibc2.35

Python dependencies:
      sklearn: 1.3.0
          pip: 22.0.2
   setuptools: 59.6.0
        numpy: 1.25.1
        scipy: 1.10.0
       Cython: None
       pandas: 1.5.3
   matplotlib: 3.7.1
       joblib: 1.2.0
threadpoolctl: 3.1.0

Built with OpenMP: True

threadpoolctl info:
       user_api: openmp
   internal_api: openmp
         prefix: libgomp
       filepath: /home/marek/.local/lib/python3.10/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/numpy.libs/libopenblas64_p-r0-7a851222.3.23.so
        version: 0.3.23
threading_layer: pthreads
   architecture: Zen
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /home/marek/.local/lib/python3.10/site-packages/scipy.libs/libopenblasp-r0-41284840.3.18.so
        version: 0.3.18
threading_layer: pthreads
   architecture: Zen
    num_threads: 16
```

COMMENT:
/take

Labels: Bug, Needs Triage
Case when y_test contains a single class and y_test == y_pred.

### Describe the bug

It shows wrong output when we call this function
So all The issue related to precision, recall , F1_score, confusion_matrix , class_likelihood_ratios is trigged
Case when y_test contains a single class and y_test == y_pred

### Steps/Code to Reproduce

y_true = np.array([1, 1])
y_pred = np.array([1, 1])
print(confusion_matrix(y_true, y_pred))

### Expected Results

[[2,0],
[0,0]]

### Actual Results

[[2]]

### Versions

```shell
System:
    python: 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0]
executable: /usr/bin/python
   machine: Linux-5.19.0-50-generic-x86_64-with-glibc2.35

Python dependencies:
      sklearn: 1.3.0
          pip: 22.0.2
   setuptools: 59.6.0
        numpy: 1.25.1
        scipy: 1.10.0
       Cython: None
       pandas: 1.5.3
   matplotlib: 3.7.1
       joblib: 1.2.0
threadpoolctl: 3.1.0

Built with OpenMP: True

threadpoolctl info:
       user_api: openmp
   internal_api: openmp
         prefix: libgomp
       filepath: /home/marek/.local/lib/python3.10/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/numpy.libs/libopenblas64_p-r0-7a851222.3.23.so
        version: 0.3.23
threading_layer: pthreads
   architecture: Zen
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /home/marek/.local/lib/python3.10/site-packages/scipy.libs/libopenblasp-r0-41284840.3.18.so
        version: 0.3.18
threading_layer: pthreads
   architecture: Zen
    num_threads: 16
```

COMMENT:
You need to pass `labels=[0, 1]` because we cannot infer what are the labels from the data provided.

Labels: Bug, Needs Triage
Case when y_test contains a single class and y_test == y_pred.

### Describe the bug

It shows wrong output when we call this function
So all The issue related to precision, recall , F1_score, confusion_matrix , class_likelihood_ratios is trigged
Case when y_test contains a single class and y_test == y_pred

### Steps/Code to Reproduce

y_true = np.array([1, 1])
y_pred = np.array([1, 1])
print(confusion_matrix(y_true, y_pred))

### Expected Results

[[2,0],
[0,0]]

### Actual Results

[[2]]

### Versions

```shell
System:
    python: 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0]
executable: /usr/bin/python
   machine: Linux-5.19.0-50-generic-x86_64-with-glibc2.35

Python dependencies:
      sklearn: 1.3.0
          pip: 22.0.2
   setuptools: 59.6.0
        numpy: 1.25.1
        scipy: 1.10.0
       Cython: None
       pandas: 1.5.3
   matplotlib: 3.7.1
       joblib: 1.2.0
threadpoolctl: 3.1.0

Built with OpenMP: True

threadpoolctl info:
       user_api: openmp
   internal_api: openmp
         prefix: libgomp
       filepath: /home/marek/.local/lib/python3.10/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/numpy.libs/libopenblas64_p-r0-7a851222.3.23.so
        version: 0.3.23
threading_layer: pthreads
   architecture: Zen
    num_threads: 16

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /home/marek/.local/lib/python3.10/site-packages/scipy.libs/libopenblasp-r0-41284840.3.18.so
        version: 0.3.18
threading_layer: pthreads
   architecture: Zen
    num_threads: 16
```

COMMENT:
what if our model accuracy is 100%

Labels: Bug, Needs Triage
⚠️ CI failed on macOS.pylatest_conda_mkl_no_openmp ⚠️

**CI failed on [macOS.pylatest_conda_mkl_no_openmp](https://dev.azure.com/scikit-learn/scikit-learn/_build/results?buildId=57880&view=logs&j=e6d5b7c0-0dfd-5ddf-13d5-c71bebf56ce2)** (Aug 11, 2023)
Unable to find junit file. Please see link for details.

COMMENT:
I am closing because the [ci logs](https://dev.azure.com/scikit-learn/scikit-learn/_build/results?buildId=57880&view=logs&j=e6d5b7c0-0dfd-5ddf-13d5-c71bebf56ce2&t=83107d01-18db-5293-bb0f-49ac2bf2f625) point to a HTTP error from conda.

Labels: Needs Triage
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
We did not document it for the following reason:

- we don't require third-party libraries to use the framework
- the API was still experimental and was, up-to-now, private

> In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la

We have common tests:

https://github.com/scikit-learn/scikit-learn/blob/acf60def1cff9d440c86b34e9a27a8c44de4d71f/sklearn/tests/test_common.py#L495-L508

and the following file for the functions: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/tests/test_public_functions.py

Labels: Documentation, Validation
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
If the documentation is internal, then we can start with documentation at the top of the file:

https://github.com/scikit-learn/scikit-learn/blob/acf60def1cff9d440c86b34e9a27a8c44de4d71f/sklearn/utils/_param_validation.py#L1

We do something similar for the Pairwise distance ArgK min:

https://github.com/scikit-learn/scikit-learn/blob/acf60def1cff9d440c86b34e9a27a8c44de4d71f/sklearn/metrics/_pairwise_distances_reduction/__init__.py#L1-L6

Labels: Documentation, Validation
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
Yes, I meant in particular documentation for ourselves. If I were to write a new estimator class in scikit-learn, I would currently be lost and start by copy & paste an arbitrary existing class.

Labels: Documentation, Validation
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
OK, I totally see your point. I will address this issue.

Labels: Documentation, Validation
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
/take

Labels: Documentation, Validation
Document developer utils for parameter validation

### Describe the issue linked to the documentation

https://github.com/scikit-learn/scikit-learn/pull/22722 and https://github.com/scikit-learn/scikit-learn/issues/24862 introduced parameter validation.

These tools should be documented under https://scikit-learn.org/dev/developers/utilities.html#validation-tools.

In addition, a lot of tests for raising errors in case of bad input seems to disappear. Are there common tests for it or is it still recommended to write tests a la
```python
def test_estim_raises():
    est = Estim(n_rounds="should be a number")
    with pytest.raises(ValueError):
        est.fit(X, y)
```

### Suggest a potential alternative/fix

_No response_

COMMENT:
We could extend the "maintainers" section of the doc to explain things like that and other conventions we need to have in mind when reviewing PRs

Labels: Documentation, Validation
HDBSCAN hierarchy tree plotting

### Describe the workflow you want to enable

I have tried working with the newly introduces hdbscan clustering functionality and this works perfectly on the dataset I'm handling but I haven't found a way to plot the hierarchy tree of the clustering that clearly shows the effect of increasing the distance epsilon on the clustering. Although the implementation automatically clusters all the points, I think plotting the tree can really help with understanding the data and the clustering.
This is already part of the hdbscan package, but I can't find it in the sklearn implementation. 

### Describe your proposed solution

I would just add the functionalities from hdbscan in the same way as these work well. But it's better if it's part of the sklearn package.

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

Alternatively, sklearn could depend on hdbscan, but this is not the best solution.

### Additional context

_No response_

COMMENT:
I think we could potentially add it in as function in the `cluster._hdbscan` submodule. We omitted it initially to keep the port of `HDBSCAN` as simple as possible, but if folks have interest in the feature then its inclusion should be relatively straightforward.

Labels: New Feature
HDBSCAN hierarchy tree plotting

### Describe the workflow you want to enable

I have tried working with the newly introduces hdbscan clustering functionality and this works perfectly on the dataset I'm handling but I haven't found a way to plot the hierarchy tree of the clustering that clearly shows the effect of increasing the distance epsilon on the clustering. Although the implementation automatically clusters all the points, I think plotting the tree can really help with understanding the data and the clustering.
This is already part of the hdbscan package, but I can't find it in the sklearn implementation. 

### Describe your proposed solution

I would just add the functionalities from hdbscan in the same way as these work well. But it's better if it's part of the sklearn package.

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

Alternatively, sklearn could depend on hdbscan, but this is not the best solution.

### Additional context

_No response_

COMMENT:
```python
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from sklearn.datasets import make_blobs
from hdbscan import HDBSCAN

# Generate sample data
data, _ = make_blobs(n_samples=300, centers=3, random_state=42)

# Fit HDBSCAN
hdbscan = HDBSCAN(min_cluster_size=10)
labels = hdbscan.fit_predict(data)

# Extract hierarchy information
hierarchy = hdbscan.condensed_tree_.to_pandas()

# Create a directed graph
G = nx.DiGraph()

# Add nodes to the graph
for idx, row in hierarchy.iterrows():
    G.add_node(idx, size=row['child_size'])

# Add edges based on parent-child relationships
for idx, row in hierarchy.iterrows():
    parent = row['parent']
    if parent >= 0:
        G.add_edge(parent, idx)

# Create a plot
pos = nx.spring_layout(G)
sizes = np.array([data for _, data in G.nodes(data='size')])
nx.draw(G, pos, node_size=sizes * 100, with_labels=False)
plt.show()
```


Try this code out I have checked and its is working for the HDBSCAN hierarchy tree plotting

Labels: New Feature
Non-metric MDS gives nonsense results on the Digits dataset

### Describe the bug

I am running metric and nonmetric MDS on the Digits dataset, and obtain nonsense results with `metric=False`. At the same time, my understanding is that non-metric MDS is more flexible and should not yield worse results compared to metric MDS. Is my understanding wrong, or does it suggest some problems with the non-metric MDS implementation?

### Steps/Code to Reproduce

```Python
%matplotlib notebook

import pylab as plt
import numpy as np
from sklearn.datasets import load_digits
from sklearn.manifold import MDS

digits = load_digits()
X, y = digits.data, digits.target

Z1 = MDS(n_components=2, n_init=1, random_state=42).fit_transform(X)
Z2 = MDS(n_components=2, n_init=1, random_state=42, metric=False).fit_transform(X)

titles = ['Metric MDS', 'Non-metric MDS']

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(6, 3), layout='constrained')

for i,Z in enumerate([Z1, Z2]):
    ax = axs.ravel()[i]
    
    ax.set_aspect('equal', 'datalim')
    
    ind = np.random.permutation(X.shape[0])
    ax.scatter(*Z[ind].T, s=3, color=plt.cm.Dark2(y)[ind])

    ax.set_xticks([])
    ax.set_yticks([])
    for sp in ax.spines:
        ax.spines[sp].set_visible(False)
        
    ax.set_title(titles[i])
    
fig.savefig('digits-embed-mds-nonmetric.png', dpi=300)
```

### Expected Results

Non-metric MDS giving something sensible.

### Actual Results

![digits-embed-mds-nonmetric](https://github.com/scikit-learn/scikit-learn/assets/8970231/aa6af88a-75d0-4ef2-ab6e-6482c4df5ae8)


### Versions

```shell
System:
    python: 3.7.9 (default, Aug 31 2020, 12:42:55)  [GCC 7.3.0]
executable: /home/dmitry/anaconda3/bin/python
   machine: Linux-5.15.0-76-generic-x86_64-with-debian-bullseye-sid

Python dependencies:
          pip: 22.3.1
   setuptools: 65.6.3
      sklearn: 0.24.1
        numpy: 1.21.5
        scipy: 1.7.3
       Cython: 0.29.32
       pandas: 1.3.5
   matplotlib: 3.5.2
       joblib: 1.1.1
threadpoolctl: 2.2.0

Built with OpenMP: True
```

COMMENT:
Maybe @NelleV would know what's going on here? She is the main author of the MDS class, it seems.

Labels: Bug, Needs Investigation
Non-metric MDS gives nonsense results on the Digits dataset

### Describe the bug

I am running metric and nonmetric MDS on the Digits dataset, and obtain nonsense results with `metric=False`. At the same time, my understanding is that non-metric MDS is more flexible and should not yield worse results compared to metric MDS. Is my understanding wrong, or does it suggest some problems with the non-metric MDS implementation?

### Steps/Code to Reproduce

```Python
%matplotlib notebook

import pylab as plt
import numpy as np
from sklearn.datasets import load_digits
from sklearn.manifold import MDS

digits = load_digits()
X, y = digits.data, digits.target

Z1 = MDS(n_components=2, n_init=1, random_state=42).fit_transform(X)
Z2 = MDS(n_components=2, n_init=1, random_state=42, metric=False).fit_transform(X)

titles = ['Metric MDS', 'Non-metric MDS']

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(6, 3), layout='constrained')

for i,Z in enumerate([Z1, Z2]):
    ax = axs.ravel()[i]
    
    ax.set_aspect('equal', 'datalim')
    
    ind = np.random.permutation(X.shape[0])
    ax.scatter(*Z[ind].T, s=3, color=plt.cm.Dark2(y)[ind])

    ax.set_xticks([])
    ax.set_yticks([])
    for sp in ax.spines:
        ax.spines[sp].set_visible(False)
        
    ax.set_title(titles[i])
    
fig.savefig('digits-embed-mds-nonmetric.png', dpi=300)
```

### Expected Results

Non-metric MDS giving something sensible.

### Actual Results

![digits-embed-mds-nonmetric](https://github.com/scikit-learn/scikit-learn/assets/8970231/aa6af88a-75d0-4ef2-ab6e-6482c4df5ae8)


### Versions

```shell
System:
    python: 3.7.9 (default, Aug 31 2020, 12:42:55)  [GCC 7.3.0]
executable: /home/dmitry/anaconda3/bin/python
   machine: Linux-5.15.0-76-generic-x86_64-with-debian-bullseye-sid

Python dependencies:
          pip: 22.3.1
   setuptools: 65.6.3
      sklearn: 0.24.1
        numpy: 1.21.5
        scipy: 1.7.3
       Cython: 0.29.32
       pandas: 1.3.5
   matplotlib: 3.5.2
       joblib: 1.1.1
threadpoolctl: 2.2.0

Built with OpenMP: True
```

COMMENT:
> At the same time, my understanding is that non-metric MDS is more flexible

Yes, I would expect its solution space is a superset of metric MDS

> and should not yield worse results compared to metric MDS

This I'm less confident about. It's flexibility and optimization strategy honestly may make it more liable to find "suboptimal" or "poor" embeddings since it "only" cares about ordinality of data.

I really am not sure whether this is just an example of how constrained systems can outperform under-constrained systems, or if there is something operatively incorrect about the non-metric MDS implementation, but I lean towards the prior.

Labels: Bug, Needs Investigation
Non-metric MDS gives nonsense results on the Digits dataset

### Describe the bug

I am running metric and nonmetric MDS on the Digits dataset, and obtain nonsense results with `metric=False`. At the same time, my understanding is that non-metric MDS is more flexible and should not yield worse results compared to metric MDS. Is my understanding wrong, or does it suggest some problems with the non-metric MDS implementation?

### Steps/Code to Reproduce

```Python
%matplotlib notebook

import pylab as plt
import numpy as np
from sklearn.datasets import load_digits
from sklearn.manifold import MDS

digits = load_digits()
X, y = digits.data, digits.target

Z1 = MDS(n_components=2, n_init=1, random_state=42).fit_transform(X)
Z2 = MDS(n_components=2, n_init=1, random_state=42, metric=False).fit_transform(X)

titles = ['Metric MDS', 'Non-metric MDS']

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(6, 3), layout='constrained')

for i,Z in enumerate([Z1, Z2]):
    ax = axs.ravel()[i]
    
    ax.set_aspect('equal', 'datalim')
    
    ind = np.random.permutation(X.shape[0])
    ax.scatter(*Z[ind].T, s=3, color=plt.cm.Dark2(y)[ind])

    ax.set_xticks([])
    ax.set_yticks([])
    for sp in ax.spines:
        ax.spines[sp].set_visible(False)
        
    ax.set_title(titles[i])
    
fig.savefig('digits-embed-mds-nonmetric.png', dpi=300)
```

### Expected Results

Non-metric MDS giving something sensible.

### Actual Results

![digits-embed-mds-nonmetric](https://github.com/scikit-learn/scikit-learn/assets/8970231/aa6af88a-75d0-4ef2-ab6e-6482c4df5ae8)


### Versions

```shell
System:
    python: 3.7.9 (default, Aug 31 2020, 12:42:55)  [GCC 7.3.0]
executable: /home/dmitry/anaconda3/bin/python
   machine: Linux-5.15.0-76-generic-x86_64-with-debian-bullseye-sid

Python dependencies:
          pip: 22.3.1
   setuptools: 65.6.3
      sklearn: 0.24.1
        numpy: 1.21.5
        scipy: 1.7.3
       Cython: 0.29.32
       pandas: 1.3.5
   matplotlib: 3.5.2
       joblib: 1.1.1
threadpoolctl: 2.2.0

Built with OpenMP: True
```

COMMENT:
What do you think @Micky774? To me the above is evidence that the optimisation is not working correctly.

Labels: Bug, Needs Investigation