Talip7/scikit-learn-issues-multilabel huggingface dataset:
joblib development version breaks `sklearn.show_versions()`

When we release joblib (soonish let's say a matter of weeks) we will break `sklearn.show_versions()`. We may need to do a bug-fix release of scikit-learn.

To reproduce:
```bash
mamba create -n test-env scikit-learn -y
conda activate test-env
pip install git+https://github.com/joblib/joblib
python -c 'import sklearn; sklearn.show_versions()'
```

This is a mixture of different things:
1. `python -c 'import pip; import setuptools'` breaks
```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/setuptools/__init__.py", line 8, in <module>
    import _distutils_hack.override  # noqa: F401
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/override.py", line 1, in <module>
    __import__('_distutils_hack').do_override()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 72, in do_override
    ensure_local_distutils()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 59, in ensure_local_distutils
    assert '_distutils' in core.__file__, core.__file__
AssertionError: /home/lesteve/miniconda3/envs/test/lib/python3.10/distutils/core.py
```
3.  `python -c 'import setuptools; import pip'` gives you only a warning about setuptools replacing distutils 
4. importing `pip` before `setuptools` breaks and it is considered as a won't fix: https://github.com/pypa/setuptools/issues/3044. The reason is that you are not supposed to `import pip` see e.g. https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program or https://github.com/pypa/pip/issues/5081#issuecomment-374251881
5. joblib removed some `distutils` version classes usage in https://github.com/joblib/joblib/pull/1272. As a side-effect `distutils` is not imported by `joblib` and so when importing `sklearn` you are anymore importing `distutils` (hence `setuptools`) before `pipand you end up in case 1 with an error

COMMENT:
After chatting a bit with @ogrisel, it may be that the most pragmatic way of tackling this issue would be to reintroduce an unused `import distutils` in `joblib`.
Pros:
- avoid unnecessary disruption (people with weird errors when using `sklearn.show_versions()`, telling them to update scikit-learn or downgrade joblib, or giving them manual instructions to get the info we need)
- avoid the work of doing a scikit-learn bug-fix release

Cons:
- not super satisfactory but oh well :shrug:

Labels: Bug, Build / CI, Blocker
joblib development version breaks `sklearn.show_versions()`

When we release joblib (soonish let's say a matter of weeks) we will break `sklearn.show_versions()`. We may need to do a bug-fix release of scikit-learn.

To reproduce:
```bash
mamba create -n test-env scikit-learn -y
conda activate test-env
pip install git+https://github.com/joblib/joblib
python -c 'import sklearn; sklearn.show_versions()'
```

This is a mixture of different things:
1. `python -c 'import pip; import setuptools'` breaks
```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/setuptools/__init__.py", line 8, in <module>
    import _distutils_hack.override  # noqa: F401
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/override.py", line 1, in <module>
    __import__('_distutils_hack').do_override()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 72, in do_override
    ensure_local_distutils()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 59, in ensure_local_distutils
    assert '_distutils' in core.__file__, core.__file__
AssertionError: /home/lesteve/miniconda3/envs/test/lib/python3.10/distutils/core.py
```
3.  `python -c 'import setuptools; import pip'` gives you only a warning about setuptools replacing distutils 
4. importing `pip` before `setuptools` breaks and it is considered as a won't fix: https://github.com/pypa/setuptools/issues/3044. The reason is that you are not supposed to `import pip` see e.g. https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program or https://github.com/pypa/pip/issues/5081#issuecomment-374251881
5. joblib removed some `distutils` version classes usage in https://github.com/joblib/joblib/pull/1272. As a side-effect `distutils` is not imported by `joblib` and so when importing `sklearn` you are anymore importing `distutils` (hence `setuptools`) before `pipand you end up in case 1 with an error

COMMENT:
> most pragmatic way of tackling this issue would be to reintroduce an unused import distutils in joblib

If joblib devs are okay with this, then I think this is the best path forward.

If `joblib`  does not want to import distuils all the time, joblib can check the version of scikit-learn and then import `disutils` only if `scikit-learn < 1.1`.

Labels: Bug, Build / CI, Blocker
joblib development version breaks `sklearn.show_versions()`

When we release joblib (soonish let's say a matter of weeks) we will break `sklearn.show_versions()`. We may need to do a bug-fix release of scikit-learn.

To reproduce:
```bash
mamba create -n test-env scikit-learn -y
conda activate test-env
pip install git+https://github.com/joblib/joblib
python -c 'import sklearn; sklearn.show_versions()'
```

This is a mixture of different things:
1. `python -c 'import pip; import setuptools'` breaks
```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/setuptools/__init__.py", line 8, in <module>
    import _distutils_hack.override  # noqa: F401
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/override.py", line 1, in <module>
    __import__('_distutils_hack').do_override()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 72, in do_override
    ensure_local_distutils()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 59, in ensure_local_distutils
    assert '_distutils' in core.__file__, core.__file__
AssertionError: /home/lesteve/miniconda3/envs/test/lib/python3.10/distutils/core.py
```
3.  `python -c 'import setuptools; import pip'` gives you only a warning about setuptools replacing distutils 
4. importing `pip` before `setuptools` breaks and it is considered as a won't fix: https://github.com/pypa/setuptools/issues/3044. The reason is that you are not supposed to `import pip` see e.g. https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program or https://github.com/pypa/pip/issues/5081#issuecomment-374251881
5. joblib removed some `distutils` version classes usage in https://github.com/joblib/joblib/pull/1272. As a side-effect `distutils` is not imported by `joblib` and so when importing `sklearn` you are anymore importing `distutils` (hence `setuptools`) before `pipand you end up in case 1 with an error

COMMENT:
I think we can just keep on importing distutils for nothing in joblib for one year to ensure a safe overlap.

But we need to switch to `importlib.metadata.version`-based version introspection in scikit-learn's `show_versions()` before releasing 1.1.

Labels: Bug, Build / CI, Blocker
joblib development version breaks `sklearn.show_versions()`

When we release joblib (soonish let's say a matter of weeks) we will break `sklearn.show_versions()`. We may need to do a bug-fix release of scikit-learn.

To reproduce:
```bash
mamba create -n test-env scikit-learn -y
conda activate test-env
pip install git+https://github.com/joblib/joblib
python -c 'import sklearn; sklearn.show_versions()'
```

This is a mixture of different things:
1. `python -c 'import pip; import setuptools'` breaks
```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/setuptools/__init__.py", line 8, in <module>
    import _distutils_hack.override  # noqa: F401
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/override.py", line 1, in <module>
    __import__('_distutils_hack').do_override()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 72, in do_override
    ensure_local_distutils()
  File "/home/lesteve/miniconda3/envs/test/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 59, in ensure_local_distutils
    assert '_distutils' in core.__file__, core.__file__
AssertionError: /home/lesteve/miniconda3/envs/test/lib/python3.10/distutils/core.py
```
3.  `python -c 'import setuptools; import pip'` gives you only a warning about setuptools replacing distutils 
4. importing `pip` before `setuptools` breaks and it is considered as a won't fix: https://github.com/pypa/setuptools/issues/3044. The reason is that you are not supposed to `import pip` see e.g. https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program or https://github.com/pypa/pip/issues/5081#issuecomment-374251881
5. joblib removed some `distutils` version classes usage in https://github.com/joblib/joblib/pull/1272. As a side-effect `distutils` is not imported by `joblib` and so when importing `sklearn` you are anymore importing `distutils` (hence `setuptools`) before `pipand you end up in case 1 with an error

COMMENT:
All the work mentioned above has been done in  joblib/joblib#1277 and #22621, the latter requires #22617 to be merged first.

Labels: Bug, Build / CI, Blocker
SVC parameter decision_function_shape states "However, one-vs-one (‘ovo’) is always used as multi-class strategy."

### Describe the issue linked to the documentation

Documentation should be changed to reflect that one-vs-rest is possible. 

```
x = np.array([0,1,2,3,4,5,3,3,5,5,5,7,7,2])
x = x.reshape(-1,1)#this has 1 feature, therefore reshaping properly

y = [0,0,0,1,0,2,1,1,2,2,2,3,3,0] #note: y has multiple classes.


model = SVC(gamma = "auto", decision_function_shape="ovr")
model.fit(x,y)
print("ovr's shape")
print(model.decision_function(x).shape)
'''
>>>ovr's shape
>>>(14, 4)
'''

model = SVC(gamma = "auto", decision_function_shape="ovo")
model.fit(x,y)
print("ovo's shape:")
print(model.decision_function(x).shape)
'''
>>>ovo's shape:
>>>(14, 6)
'''

```
ovr's shape is indeed (n_samples, n_classes)
and ovo's shape is (n_samples, n_classes * (n_classes - 1) / 2)
looking at the documentation for SVC, 
"**decision_function_shape{‘ovo’, ‘ovr’}**, default=’ovr’
Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). **However, one-vs-one (‘ovo’) is always used as multi-class strategy.** The parameter is ignored for binary classification."
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC
does not appear to be true. 

Edit:
Appears the change was originally from here:
https://github.com/scikit-learn/scikit-learn/commit/593bf65bd42db8dcc0ae414f27083b5675310d71

### Suggest a potential alternative/fix

change 
"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). However, one-vs-one (‘ovo’) is always used as multi-class strategy. The parameter is ignored for binary classification."

to

"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). The parameter is ignored for binary classification."

COMMENT:
So internally the SVC always does `ovo`, but if the user sets `decision_function_shape="ovr"`, an `ovr` shape decision function is created from the underlying `ovo` matrix.

So I'd say we should change that statement to be more clear, to something like:

"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). However, note that internally, one-vs-one (‘ovo’) is always used as multi-class strategy to train models and an `ovr` matrix is only constructed from the `ovo` matrix.. The parameter is ignored for binary classification."

Labels: Documentation, good first issue, help wanted, module:svm
SVC parameter decision_function_shape states "However, one-vs-one (‘ovo’) is always used as multi-class strategy."

### Describe the issue linked to the documentation

Documentation should be changed to reflect that one-vs-rest is possible. 

```
x = np.array([0,1,2,3,4,5,3,3,5,5,5,7,7,2])
x = x.reshape(-1,1)#this has 1 feature, therefore reshaping properly

y = [0,0,0,1,0,2,1,1,2,2,2,3,3,0] #note: y has multiple classes.


model = SVC(gamma = "auto", decision_function_shape="ovr")
model.fit(x,y)
print("ovr's shape")
print(model.decision_function(x).shape)
'''
>>>ovr's shape
>>>(14, 4)
'''

model = SVC(gamma = "auto", decision_function_shape="ovo")
model.fit(x,y)
print("ovo's shape:")
print(model.decision_function(x).shape)
'''
>>>ovo's shape:
>>>(14, 6)
'''

```
ovr's shape is indeed (n_samples, n_classes)
and ovo's shape is (n_samples, n_classes * (n_classes - 1) / 2)
looking at the documentation for SVC, 
"**decision_function_shape{‘ovo’, ‘ovr’}**, default=’ovr’
Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). **However, one-vs-one (‘ovo’) is always used as multi-class strategy.** The parameter is ignored for binary classification."
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC
does not appear to be true. 

Edit:
Appears the change was originally from here:
https://github.com/scikit-learn/scikit-learn/commit/593bf65bd42db8dcc0ae414f27083b5675310d71

### Suggest a potential alternative/fix

change 
"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). However, one-vs-one (‘ovo’) is always used as multi-class strategy. The parameter is ignored for binary classification."

to

"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). The parameter is ignored for binary classification."

COMMENT:
Can I work on this issue?

Labels: Documentation, good first issue, help wanted, module:svm
SVC parameter decision_function_shape states "However, one-vs-one (‘ovo’) is always used as multi-class strategy."

### Describe the issue linked to the documentation

Documentation should be changed to reflect that one-vs-rest is possible. 

```
x = np.array([0,1,2,3,4,5,3,3,5,5,5,7,7,2])
x = x.reshape(-1,1)#this has 1 feature, therefore reshaping properly

y = [0,0,0,1,0,2,1,1,2,2,2,3,3,0] #note: y has multiple classes.


model = SVC(gamma = "auto", decision_function_shape="ovr")
model.fit(x,y)
print("ovr's shape")
print(model.decision_function(x).shape)
'''
>>>ovr's shape
>>>(14, 4)
'''

model = SVC(gamma = "auto", decision_function_shape="ovo")
model.fit(x,y)
print("ovo's shape:")
print(model.decision_function(x).shape)
'''
>>>ovo's shape:
>>>(14, 6)
'''

```
ovr's shape is indeed (n_samples, n_classes)
and ovo's shape is (n_samples, n_classes * (n_classes - 1) / 2)
looking at the documentation for SVC, 
"**decision_function_shape{‘ovo’, ‘ovr’}**, default=’ovr’
Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). **However, one-vs-one (‘ovo’) is always used as multi-class strategy.** The parameter is ignored for binary classification."
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC
does not appear to be true. 

Edit:
Appears the change was originally from here:
https://github.com/scikit-learn/scikit-learn/commit/593bf65bd42db8dcc0ae414f27083b5675310d71

### Suggest a potential alternative/fix

change 
"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). However, one-vs-one (‘ovo’) is always used as multi-class strategy. The parameter is ignored for binary classification."

to

"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). The parameter is ignored for binary classification."

COMMENT:
Of course.

Labels: Documentation, good first issue, help wanted, module:svm
SVC parameter decision_function_shape states "However, one-vs-one (‘ovo’) is always used as multi-class strategy."

### Describe the issue linked to the documentation

Documentation should be changed to reflect that one-vs-rest is possible. 

```
x = np.array([0,1,2,3,4,5,3,3,5,5,5,7,7,2])
x = x.reshape(-1,1)#this has 1 feature, therefore reshaping properly

y = [0,0,0,1,0,2,1,1,2,2,2,3,3,0] #note: y has multiple classes.


model = SVC(gamma = "auto", decision_function_shape="ovr")
model.fit(x,y)
print("ovr's shape")
print(model.decision_function(x).shape)
'''
>>>ovr's shape
>>>(14, 4)
'''

model = SVC(gamma = "auto", decision_function_shape="ovo")
model.fit(x,y)
print("ovo's shape:")
print(model.decision_function(x).shape)
'''
>>>ovo's shape:
>>>(14, 6)
'''

```
ovr's shape is indeed (n_samples, n_classes)
and ovo's shape is (n_samples, n_classes * (n_classes - 1) / 2)
looking at the documentation for SVC, 
"**decision_function_shape{‘ovo’, ‘ovr’}**, default=’ovr’
Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). **However, one-vs-one (‘ovo’) is always used as multi-class strategy.** The parameter is ignored for binary classification."
https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC
does not appear to be true. 

Edit:
Appears the change was originally from here:
https://github.com/scikit-learn/scikit-learn/commit/593bf65bd42db8dcc0ae414f27083b5675310d71

### Suggest a potential alternative/fix

change 
"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). However, one-vs-one (‘ovo’) is always used as multi-class strategy. The parameter is ignored for binary classification."

to

"Whether to return a one-vs-rest (‘ovr’) decision function of shape (n_samples, n_classes) as all other classifiers, or the original one-vs-one (‘ovo’) decision function of libsvm which has shape (n_samples, n_classes * (n_classes - 1) / 2). The parameter is ignored for binary classification."

COMMENT:
I think just need to remove "However, one-vs-one (‘ovo’) is always used as multi-class strategy." from the documentation. @adrinjalali I believe explaining what the internal does is not useful for the user to know, it just causes more confusion. 
Please let me know if I am not making mistake.

Labels: Documentation, good first issue, help wanted, module:svm
If “auto”, then max_features=sqrt(n_features). in https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

Hi Scikit-learn community,

in the Documentation, https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

it is given that If **“auto”, then max_features=sqrt(n_features).** 

as per the decision tree it shold be If “auto”, then max_features = (n_features). 

Correct me if iam wrong. Or help in adding the change the documentation

![image](https://user-images.githubusercontent.com/76277751/155496904-c6e07211-696d-4896-ae29-75afd24939d3.png)

COMMENT:
Hi @SaiArja , if `max_features` is set to `"auto"`, then it will be set to `sqrt(n_features)` for classification trees and `n_features` for regression trees.

Labels: Documentation, module:tree
If “auto”, then max_features=sqrt(n_features). in https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

Hi Scikit-learn community,

in the Documentation, https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

it is given that If **“auto”, then max_features=sqrt(n_features).** 

as per the decision tree it shold be If “auto”, then max_features = (n_features). 

Correct me if iam wrong. Or help in adding the change the documentation

![image](https://user-images.githubusercontent.com/76277751/155496904-c6e07211-696d-4896-ae29-75afd24939d3.png)

COMMENT:
As noted in https://github.com/scikit-learn/scikit-learn/issues/22601#issuecomment-1049765295, the documentation is correct for `DecisionTreeClassifier`.

Labels: Documentation, module:tree
PERF `PairwiseDistancesReductions` initial work

`PairwiseDistancesReductions` have been introduced as a hierarchy of Cython classes to implement back-ends of some scikit-learn algorithms.

Pieces of work include:

 - https://github.com/scikit-learn/scikit-learn/pull/22134
 - https://github.com/scikit-learn/scikit-learn/pull/22320
 - https://github.com/scikit-learn/scikit-learn/pull/23865
 - Support sparse-dense data-sets pairs:
   - https://github.com/scikit-learn/scikit-learn/pull/23604
   - https://github.com/scikit-learn/scikit-learn/pull/23585
   - https://github.com/scikit-learn/scikit-learn/pull/24807 by @Vincent-Maladiere
   - https://github.com/scikit-learn/scikit-learn/pull/24556 by @Vincent-Maladiere
   - https://github.com/scikit-learn/scikit-learn/pull/25044
 - https://github.com/scikit-learn/scikit-learn/pull/22829
 - https://github.com/scikit-learn/scikit-learn/pull/23978
 - #24043
 - Document and communicate about the changes of behaviour regarding `n_jobs`:
   - #24997
   - Add a comment in impacted user-facing `PairwiseDistancesReductions`-backed API's doc-strings regarding the non-use of `n_jobs`
 - Dedicated ASV benchmark suite: [`scikit-learn/pairwise-distances-reductions-asv-suite`](https://github.com/scikit-learn/pairwise-distances-reductions-asv-suite)


Note that this needs not be personal work, I would be really glad having others help on this subject, proposing changes and implementations! :slightly_smiling_face:

COMMENT:
@Vincent-Maladiere and I are wondering about people's thoughts and opinions regarding prioritisation of the work proposed here.

For me, it is rather hard to assess what is of value. I think educating users about internals probably is more valuable than completing some of the items which are listed here.

What do people think of this? Are there any work that is not of value?

I am looking for discussions and critics. 🙂

Labels: Performance, cython, Meta-issue