Talip7/scikit-learn-issues-multilabel huggingface dataset:
Suggesting updates on the doc of `sklearn.linear_model.OrthogonalMatchingPursuit`

### Describe the issue linked to the documentation

Hi,

We discover an inconsistency issue between documentation and code in the class [`sklearn.linear_model.OrthogonalMatchingPursuit`](https://scikit-learn.org/dev/modules/generated/sklearn.linear_model.OrthogonalMatchingPursuit.html#sklearn-linear-model-orthogonalmatchingpursuit). As mentioned in the description of parameter `n_nonzero_coefs` and `tol`.

> **n_nonzero_coefs: int, default=None**
Desired number of non-zero entries in the solution. _**If None (by default) this value is set to 10% of n_features.**_

> **tol: float, default=None**
Maximum squared norm of the residual. _**If not None, overrides n_nonzero_coefs.**_

The most relevant piece of source code looks like this:
```
if self.n_nonzero_coefs is None and self.tol is None:
    self.n_nonzero_coefs_ = max(int(0.1 * n_features), 1)
else:
    self.n_nonzero_coefs_ = self.n_nonzero_coefs
```

This piece of code does not logically cover the description in the documentation perfectly. For example, when `n_nonzero_coefs` is None and `tol` is not None, `n_nonzero_coefs` will be still overridden. However as the rule in `n_nonzero_coefs`, `n_nonzero_coefs` should be set to 10% of n_features.

Could you please check it?

### Suggest a potential alternative/fix

Maybe you can reconstruct the if-else branch to cover the situation or update the doc to make it clear.

COMMENT:
Are you interested? I'm happy to make a PR otherwise.

Labels: Documentation
Suggesting updates on the doc of `sklearn.linear_model.OrthogonalMatchingPursuit`

### Describe the issue linked to the documentation

Hi,

We discover an inconsistency issue between documentation and code in the class [`sklearn.linear_model.OrthogonalMatchingPursuit`](https://scikit-learn.org/dev/modules/generated/sklearn.linear_model.OrthogonalMatchingPursuit.html#sklearn-linear-model-orthogonalmatchingpursuit). As mentioned in the description of parameter `n_nonzero_coefs` and `tol`.

> **n_nonzero_coefs: int, default=None**
Desired number of non-zero entries in the solution. _**If None (by default) this value is set to 10% of n_features.**_

> **tol: float, default=None**
Maximum squared norm of the residual. _**If not None, overrides n_nonzero_coefs.**_

The most relevant piece of source code looks like this:
```
if self.n_nonzero_coefs is None and self.tol is None:
    self.n_nonzero_coefs_ = max(int(0.1 * n_features), 1)
else:
    self.n_nonzero_coefs_ = self.n_nonzero_coefs
```

This piece of code does not logically cover the description in the documentation perfectly. For example, when `n_nonzero_coefs` is None and `tol` is not None, `n_nonzero_coefs` will be still overridden. However as the rule in `n_nonzero_coefs`, `n_nonzero_coefs` should be set to 10% of n_features.

Could you please check it?

### Suggest a potential alternative/fix

Maybe you can reconstruct the if-else branch to cover the situation or update the doc to make it clear.

COMMENT:
Yes, that would be much clearer. Please, go ahead with the PR, @lucyleeow. :heart:

Labels: Documentation
RFC Revisiting meta-routing developer API for defining method mappings

For metadata routing, meta-estimators define method mappings through this API:

```python
router = MetadataRouter(...).add(
	 method_mapping=MethodMapping()
     .add(callee="fit", caller="fit")
     .add(callee="transform", caller="fit")
     .add(callee="transform", caller="predict"),
)
```

Currently, we have a shortcut to map every available method dynamically:

```python
MetadataRouter(...).add(method_mapping="one-to-one")
```

And a shortcut to do a single "one-to-one" mapping:

```python
MetadataRouter(...).add(method_mapping="score")
```

https://github.com/scikit-learn/scikit-learn/pull/28422 proposes to remove both theses shortcuts. The proposal makes sense as it forces everything to be explicit and there is only one way to define the method mappings.

On the other hand, I think a majority of the time a meta-estimator does "one-to-one" method mappings. In https://github.com/scikit-learn/scikit-learn/pull/28422#issuecomment-1951377557, I proposed this API:

```python
# Single string for a single mapping:
MethodMapping().add_one_to_one("score")

# Add a second mapping by using a list:
MethodMapping().add_one_to_one(["score", "predict"])
```

I'm mostly considering third party meta-estimator developers and how to make it easier for them to adopt the metadata routing API and define these mappings. If `add_one_to_one` handles a majority of the use cases, I think it's worth introducing even if it a second way to specify the mappings.

COMMENT:
I'm fine with adding a new method instead of the string. It has the advantage to be more explicit to have its own docstring. We can cross-reference the `add` and `add_one_to_one` functions in the documentation as well.

Labels: API, Needs Decision, Needs Decision - Close, Metadata Routing
RFC Revisiting meta-routing developer API for defining method mappings

For metadata routing, meta-estimators define method mappings through this API:

```python
router = MetadataRouter(...).add(
	 method_mapping=MethodMapping()
     .add(callee="fit", caller="fit")
     .add(callee="transform", caller="fit")
     .add(callee="transform", caller="predict"),
)
```

Currently, we have a shortcut to map every available method dynamically:

```python
MetadataRouter(...).add(method_mapping="one-to-one")
```

And a shortcut to do a single "one-to-one" mapping:

```python
MetadataRouter(...).add(method_mapping="score")
```

https://github.com/scikit-learn/scikit-learn/pull/28422 proposes to remove both theses shortcuts. The proposal makes sense as it forces everything to be explicit and there is only one way to define the method mappings.

On the other hand, I think a majority of the time a meta-estimator does "one-to-one" method mappings. In https://github.com/scikit-learn/scikit-learn/pull/28422#issuecomment-1951377557, I proposed this API:

```python
# Single string for a single mapping:
MethodMapping().add_one_to_one("score")

# Add a second mapping by using a list:
MethodMapping().add_one_to_one(["score", "predict"])
```

I'm mostly considering third party meta-estimator developers and how to make it easier for them to adopt the metadata routing API and define these mappings. If `add_one_to_one` handles a majority of the use cases, I think it's worth introducing even if it a second way to specify the mappings.

COMMENT:
With the original design, I was hoping to reduce the number of required imports in cases where it's not needed. But if we don't like that, I'm okay with the proposal here.

Labels: API, Needs Decision, Needs Decision - Close, Metadata Routing
RFC Revisiting meta-routing developer API for defining method mappings

For metadata routing, meta-estimators define method mappings through this API:

```python
router = MetadataRouter(...).add(
	 method_mapping=MethodMapping()
     .add(callee="fit", caller="fit")
     .add(callee="transform", caller="fit")
     .add(callee="transform", caller="predict"),
)
```

Currently, we have a shortcut to map every available method dynamically:

```python
MetadataRouter(...).add(method_mapping="one-to-one")
```

And a shortcut to do a single "one-to-one" mapping:

```python
MetadataRouter(...).add(method_mapping="score")
```

https://github.com/scikit-learn/scikit-learn/pull/28422 proposes to remove both theses shortcuts. The proposal makes sense as it forces everything to be explicit and there is only one way to define the method mappings.

On the other hand, I think a majority of the time a meta-estimator does "one-to-one" method mappings. In https://github.com/scikit-learn/scikit-learn/pull/28422#issuecomment-1951377557, I proposed this API:

```python
# Single string for a single mapping:
MethodMapping().add_one_to_one("score")

# Add a second mapping by using a list:
MethodMapping().add_one_to_one(["score", "predict"])
```

I'm mostly considering third party meta-estimator developers and how to make it easier for them to adopt the metadata routing API and define these mappings. If `add_one_to_one` handles a majority of the use cases, I think it's worth introducing even if it a second way to specify the mappings.

COMMENT:
I am also ok with @thomasjpfan proposal to special case the one to one mapping with a dedicated API such as `MethodMapping().add_one_to_one(["score", "predict"])`.

Labels: API, Needs Decision, Needs Decision - Close, Metadata Routing
RFC Revisiting meta-routing developer API for defining method mappings

For metadata routing, meta-estimators define method mappings through this API:

```python
router = MetadataRouter(...).add(
	 method_mapping=MethodMapping()
     .add(callee="fit", caller="fit")
     .add(callee="transform", caller="fit")
     .add(callee="transform", caller="predict"),
)
```

Currently, we have a shortcut to map every available method dynamically:

```python
MetadataRouter(...).add(method_mapping="one-to-one")
```

And a shortcut to do a single "one-to-one" mapping:

```python
MetadataRouter(...).add(method_mapping="score")
```

https://github.com/scikit-learn/scikit-learn/pull/28422 proposes to remove both theses shortcuts. The proposal makes sense as it forces everything to be explicit and there is only one way to define the method mappings.

On the other hand, I think a majority of the time a meta-estimator does "one-to-one" method mappings. In https://github.com/scikit-learn/scikit-learn/pull/28422#issuecomment-1951377557, I proposed this API:

```python
# Single string for a single mapping:
MethodMapping().add_one_to_one("score")

# Add a second mapping by using a list:
MethodMapping().add_one_to_one(["score", "predict"])
```

I'm mostly considering third party meta-estimator developers and how to make it easier for them to adopt the metadata routing API and define these mappings. If `add_one_to_one` handles a majority of the use cases, I think it's worth introducing even if it a second way to specify the mappings.

COMMENT:
I think @StefanieSenger removed the `add(method_mapping: str, ...)` a while ago, and we haven't felt the need to have the alternatives. I propose we close this one.

Labels: API, Needs Decision, Needs Decision - Close, Metadata Routing
RFC Revisiting meta-routing developer API for defining method mappings

For metadata routing, meta-estimators define method mappings through this API:

```python
router = MetadataRouter(...).add(
	 method_mapping=MethodMapping()
     .add(callee="fit", caller="fit")
     .add(callee="transform", caller="fit")
     .add(callee="transform", caller="predict"),
)
```

Currently, we have a shortcut to map every available method dynamically:

```python
MetadataRouter(...).add(method_mapping="one-to-one")
```

And a shortcut to do a single "one-to-one" mapping:

```python
MetadataRouter(...).add(method_mapping="score")
```

https://github.com/scikit-learn/scikit-learn/pull/28422 proposes to remove both theses shortcuts. The proposal makes sense as it forces everything to be explicit and there is only one way to define the method mappings.

On the other hand, I think a majority of the time a meta-estimator does "one-to-one" method mappings. In https://github.com/scikit-learn/scikit-learn/pull/28422#issuecomment-1951377557, I proposed this API:

```python
# Single string for a single mapping:
MethodMapping().add_one_to_one("score")

# Add a second mapping by using a list:
MethodMapping().add_one_to_one(["score", "predict"])
```

I'm mostly considering third party meta-estimator developers and how to make it easier for them to adopt the metadata routing API and define these mappings. If `add_one_to_one` handles a majority of the use cases, I think it's worth introducing even if it a second way to specify the mappings.

COMMENT:
> I think @StefanieSenger removed the add(method_mapping: str, ...) a while ago, and we haven't felt the need to have the alternatives.

Yes, I was thinking it simplifies to not offer several similar ways to do the very same thing and the `caller` `callee` syntax can do more than the `str` variation. It was this PR: #28422

Labels: API, Needs Decision, Needs Decision - Close, Metadata Routing
OrdinalEncoder doesn't recognize np.nan in np.array with multiple entries

### Describe the bug

Hello friends, first time opening a bug report here. Don't hesitate to let me know if I should be doing this differently. 

When a multi-element array is passed in to transform() method, np.nan are treated as `unknown_value` instead of `encoded_missing_value`. Single-element arrays and pandas dataframes with multiple rows seem to work fine. 

### Steps/Code to Reproduce

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder, PowerTransformer

encoder = OrdinalEncoder(
    handle_unknown="use_encoded_value",
    unknown_value=-1,
    encoded_missing_value=-2,
    dtype=np.int32,
)
        
Xcat = pd.DataFrame(
    {"c1": [np.nan, "b", "b", "c", "c", "c", "d"]}
)        
        
encoder.fit(Xcat)
```
### Expected Results

```
# When X is an array with single entry, np.nan are -2 as expected
encoder.transform(np.asarray([[np.nan]]).astype("O"))
>> array([[-2]], dtype=int32)

# When X is a pandas df with several rows, np.nan are also -2 as expected
df = pd.DataFrame([{"c1": np.nan}, {"c1": "b"}])
encoder.transform(df)
>> array([[-2],
       [ 0]], dtype=int32)

```

### Actual Results

```
# However, when X is an array with multiple entries, transform() method treats np.nan as unknown_value 
>> encoder.transform(np.asarray([[np.nan], ['b']]).astype("O"))
array([[-1],
       [ 0]], dtype=int32)
```

### Versions

```shell
This is happening on both versions 1.2.2 and 1.3.0.
```

COMMENT:
I cannot reproduce in `main`:

```python
In [2]: import numpy as np
   ...: import pandas as pd
   ...: from sklearn.preprocessing import OrdinalEncoder, PowerTransformer
   ...: 
   ...: encoder = OrdinalEncoder(
   ...:             handle_unknown="use_encoded_value",
   ...:             unknown_value=-1,
   ...:             encoded_missing_value=-2,
   ...:             dtype=np.int32,
   ...:         )
   ...: 
   ...: Xcat = pd.DataFrame(
   ...:             {"c1": [np.nan, "b", "b", "c", "c", "c", "d"]}
   ...:         )
   ...: 
   ...: encoder.fit(Xcat)
Out[2]: 
OrdinalEncoder(dtype=<class 'numpy.int32'>, encoded_missing_value=-2,
               handle_unknown='use_encoded_value', unknown_value=-1)

In [6]: df = pd.DataFrame([{"c1": np.nan}, {"c1": "b"}])

In [7]: df
Out[7]: 
    c1
0  NaN
1    b

In [8]: encoder.transform(df)
Out[8]: 
array([[-2],
       [ 0]], dtype=int32)
```

Labels: Bug, Needs Triage
OrdinalEncoder doesn't recognize np.nan in np.array with multiple entries

### Describe the bug

Hello friends, first time opening a bug report here. Don't hesitate to let me know if I should be doing this differently. 

When a multi-element array is passed in to transform() method, np.nan are treated as `unknown_value` instead of `encoded_missing_value`. Single-element arrays and pandas dataframes with multiple rows seem to work fine. 

### Steps/Code to Reproduce

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder, PowerTransformer

encoder = OrdinalEncoder(
    handle_unknown="use_encoded_value",
    unknown_value=-1,
    encoded_missing_value=-2,
    dtype=np.int32,
)
        
Xcat = pd.DataFrame(
    {"c1": [np.nan, "b", "b", "c", "c", "c", "d"]}
)        
        
encoder.fit(Xcat)
```
### Expected Results

```
# When X is an array with single entry, np.nan are -2 as expected
encoder.transform(np.asarray([[np.nan]]).astype("O"))
>> array([[-2]], dtype=int32)

# When X is a pandas df with several rows, np.nan are also -2 as expected
df = pd.DataFrame([{"c1": np.nan}, {"c1": "b"}])
encoder.transform(df)
>> array([[-2],
       [ 0]], dtype=int32)

```

### Actual Results

```
# However, when X is an array with multiple entries, transform() method treats np.nan as unknown_value 
>> encoder.transform(np.asarray([[np.nan], ['b']]).astype("O"))
array([[-1],
       [ 0]], dtype=int32)
```

### Versions

```shell
This is happening on both versions 1.2.2 and 1.3.0.
```

COMMENT:
Not that I get the same results when providing a numpy array (i.e. calling `Xcat.values` and `df.values`).

Labels: Bug, Needs Triage
OrdinalEncoder doesn't recognize np.nan in np.array with multiple entries

### Describe the bug

Hello friends, first time opening a bug report here. Don't hesitate to let me know if I should be doing this differently. 

When a multi-element array is passed in to transform() method, np.nan are treated as `unknown_value` instead of `encoded_missing_value`. Single-element arrays and pandas dataframes with multiple rows seem to work fine. 

### Steps/Code to Reproduce

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder, PowerTransformer

encoder = OrdinalEncoder(
    handle_unknown="use_encoded_value",
    unknown_value=-1,
    encoded_missing_value=-2,
    dtype=np.int32,
)
        
Xcat = pd.DataFrame(
    {"c1": [np.nan, "b", "b", "c", "c", "c", "d"]}
)        
        
encoder.fit(Xcat)
```
### Expected Results

```
# When X is an array with single entry, np.nan are -2 as expected
encoder.transform(np.asarray([[np.nan]]).astype("O"))
>> array([[-2]], dtype=int32)

# When X is a pandas df with several rows, np.nan are also -2 as expected
df = pd.DataFrame([{"c1": np.nan}, {"c1": "b"}])
encoder.transform(df)
>> array([[-2],
       [ 0]], dtype=int32)

```

### Actual Results

```
# However, when X is an array with multiple entries, transform() method treats np.nan as unknown_value 
>> encoder.transform(np.asarray([[np.nan], ['b']]).astype("O"))
array([[-1],
       [ 0]], dtype=int32)
```

### Versions

```shell
This is happening on both versions 1.2.2 and 1.3.0.
```

COMMENT:
Oh I see, transform() takes as input:

```
array([[nan],
       ['b']], dtype=object)
```
       
But not:

```
array([['nan'],
       ['b']], dtype='<U32')
```
       
Thanks!

Labels: Bug, Needs Triage
OrdinalEncoder doesn't recognize np.nan in np.array with multiple entries

### Describe the bug

Hello friends, first time opening a bug report here. Don't hesitate to let me know if I should be doing this differently. 

When a multi-element array is passed in to transform() method, np.nan are treated as `unknown_value` instead of `encoded_missing_value`. Single-element arrays and pandas dataframes with multiple rows seem to work fine. 

### Steps/Code to Reproduce

```python
import numpy as np
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder, PowerTransformer

encoder = OrdinalEncoder(
    handle_unknown="use_encoded_value",
    unknown_value=-1,
    encoded_missing_value=-2,
    dtype=np.int32,
)
        
Xcat = pd.DataFrame(
    {"c1": [np.nan, "b", "b", "c", "c", "c", "d"]}
)        
        
encoder.fit(Xcat)
```
### Expected Results

```
# When X is an array with single entry, np.nan are -2 as expected
encoder.transform(np.asarray([[np.nan]]).astype("O"))
>> array([[-2]], dtype=int32)

# When X is a pandas df with several rows, np.nan are also -2 as expected
df = pd.DataFrame([{"c1": np.nan}, {"c1": "b"}])
encoder.transform(df)
>> array([[-2],
       [ 0]], dtype=int32)

```

### Actual Results

```
# However, when X is an array with multiple entries, transform() method treats np.nan as unknown_value 
>> encoder.transform(np.asarray([[np.nan], ['b']]).astype("O"))
array([[-1],
       [ 0]], dtype=int32)
```

### Versions

```shell
This is happening on both versions 1.2.2 and 1.3.0.
```

COMMENT:
In the second case, `'nan'` is a string and is therefore categories never seen at `fit`. So it is indeed making sense.

Labels: Bug, Needs Triage
Very old notes in docstrings

### Describe the issue linked to the documentation

In `sklearn/feature_extraction/image.py` very old notes are contained in the docstrings of two functions:

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L178-L185

and

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L232-L239

These notes refer to scikit-learn 0.14.1 which is approx. 10 years old:

```python
"""
    .
    .
    .
    Notes
    -----
    For scikit-learn versions 0.14.1 and prior, return_as=np.ndarray was
    handled by returning a dense np.matrix instance.  Going forward, np.ndarray
    returns an np.ndarray, as expected.
    .
    .
    .
"""
```

Maybe these notes are obsolet and can be removed?
What is the employed strategy in scikit-learn regarding such old notes?

### Suggest a potential alternative/fix

_No response_

COMMENT:
I don't think there is a policy? I also think that we could do some clean up removing comments from more than two released versions ago? Or maybe three?

Labels: Documentation
Very old notes in docstrings

### Describe the issue linked to the documentation

In `sklearn/feature_extraction/image.py` very old notes are contained in the docstrings of two functions:

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L178-L185

and

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L232-L239

These notes refer to scikit-learn 0.14.1 which is approx. 10 years old:

```python
"""
    .
    .
    .
    Notes
    -----
    For scikit-learn versions 0.14.1 and prior, return_as=np.ndarray was
    handled by returning a dense np.matrix instance.  Going forward, np.ndarray
    returns an np.ndarray, as expected.
    .
    .
    .
"""
```

Maybe these notes are obsolet and can be removed?
What is the employed strategy in scikit-learn regarding such old notes?

### Suggest a potential alternative/fix

_No response_

COMMENT:
Whatever the policy, those are REALLY old, and can be removed/updated.

Labels: Documentation
Very old notes in docstrings

### Describe the issue linked to the documentation

In `sklearn/feature_extraction/image.py` very old notes are contained in the docstrings of two functions:

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L178-L185

and

https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/image.py#L232-L239

These notes refer to scikit-learn 0.14.1 which is approx. 10 years old:

```python
"""
    .
    .
    .
    Notes
    -----
    For scikit-learn versions 0.14.1 and prior, return_as=np.ndarray was
    handled by returning a dense np.matrix instance.  Going forward, np.ndarray
    returns an np.ndarray, as expected.
    .
    .
    .
"""
```

Maybe these notes are obsolet and can be removed?
What is the employed strategy in scikit-learn regarding such old notes?

### Suggest a potential alternative/fix

_No response_

COMMENT:
Okay, I created a little PR for this...

Labels: Documentation