Talip7/scikit-learn-issues-multilabel huggingface dataset:
Mention setting env variable SCIPY_ARRAY_API=1 in Array API support doc

### Describe the issue linked to the documentation

https://scikit-learn.org/dev/modules/array_api.html#array-api-support-experimental does not mention `SCIPY_ARRAY_API=1`


### Suggest a potential alternative/fix

Maybe it should mention setting `SCIPY_ARRAY_API=1`.

I guess you get an error message about it but mentioning it in the doc similarly to installing array-api-compat would make sense.

COMMENT:
I’d like to take on this issue if it’s available.

Would you also like me to add a similar note to the [Parallelism, resource management, and configuration section](https://scikit-learn.org/stable/computing/parallelism.html) of the User Guide? Based on my experience, I need to set the environment variables `SKLEARN_WARNINGS_AS_ERRORS=1` and `SCIPY_ARRAY_API=1` together whenever I’m working on the Array API Project.

Labels: Documentation
Mention setting env variable SCIPY_ARRAY_API=1 in Array API support doc

### Describe the issue linked to the documentation

https://scikit-learn.org/dev/modules/array_api.html#array-api-support-experimental does not mention `SCIPY_ARRAY_API=1`


### Suggest a potential alternative/fix

Maybe it should mention setting `SCIPY_ARRAY_API=1`.

I guess you get an error message about it but mentioning it in the doc similarly to installing array-api-compat would make sense.

COMMENT:
Sure go for it!

For now I would only add it to the https://scikit-learn.org/dev/modules/array_api.html#array-api-support-experimental. My main focus is end-users.

People that work on Array API support get the error message about the env variable if they don't set it and kind of know what to do I would say. It would also feel a bit weird to add it to the list of the `SKLEARN_` environment variable since after all this is not a `SKLEARN_` environment variable but a `SCIPY_` one ...

Labels: Documentation
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
Looks like a regression in 1.5 (i.e. not a regression in the latest release 1.6), there was a passthrough block in 1.4 but it disappeared in 1.5:
[1.4 doc example](https://scikit-learn.org/1.4/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#processing-the-dataset)
![image](https://github.com/user-attachments/assets/88d0777e-d795-4668-8e32-3630e482bc63)

[1.5 doc example](https://scikit-learn.org/1.5/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#processing-the-dataset)

![image](https://github.com/user-attachments/assets/84afccfa-9aa1-4813-a364-56b59d7566ec)

Labels: Bug
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
Semi-random thought: it could also be a pydata-sphinx-theme side-effect somehow since IIRC 1.5 is when we started to use pydata-sphinx-theme

Labels: Bug
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
But it seems inconsistent depending on what is inside the column transformer :). A pydata-sphinx-theme should influence the same whether or not there is the passthrough in it.

Labels: Bug
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
That's weird, when I build the doc locally, I get the expected output
![ct_html_repr](https://github.com/user-attachments/assets/fbfa6600-c405-4179-b660-496b22293409)

Labels: Bug
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
I have the same pydata sphinx theme version as the `doc` lock file but the versions of sphinx and some sphinx extensions differ.

EDIT: I have the correct behavior locally when I build the doc in an env created from the doc lock-file.

Labels: Bug
`remainder='passthrough'` block is missing from `ColumnTransformer` HTML repr since 1.5

In the following example, the `repr` of `ColumnTransformer` does not seem to work as I expect it:

https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#sphx-glr-auto-examples-inspection-plot-linear-model-coefficient-interpretation-py

<img width="809" alt="image" src="https://github.com/user-attachments/assets/f3f258e6-11f6-49ee-a9df-8c6a464fe792" />

Instead I would expect a `passthrough` block and a `OneHotEncoder` block in the `ColumnTransformer`.
I think that we should check the reason and see if we can improve the rendering.

COMMENT:
This seems fine in the [1.7 doc](https://scikit-learn.org/1.7/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#processing-the-dataset) and [dev doc](https://scikit-learn.org/dev/auto_examples/inspection/plot_linear_model_coefficient_interpretation.html#processing-the-dataset) so only a problem in the 1.5 and 1.6 doc for some reason 🤷, closing.

Labels: Bug
Version 1.6 docs inconsistency related to isolation forest.

### Describe the issue linked to the documentation

The current [isolation forest docs](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest) say this:

![image](https://github.com/user-attachments/assets/151df906-a56b-45d9-a704-41bd5606d8b4)

And this: 

![image](https://github.com/user-attachments/assets/6dac62f3-0f9d-4a32-8fe2-9fea9c380dae)

After trying myself locally I can also confirm that you need to context manager for the actual speedup. 

### Suggest a potential alternative/fix

The `n_jobs` did not cause a speedup locally but the context manager did so there is probably a situation with a docstring that needs updating. We should probably just change the docstring for the input of the estimator? But it could also make sense to mention the context manager more boldly.

@glemaitre had some ideas on this and knows more about the internals here.

COMMENT:
Which `n_jobs` did you use for `IsolationForest`, for the `parallel_backend` around `predict` and what do you get with the following snippet:
```py
import joblib
joblib.cpu_count()
```

I know it's probably a bit of work, but sharing some snippet would be very useful to be able to reproduce and debug.

What that probably means is that the default `n_jobs` is not optimal in some cases?

Labels: Documentation
Version 1.6 docs inconsistency related to isolation forest.

### Describe the issue linked to the documentation

The current [isolation forest docs](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest) say this:

![image](https://github.com/user-attachments/assets/151df906-a56b-45d9-a704-41bd5606d8b4)

And this: 

![image](https://github.com/user-attachments/assets/6dac62f3-0f9d-4a32-8fe2-9fea9c380dae)

After trying myself locally I can also confirm that you need to context manager for the actual speedup. 

### Suggest a potential alternative/fix

The `n_jobs` did not cause a speedup locally but the context manager did so there is probably a situation with a docstring that needs updating. We should probably just change the docstring for the input of the estimator? But it could also make sense to mention the context manager more boldly.

@glemaitre had some ideas on this and knows more about the internals here.

COMMENT:
The docstring should be updated. As noted in the `predict` docstring, it is not always faster to set `n_jobs` for prediction.

In the PR that enabled `n_jobs` for prediction, we did not want to introduce a performance regression to `predict`. (Let's say you set `n_jobs=8` for training and an update to scikit-learn made `predict` slower).

Labels: Documentation
Version 1.6 docs inconsistency related to isolation forest.

### Describe the issue linked to the documentation

The current [isolation forest docs](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest) say this:

![image](https://github.com/user-attachments/assets/151df906-a56b-45d9-a704-41bd5606d8b4)

And this: 

![image](https://github.com/user-attachments/assets/6dac62f3-0f9d-4a32-8fe2-9fea9c380dae)

After trying myself locally I can also confirm that you need to context manager for the actual speedup. 

### Suggest a potential alternative/fix

The `n_jobs` did not cause a speedup locally but the context manager did so there is probably a situation with a docstring that needs updating. We should probably just change the docstring for the input of the estimator? But it could also make sense to mention the context manager more boldly.

@glemaitre had some ideas on this and knows more about the internals here.

COMMENT:
Indeed, the docstring should be updated to mention that `n_jobs` only affect `fit` and not `predict` (although in the snippet below `n_jobs` does not seem to have any effect on train time but that's a slightly different issue to investigate maybe):

For completeness the kind of script that @koaning ran on his machine:
```py
import time

from sklearn.datasets import make_blobs
from sklearn.ensemble import IsolationForest

from joblib import parallel_backend

X, y = make_blobs(n_samples=int(1e6))

def bench(n_jobs):
    start_time = time.time()
    iso = IsolationForest(n_jobs=n_jobs).fit(X, y)
    train_time = time.time()
    with parallel_backend('threading', n_jobs=n_jobs):
        iso.predict(X)
    predict_time = time.time()
    return {'train_time': train_time - start_time, 'predict_time': predict_time - train_time}


for n_jobs in [1, 2, 4, 8]:
    result = bench(n_jobs)
    train_time = result['train_time']
    predict_time = result['predict_time']

    print(f'{n_jobs=}: {train_time=} {predict_time=}')
```

I see similar thing as him, no effect of `n_jobs` on train time and some effect of `n_jobs` on predict time if a `parallel_backend` contextmanager is used (`joblib.cpu_count() = 12` on my machine with 2 performance cores with hyper-threading and 8 efficient cores):
```
n_jobs=1: train_time=0.4670231342315674 predict_time=4.309798717498779
n_jobs=2: train_time=0.41599225997924805 predict_time=2.055851936340332
n_jobs=4: train_time=0.4671483039855957 predict_time=1.2407822608947754
n_jobs=8: train_time=0.6490604877471924 predict_time=0.8615925312042236
```

Labels: Documentation
Version 1.6 docs inconsistency related to isolation forest.

### Describe the issue linked to the documentation

The current [isolation forest docs](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest) say this:

![image](https://github.com/user-attachments/assets/151df906-a56b-45d9-a704-41bd5606d8b4)

And this: 

![image](https://github.com/user-attachments/assets/6dac62f3-0f9d-4a32-8fe2-9fea9c380dae)

After trying myself locally I can also confirm that you need to context manager for the actual speedup. 

### Suggest a potential alternative/fix

The `n_jobs` did not cause a speedup locally but the context manager did so there is probably a situation with a docstring that needs updating. We should probably just change the docstring for the input of the estimator? But it could also make sense to mention the context manager more boldly.

@glemaitre had some ideas on this and knows more about the internals here.

COMMENT:
I opened https://github.com/scikit-learn/scikit-learn/pull/30501 to fix the confusing documentation and clarify the code a bit.

Labels: Documentation
`SVC` incorrectly swaps the weights for the positive and negative classes

### Describe the bug

See the example below. `C` is set to `100`, so with the class weights applied, `C` should be `100` for the positive class and `C` should be `50` for the negative class. But after adding some logging, we can see the `Cp` and `Cn` variables [here](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L1853) are `50` and `100`, respectively. This is the opposite of what was specified.

Root cause:
1. The labels are [sorted](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L2278-L2295) in ascending order. In the below example, the order is `[-1, 1]`.
2. The training code [assumes](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L2516) that the first label is the positive label and the second label is the negative label. This is the opposite order.

### Steps/Code to Reproduce

```python
from sklearn.svm import SVC

X = [
    [0],
    [11],
    [10]
]
y = [
    -1,
    -1,
    1
]

svc = SVC(
    C=100,
    kernel='linear',
    shrinking=False,
    class_weight={
        -1: 0.5,
        1: 1
    }
)
svc.fit(X=X, y=y)

print(svc.dual_coef_)
```

### Expected Results

```
[[ -4.54545455 -45.45454545  50.        ]]
```

### Actual Results

```
[[ -5.02 -50.    55.02]]
```

### Versions

```shell
System:
    python: 3.11.11 | packaged by conda-forge | (main, Dec  5 2024, 14:21:42) [Clang 18.1.8 ]
executable: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/bin/python
   machine: macOS-14.7.1-arm64-arm-64bit

Python dependencies:
      sklearn: 1.5.2
          pip: 24.3.1
   setuptools: 75.5.0
        numpy: 1.26.4
        scipy: 1.14.1
       Cython: None
       pandas: 2.2.3
   matplotlib: 3.9.3
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 10
         prefix: libopenblas
       filepath: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/lib/libopenblas.0.dylib
        version: 0.3.28
threading_layer: openmp
   architecture: VORTEX

       user_api: openmp
   internal_api: openmp
    num_threads: 10
         prefix: libomp
       filepath: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/lib/libomp.dylib
        version: None
```

COMMENT:
Related but not applicable to this fork: https://github.com/cjlin1/libsvm/pull/227.

Labels: Bug, Needs Triage
`SVC` incorrectly swaps the weights for the positive and negative classes

### Describe the bug

See the example below. `C` is set to `100`, so with the class weights applied, `C` should be `100` for the positive class and `C` should be `50` for the negative class. But after adding some logging, we can see the `Cp` and `Cn` variables [here](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L1853) are `50` and `100`, respectively. This is the opposite of what was specified.

Root cause:
1. The labels are [sorted](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L2278-L2295) in ascending order. In the below example, the order is `[-1, 1]`.
2. The training code [assumes](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L2516) that the first label is the positive label and the second label is the negative label. This is the opposite order.

### Steps/Code to Reproduce

```python
from sklearn.svm import SVC

X = [
    [0],
    [11],
    [10]
]
y = [
    -1,
    -1,
    1
]

svc = SVC(
    C=100,
    kernel='linear',
    shrinking=False,
    class_weight={
        -1: 0.5,
        1: 1
    }
)
svc.fit(X=X, y=y)

print(svc.dual_coef_)
```

### Expected Results

```
[[ -4.54545455 -45.45454545  50.        ]]
```

### Actual Results

```
[[ -5.02 -50.    55.02]]
```

### Versions

```shell
System:
    python: 3.11.11 | packaged by conda-forge | (main, Dec  5 2024, 14:21:42) [Clang 18.1.8 ]
executable: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/bin/python
   machine: macOS-14.7.1-arm64-arm-64bit

Python dependencies:
      sklearn: 1.5.2
          pip: 24.3.1
   setuptools: 75.5.0
        numpy: 1.26.4
        scipy: 1.14.1
       Cython: None
       pandas: 2.2.3
   matplotlib: 3.9.3
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 10
         prefix: libopenblas
       filepath: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/lib/libopenblas.0.dylib
        version: 0.3.28
threading_layer: openmp
   architecture: VORTEX

       user_api: openmp
   internal_api: openmp
    num_threads: 10
         prefix: libomp
       filepath: /opt/homebrew/Caskroom/miniforge/base/envs/momatrader-intelligence/lib/libomp.dylib
        version: None
```

COMMENT:
Oops, false alarm. The label values are also flipped [here](https://github.com/scikit-learn/scikit-learn/blob/6cccd99aee3483eb0f7562afdd3179ccccab0b1d/sklearn/svm/src/libsvm/svm.cpp#L2500-L2511) based on the label order, so the labels and the weights are consistent with each other.

Labels: Bug, Needs Triage
How can I obtain the explained variance for each latent component in PLS?

### Describe the workflow you want to enable

How can I further obtain the explained variance for each latent component in PLS using **sklearn.cross_decomposition.PLSRegression**?

### Describe your proposed solution

I need proposed solution

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

_No response_

### Additional context

_No response_

COMMENT:
Sorry I am going to close this one, it seems like you are asking a usage question and on top of this you did not provide enough information to help you.

The issue tracker is for bugs and new features. For usage questions, it is recommended to try [Stack Overflow](https://stackoverflow.com/questions/tagged/scikit-learn) or [Github Discussions](https://github.com/scikit-learn/scikit-learn/discussions).

Labels: New Feature, Needs Triage
API Deprecate n_alphas in LinearModelCV

In LassoCV, ElasticNetCV, ... we have two parameters, `alphas` and `n_alphas`, that have the same purpose, i.e. determine the alpha values to test.

I'd be in favor of deprecating `n_alphas` and make `alphas` accept either an int or an array-like, filling both roles.

I chose to keep `alphas` and not the other because `RidgeCV` has `alphas` and no `n_alphas` (although `alphas` can't be an int there, maybe an enhancement to make ?), and the most recent param of this kind, `threshold` in `TunedThresholdClassifierCV`, follows this naming pattern and fills both roles.

COMMENT:
Hi, can I take a shot at refactoring?

Labels: API, RFC
API Deprecate n_alphas in LinearModelCV

In LassoCV, ElasticNetCV, ... we have two parameters, `alphas` and `n_alphas`, that have the same purpose, i.e. determine the alpha values to test.

I'd be in favor of deprecating `n_alphas` and make `alphas` accept either an int or an array-like, filling both roles.

I chose to keep `alphas` and not the other because `RidgeCV` has `alphas` and no `n_alphas` (although `alphas` can't be an int there, maybe an enhancement to make ?), and the most recent param of this kind, `threshold` in `TunedThresholdClassifierCV`, follows this naming pattern and fills both roles.

COMMENT:
sure ! You can take a look at the [contributing guide](https://scikit-learn.org/dev/developers/contributing.html) and especially the [deprecation section](https://scikit-learn.org/dev/developers/contributing.html#deprecation) to get started.

Labels: API, RFC
API Deprecate n_alphas in LinearModelCV

In LassoCV, ElasticNetCV, ... we have two parameters, `alphas` and `n_alphas`, that have the same purpose, i.e. determine the alpha values to test.

I'd be in favor of deprecating `n_alphas` and make `alphas` accept either an int or an array-like, filling both roles.

I chose to keep `alphas` and not the other because `RidgeCV` has `alphas` and no `n_alphas` (although `alphas` can't be an int there, maybe an enhancement to make ?), and the most recent param of this kind, `threshold` in `TunedThresholdClassifierCV`, follows this naming pattern and fills both roles.

COMMENT:
@jeremiedbb Just created a PR, I believe it is linked. I followed the contributing guidelines to the best of my abilities, but happy to make any changes!

Labels: API, RFC