Talip7/scikit-learn-issues-multilabel huggingface dataset:
TF*IDF yields different results than TfidfTransformer

### Describe the bug

I was trying out some TF-IDF for NLP with sklearn. To double check the results, I was expecting to get the same output tfidf_matrix == TF*IDF where TF is the output of the `CountVectorizer` and IDF is the`tfidf_transformer.idf_` I was suprise to see both arrays are not the same (returns `False`):

<img width="1280" alt="image" src="https://user-images.githubusercontent.com/17580456/171156940-6455c8d8-b61c-45c2-a1ac-f1fba11d6965.png">
<img width="1280" alt="image" src="https://user-images.githubusercontent.com/17580456/171157032-3c519817-92e2-4abc-9b74-4449d390120b.png">

Is this a bug or I am missing something silly? 



### Steps/Code to Reproduce

-

### Expected Results

Both arrays to be the same

### Actual Results

Results differ

### Versions

```shell
System:
    python: 3.7.13 (default, Apr 24 2022, 01:04:09)  [GCC 7.5.0]
executable: /usr/bin/python3
   machine: Linux-5.4.188+-x86_64-with-Ubuntu-18.04-bionic

Python dependencies:
          pip: 21.1.3
   setuptools: 57.4.0
      sklearn: 1.0.2
        numpy: 1.21.6
        scipy: 1.4.1
       Cython: 0.29.30
       pandas: 1.3.5
   matplotlib: 3.2.2
       joblib: 1.1.0
threadpoolctl: 3.1.0

Built with OpenMP: True
```

COMMENT:
@jeremiedbb PR submitted. You were right, `norm` cannot be `True` (error is indeed raised during normalization). Thanks for your guidance.

Labels: Documentation, module:feature_extraction
Wrong order for check_sample_weights_invariance

### Describe the bug

The intent of check_sample_weights_invariance here: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/utils/estimator_checks.py#L1016

is as it says that for kind="zeros", will produce a y1 such that a y2 with weights will give be "identical".

However, this is not true.  Instead, the rows gets shuffled.  This matters for any method that relies upon row-order, even if reproducible.  E.g. tree methods that do row sampling will be affected.  Any splitting that occurs in the estimator itself will be different due to the different order.  Any batching for neural networks will learn in a different order.  etc.

The code should not shuffle the output for y2.  The shuffle line should be removed.

### Steps/Code to Reproduce

```
import numpy as np
from sklearn.utils import shuffle

kind = "zeros"
name = "foo"


X1 = np.array(
    [
        [1, 3],
        [1, 3],
        [1, 3],
        [1, 3],
        [2, 1],
        [2, 1],
        [2, 1],
        [2, 1],
        [3, 3],
        [3, 3],
        [3, 3],
        [3, 3],
        [4, 1],
        [4, 1],
        [4, 1],
        [4, 1],
    ],
    dtype=np.float64,
)
y1 = np.array([1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int)

if kind == "ones":
    X2 = X1
    y2 = y1
    sw2 = np.ones(shape=len(y1))
    err_msg = (
        f"For {name} sample_weight=None is not equivalent to sample_weight=ones"
    )
elif kind == "zeros":
    # Construct a dataset that is very different to (X, y) if weights
    # are disregarded, but identical to (X, y) given weights.
    X2 = np.vstack([X1, X1 + 1])
    y2 = np.hstack([y1, 3 - y1])
    sw2 = np.ones(shape=len(y1) * 2)
    sw2[len(y1) :] = 0
    X2, y2, sw2 = shuffle(X2, y2, sw2, random_state=0)

print(y1)
print(y2[sw2 > 0.0])
assert y1 == y2[sw2 > 0.0]
```

### Expected Results

No error in above copy-paste from the function with just different setup and check added at end.  No shuffle should occur.

### Actual Results

```
python checksk1.py 
```
gives:
```
[1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2]
[1 1 1 2 2 2 1 1 2 2 1 2 1 1 2 2]
```
i.e. *not* identical.

### Versions

```shell
>>> import sklearn; sklearn.show_versions()

System:
    python: 3.8.12 | packaged by conda-forge | (default, Sep 29 2021, 19:52:28)  [GCC 9.4.0]
executable: /home/jon/miniconda/bin/python
   machine: Linux-5.4.0-74-generic-x86_64-with-glibc2.10

Python dependencies:
          pip: 21.1
   setuptools: 49.6.0
      sklearn: 0.24.2
        numpy: 1.19.5
        scipy: 1.6.3
       Cython: 0.29.21
       pandas: 1.2.5
   matplotlib: 3.4.3
       joblib: 1.0.1
threadpoolctl: 3.0.0

Built with OpenMP: True
>>> 

```
```

COMMENT:
Ok, but the test isn't doing what it says it is doing.  The frames are *not* identical after dropping weights.  Those are the wrong words to use at least.

For now, I preemptively drop sample_weight=0 before the checks, so that by the time the check is done it has nothing to do now, to effectively pass the test.

Labels: Bug, Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2406678618)**

COMMENT:
```
llvm-openmp-11.1.0   |            |   0% 
llvm-openmp-11.1.0   |            |   0% 
CondaHTTPError: HTTP 403 FORBIDDEN for url <https://anaconda.org/conda-forge/llvm-openmp/11.1.0/download/osx-64/llvm-openmp-11.1.0-hda6cdc1_1.tar.bz2>
Elapsed: 00:00.040460
CF-RAY: 7134a191e8b5b172-ATL

An HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.
```

I tried to download the `.tar.bz2` file manually and the URL is still valid. So I suspect a transient network error that should automatically go away at the next build.

Labels: Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2406678618)**

COMMENT:
This seems like this one happened quite regularly recently, this seems the exact same error as https://github.com/scikit-learn/scikit-learn/issues/23454 and https://github.com/scikit-learn/scikit-learn/issues/23482.

Labels: Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2406678618)**

COMMENT:
## CI is no longer failing! ✅

[Successful run](https://github.com/scikit-learn/scikit-learn/actions/runs/2412563829)

Labels: Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2399851254)**

COMMENT:
## CI is no longer failing! ✅

[Successful run](https://github.com/scikit-learn/scikit-learn/actions/runs/2403102218)

Labels: Needs Triage
ConfusionMatrixDisplay.from_estimator(normalize='true') returns

### Describe the bug

When using the parameter `normalize` the plotting function cannot handle the floats generated after the normalization. 

### Steps/Code to Reproduce
```
from sklearn.metrics import ConfusionMatrixDisplay

# Plot Confussion matrix
y_pred = [0, 1, 1, 0, 0, 1, 2, 2, 0, 0, 2, 0, 1, 1, 1, 0, 3, 3, 3, 0, 1, 1, 2, 0, 2, 0, 0, 0, 1, 0, 2, 2, 2, 0, 3, 3, 3]
y_true = [0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 1, 0, 2, 2, 2, 0, 2, 2, 2, 0, 3, 3, 3]

ConfusionMatrixDisplay.from_predictions(y_pred, y_true, values_format='d', cmap='Blues', normalize='true')
```
### Expected Results

Confussion Matrix like this one but with values normalized. 

![1_confussion_matrix](https://user-images.githubusercontent.com/58173750/170670253-3804ec0f-34d6-490f-bb88-5a0ea470b302.png)


### Actual Results
```
        149                     text_cm = text_d
        150         else:
-->  151             text_cm = format(cm[i, j], values_format)
       153         self.text_[i, j] = ax.text(
       154             j, i, text_cm, ha="center", va="center", color=color
       155         )
       157 if self.display_labels is None:

ValueError: Unknown format code 'd' for object of type 'float'
```
### Versions

```shell
System:
    python: 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)]
executable: c:\Users\Manuel.MANUEL-PC\Documents\Git\machine-learning\.venv\Scripts\python.exe
   machine: Windows-10-10.0.22000-SP0

Python dependencies:
          pip: 22.0.3
   setuptools: 60.6.0
      sklearn: 1.0.2
        numpy: 1.22.3
        scipy: 1.6.1
       Cython: None
       pandas: 1.4.2
   matplotlib: 3.5.1
       joblib: 1.1.0
threadpoolctl: 3.1.0
```

COMMENT:
Sorry, I realized the problem was in the value_format from my size. My apologies.

Labels: Bug, Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2382037171)**

COMMENT:
Likely a temporary glitch:
```
CondaHTTPError: HTTP 403 FORBIDDEN for url <https://anaconda.org/conda-forge/llvm-openmp/11.1.0/download/osx-64/llvm-openmp-11.1.0-hda6cdc1_1.tar.bz2>
```

but I can download the file fine ...

I guess we can wait until the next scheduled build to see if the error goes away.

Labels: Needs Triage
⚠️ CI failed on Wheel builder ⚠️

**CI Failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/2382037171)**

COMMENT:
## CI is no longer failing! ✅

[Successful run](https://github.com/scikit-learn/scikit-learn/actions/runs/2394479493)

Labels: Needs Triage
Default constant value in SimpleImputer with heterogeneous data

Let's consider the following example:

```python
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer

X = pd.DataFrame(
    {
        "numerics": [1, 2, 3, np.nan],
        "strings": ["A", "B", "C", np.nan],
    }
)

imputer = SimpleImputer(strategy="constant")
imputer.fit_transform(X)
```

```py
array([[1.0, 'A'],
       [2.0, 'B'],
       [3.0, 'C'],
       ['missing_value', 'missing_value']], dtype=object)
```

I was wondering if instead of filling with `"missing_value"` for the first column, we should instead default with `0` as we would do when we only have numerical values.

In short, we always impute with `0` for numerics and `"missing_values"` with strings in the case of heterogeneous datasets.

COMMENT:
But SimpleImputer doesn't work on heterogeneous data. I mean that X goes through `validate_data` and then X is a numpy array with a unque dtype. With your initial X, the dtype will be object and thus the fill_value will be `missing_value`.

To do what you want you need to add a ColumnTransformer imo

Labels: module:impute
Default constant value in SimpleImputer with heterogeneous data

Let's consider the following example:

```python
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer

X = pd.DataFrame(
    {
        "numerics": [1, 2, 3, np.nan],
        "strings": ["A", "B", "C", np.nan],
    }
)

imputer = SimpleImputer(strategy="constant")
imputer.fit_transform(X)
```

```py
array([[1.0, 'A'],
       [2.0, 'B'],
       [3.0, 'C'],
       ['missing_value', 'missing_value']], dtype=object)
```

I was wondering if instead of filling with `"missing_value"` for the first column, we should instead default with `0` as we would do when we only have numerical values.

In short, we always impute with `0` for numerics and `"missing_values"` with strings in the case of heterogeneous datasets.

COMMENT:
Looking at it again, I think that `OrdinalEncoder` managing to encode missing values is solving the use case that I have in mind.

I still think that removing the need for a `ColumnTransformer` would be great. It would make it easier for custom transformers that would not have to deal with mixed types in a single column but we don't have currently this need in scikit-learn.

Closing then.

Labels: module:impute
Include drop='last' to OneHotEncoder

### Describe the workflow you want to enable

When using `SimpleImputer` + `OneHotEncoder`, I am able to add a new constant category for NaN values like the example below:

```python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import numpy as np

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)

# array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])
```

However, I wanted to have an argument like `OneHotEncoder(drop='last')` in order to have an output like:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

This would allow all NaNs to be filled with zeros. 

### Describe your proposed solution

```
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(drop='last'))])
```

### Describe alternatives you've considered, if relevant

There's no good alternative for compatibility with sklearn's pipelines. I was following the issue #11996 of adding a handle_missing to OneHotEncoder but it has been ignored in favor of using a "constant" strategy on the categorical columns. But the constant strategy will add an unnecessary new column that could be dropped in this scenario.

### Additional context

_No response_

COMMENT:
There is a `drop` argument in `OneHotEncoder` which you can pass a array to (one category to drop for each feature), can you use this for you use case? Adapting your snippet, something like this:

```py
import numpy as np
import pandas as pd
from sklearn.preprocessing import OneHotEncoder

df = pd.DataFrame(['Male', 'Female', np.nan])
ohe = OneHotEncoder(drop=[np.nan])
ohe.fit_transform(df).toarray()
```

Output:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

Labels: New Feature, module:preprocessing, Needs Decision - Include Feature
Include drop='last' to OneHotEncoder

### Describe the workflow you want to enable

When using `SimpleImputer` + `OneHotEncoder`, I am able to add a new constant category for NaN values like the example below:

```python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import numpy as np

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)

# array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])
```

However, I wanted to have an argument like `OneHotEncoder(drop='last')` in order to have an output like:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

This would allow all NaNs to be filled with zeros. 

### Describe your proposed solution

```
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(drop='last'))])
```

### Describe alternatives you've considered, if relevant

There's no good alternative for compatibility with sklearn's pipelines. I was following the issue #11996 of adding a handle_missing to OneHotEncoder but it has been ignored in favor of using a "constant" strategy on the categorical columns. But the constant strategy will add an unnecessary new column that could be dropped in this scenario.

### Additional context

_No response_

COMMENT:
I think the original request could be a convenience in some cases but it's a bit weird to have a drop strategy that depends on the lexicographical ordering of the categories.

For this particular case, I think @lesteve's solution is the right approach.

We could also offer to drop the `"most_frequent"` (and maybe also `"least_frequent"` although the latter is probably very unstable under CV/resampling) to drop a category based on its frequency in the training set.

Since the choice of the category to drop has an impact on the effect of regularization in a downstream linear model, dropping based on the frequency on the training set might be a good strategy to reduce collinearity for non-binary categorical variables in general.

Maybe @lorentzenchr has an opinion on this.

Labels: New Feature, module:preprocessing, Needs Decision - Include Feature
Include drop='last' to OneHotEncoder

### Describe the workflow you want to enable

When using `SimpleImputer` + `OneHotEncoder`, I am able to add a new constant category for NaN values like the example below:

```python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import numpy as np

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)

# array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])
```

However, I wanted to have an argument like `OneHotEncoder(drop='last')` in order to have an output like:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

This would allow all NaNs to be filled with zeros. 

### Describe your proposed solution

```
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(drop='last'))])
```

### Describe alternatives you've considered, if relevant

There's no good alternative for compatibility with sklearn's pipelines. I was following the issue #11996 of adding a handle_missing to OneHotEncoder but it has been ignored in favor of using a "constant" strategy on the categorical columns. But the constant strategy will add an unnecessary new column that could be dropped in this scenario.

### Additional context

_No response_

COMMENT:
IIRC, R‘s formula drops the first level by default. That corresponds to our option `"first"`. ~~Having first, why not have an option `"last"`.~~ Edit: maybe not worth it.

More striking is the argument to have `"most_frequent"`. This is a strategy that I‘ve seen in other GLM software. Model coefficients are then the effect relative to this most frequent level which seems the most natural choice (but is irrelevant for most other things).

We could also consider to support sample weights with "most_frequent", i.e. choose the level with highest sum of sample weights.

To the best of my knowledge, for linear models with penalties, one should never drop a level. For unpenalized linear models, the converse is true: always drop one level (otherwise one has perfect collinearity and solvers have a much harder job finding the unique minimum norm solution).

Labels: New Feature, module:preprocessing, Needs Decision - Include Feature
Include drop='last' to OneHotEncoder

### Describe the workflow you want to enable

When using `SimpleImputer` + `OneHotEncoder`, I am able to add a new constant category for NaN values like the example below:

```python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import numpy as np

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)

# array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])
```

However, I wanted to have an argument like `OneHotEncoder(drop='last')` in order to have an output like:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

This would allow all NaNs to be filled with zeros. 

### Describe your proposed solution

```
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(drop='last'))])
```

### Describe alternatives you've considered, if relevant

There's no good alternative for compatibility with sklearn's pipelines. I was following the issue #11996 of adding a handle_missing to OneHotEncoder but it has been ignored in favor of using a "constant" strategy on the categorical columns. But the constant strategy will add an unnecessary new column that could be dropped in this scenario.

### Additional context

_No response_

COMMENT:
There is a (stalled) open PR for `drop="most_frequent"` here: #18679.

Labels: New Feature, module:preprocessing, Needs Decision - Include Feature
Include drop='last' to OneHotEncoder

### Describe the workflow you want to enable

When using `SimpleImputer` + `OneHotEncoder`, I am able to add a new constant category for NaN values like the example below:

```python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import numpy as np

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)

# array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])
```

However, I wanted to have an argument like `OneHotEncoder(drop='last')` in order to have an output like:
```
array([[0., 1.],
       [1., 0.],
       [0., 0.]])
```

This would allow all NaNs to be filled with zeros. 

### Describe your proposed solution

```
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant')),
    ('encoder', OneHotEncoder(drop='last'))])
```

### Describe alternatives you've considered, if relevant

There's no good alternative for compatibility with sklearn's pipelines. I was following the issue #11996 of adding a handle_missing to OneHotEncoder but it has been ignored in favor of using a "constant" strategy on the categorical columns. But the constant strategy will add an unnecessary new column that could be dropped in this scenario.

### Additional context

_No response_

COMMENT:
I agree it is not worth it to have a `drop="last"`. The `drop="most_frequent"` feature is being tracked in https://github.com/scikit-learn/scikit-learn/issues/18553.

Labels: New Feature, module:preprocessing, Needs Decision - Include Feature
The location of `distance_metrics()` is wrong in this documentation snippet.

In `sklearn/metrics/pairwise.py` replacing
```
the __doc__ of the sklearn.pairwise.distance_metrics
```
by 
```
:func:`sklearn.metrics.pairwise.pairwise_distances`
```

would be the best thing to do I think. This way it will be a hyperlink in the HTML documentation.

### Originally discussed in https://github.com/scikit-learn/scikit-learn/discussions/23171

<div type='discussions-op-text'>

<sup>Originally posted by **leogama** April 20, 2022</sup>
https://github.com/scikit-learn/scikit-learn/blob/baf828ca126bcb2c0ad813226963621cafe38adb/sklearn/metrics/pairwise.py#L1765

The correct path should be `sklearn.metrics.pairwise.distance_metrics`, instead of `sklearn.pairwise.distance_metrics`.</div>

COMMENT:
Hi would love to take this one on.

Labels: Easy, Documentation, good first issue
Change <= to \leq sign in tree module documentation

### Describe the issue linked to the documentation

I have found out that less or equal sign is written [here](https://scikit-learn.org/stable/modules/tree.html#mathematical-formulation) as "<=" instead of special LaTeX \leq symbol, which is inconsistent with other documentation pages.



### Suggest a potential alternative/fix

change the "<=" to \leq

COMMENT:
I am going to to this!

Labels: Documentation, Needs Triage