Talip7/scikit-learn-issues-multilabel huggingface dataset:
Expose Seed in FeatureHasher and HashingVectorizer

### Describe the workflow you want to enable

Varying the seed of the FeatureHasher allows the user to control what inputs collide. This can allow for a better feature space either through experimentation (as a hyperparameter) or explicitly searching for a space that minimizes "bad" collisions

### Describe your proposed solution

Add an optional "seed" parameter to the init of [FeatureHasher](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L20) which defaults to 0 (the current behavior, see [the underlying hashing function](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hashing_fast.pyx#L16)). The seed would be thread through to [_hashing_transform](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L179)

Ditto for [HashingVectorizer](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903). Only difference here is that the seed would be passed to the [FeatureHasher instance](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903)

This seems straightforward so I can implement this solution if it makes sense

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

_No response_

### Additional context

_No response_

COMMENT:
> Looking at the file's [commit history](https://github.com/scikit-learn/scikit-learn/commits/13134a884b92f8c601162ce4f125c2fc17c6ed4a/sklearn/feature_extraction/_hashing.py?browsing_rename_history=true&new_path=sklearn/feature_extraction/_hash.py&original_branch=main) the seed gets merged [here](https://github.com/scikit-learn/scikit-learn/commit/9b045d4bde6f8bd50d05468aad8731547ec21910), but removed the [next commit during a renaming](https://github.com/scikit-learn/scikit-learn/commit/bb3b3f9261bd092ed010d80de35fe031123c1687)

As far I see, the `seed` parameter is added to the helper function of the cython routine and not the public class (i.e. `FeatureHasher` and `HashingVectorizer`).

> If so, could the seed be added back like was done by https://github.com/scikit-learn/scikit-learn/pull/14605?

I went through the discussion and I could spot the following points. For a consistent API, we would prefer to have `random_state`. However, the behaviour is not in line with other estimators' `random_state` and it is surprising. So `seed` is a better name but we might not want to introduce it because it makes it inconsistent.

So it lead to discussion around fixing (or not) the behaviour of `random_state` with random number generator that is tightly related to https://github.com/scikit-learn/enhancement_proposals/pull/88.

So the middle ground in #14605 was to introduce `seed` into the cython function only.

Labels: New Feature, Needs Decision
Expose Seed in FeatureHasher and HashingVectorizer

### Describe the workflow you want to enable

Varying the seed of the FeatureHasher allows the user to control what inputs collide. This can allow for a better feature space either through experimentation (as a hyperparameter) or explicitly searching for a space that minimizes "bad" collisions

### Describe your proposed solution

Add an optional "seed" parameter to the init of [FeatureHasher](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L20) which defaults to 0 (the current behavior, see [the underlying hashing function](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hashing_fast.pyx#L16)). The seed would be thread through to [_hashing_transform](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L179)

Ditto for [HashingVectorizer](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903). Only difference here is that the seed would be passed to the [FeatureHasher instance](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903)

This seems straightforward so I can implement this solution if it makes sense

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

_No response_

### Additional context

_No response_

COMMENT:
My bad, I misunderstood the original commit.

For the discussion about naming the variable, is there a similar case in the Sklearn API that serve as a reference? I'm not sure how to help or who could help otherwise

It would be nice to have a long term solution and not just modify sklearn files locally to have access to the seed

Labels: New Feature, Needs Decision
Expose Seed in FeatureHasher and HashingVectorizer

### Describe the workflow you want to enable

Varying the seed of the FeatureHasher allows the user to control what inputs collide. This can allow for a better feature space either through experimentation (as a hyperparameter) or explicitly searching for a space that minimizes "bad" collisions

### Describe your proposed solution

Add an optional "seed" parameter to the init of [FeatureHasher](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L20) which defaults to 0 (the current behavior, see [the underlying hashing function](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hashing_fast.pyx#L16)). The seed would be thread through to [_hashing_transform](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/_hash.py#L179)

Ditto for [HashingVectorizer](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903). Only difference here is that the seed would be passed to the [FeatureHasher instance](https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/feature_extraction/text.py#L903)

This seems straightforward so I can implement this solution if it makes sense

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

_No response_

### Additional context

_No response_

COMMENT:
> For the discussion about naming the variable, is there a similar case in the Sklearn API that serve as a reference? I'm not sure how to help or who could help otherwise

Basically this is a particular case which make it difficult. In this case, we need to come with a consensus among the core developer. I'll bring this topic on the next developer meeting at the end of the month.

Labels: New Feature, Needs Decision
spin docs --no-plot runs the examples

Seen at the EuroScipy sprint

Commands run by spin:
```
$ export SPHINXOPTS=-W -D plot_gallery=0 -j auto
$ cd doc
$ make html
```

Looks like our Makefile does not use SPHINXOPTS the same way as expected:
Probably we have a slightly different way of building the doc

```
❯ make html-noplot -n
sphinx-build -D plot_gallery=0 -b html -d _build/doctrees  -T  . -jauto \
    _build/html/stable
echo
echo "Build finished. The HTML pages are in _build/html/stable."
```

COMMENT:
Things must have changed in the meantime. Right now:

```
export SPHINXOPTS="-W -D plot_gallery=0"
export SPHINX_NUMJOBS=1
make html
```

gives this command:

```
sphinx-build -b html -d _build/doctrees  -W -D plot_gallery=0  . -j1 _build/html/stable
```
which seems correct.

Labels: Bug, Sprint
Add a LogTransformer and a LogWithShiftTransformer

### Describe the workflow you want to enable

I suggest adding new transformers to scikit-learn named `LogTransformer` and `LogWithShiftTransformer`, which would add the functionality of applying a logarithmic transformation and a logarithmic transformation capable of handling negative values in time series data, respectively. These transformers would be particularly useful for preprocessing time series data that may contain zero or negative values

### Describe your proposed solution

Add two custom scikit-learn transformers: `LogTransformer` and `LogWithShiftTransformer`, designed for preprocessing time series with their corresponding inverse transformers. Currently one can able to do that with the `FunctionTransformer` which is not efficient or checked.

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

_No response_

### Additional context

_No response_

COMMENT:
> Currently one can able to do that with the FunctionTransformer which is not efficient or checked.

Could you elaborate on the effectiveness and checks?

Since this is a stateless transform, I would expect the `FunctionTransformer` to be good enough. For checks, the `FunctionTransformer` can validate data if needed. However, you might have in head a different type of checking?

Labels: New Feature, Needs Info
Add a LogTransformer and a LogWithShiftTransformer

### Describe the workflow you want to enable

I suggest adding new transformers to scikit-learn named `LogTransformer` and `LogWithShiftTransformer`, which would add the functionality of applying a logarithmic transformation and a logarithmic transformation capable of handling negative values in time series data, respectively. These transformers would be particularly useful for preprocessing time series data that may contain zero or negative values

### Describe your proposed solution

Add two custom scikit-learn transformers: `LogTransformer` and `LogWithShiftTransformer`, designed for preprocessing time series with their corresponding inverse transformers. Currently one can able to do that with the `FunctionTransformer` which is not efficient or checked.

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

_No response_

### Additional context

_No response_

COMMENT:
No answer from the reporter, let's close this one. Happy to reopen if we get more details and we think there is enough interest from our users.

Labels: New Feature, Needs Info
Remove outdated brand file identity.pdf

### Describe the issue linked to the documentation

This document is outdated : doc/logos/identity.pdf

### Suggest a potential alternative/fix

_No response_

COMMENT:
Thanks @x-probabl for raising the issue. 
@glemaitre we don't have this yet, but it is on our TODO. For the moment I think the identity.pdf was supposed to be a .pdf version /doc/logos/README.md

Labels: Documentation, Needs Triage
Remove outdated brand file identity.pdf

### Describe the issue linked to the documentation

This document is outdated : doc/logos/identity.pdf

### Suggest a potential alternative/fix

_No response_

COMMENT:
Once we have a replacement, happy to replace the file, but in the meantime, I honestly don't see how it's outdated really (other than the version). So I think we can close this one. Also, please add more context when opening issues.

Labels: Documentation, Needs Triage
⚠️ CI failed on Linux_Runs.pylatest_conda_forge_mkl (last failure: Sep 01, 2024) ⚠️

**CI is still failing on [Linux_Runs.pylatest_conda_forge_mkl](https://dev.azure.com/scikit-learn/scikit-learn/_build/results?buildId=69751&view=logs&j=dde5042c-7464-5d47-9507-31bdd2ee0a3a)** (Sep 01, 2024)
- sklearn.datasets._lfw.fetch_lfw_pairs

COMMENT:
Why this is starting to fail only now is a mystery but the fix is easy https://github.com/scikit-learn/scikit-learn/pull/29753 ...

```
_______________ [doctest] sklearn.datasets._lfw.fetch_lfw_pairs ________________
[gw0] linux -- Python 3.12.5 /usr/share/miniconda/envs/testvenv/bin/python
564             Explains the target values of the target array.
565             0 corresponds to "Different person", 1 corresponds to "same person".
566         DESCR : str
567             Description of the Labeled Faces in the Wild (LFW) dataset.
568 
569     Examples
570     --------
571     >>> from sklearn.datasets import fetch_lfw_pairs
572     >>> lfw_pairs_train = fetch_lfw_pairs(subset='train')
573     >>> list(lfw_pairs_train.target_names)
Expected:
    ['Different persons', 'Same person']
Got:
    [np.str_('Different persons'), np.str_('Same person')]
```

Labels: Needs Triage
Make `KNeighborsClassifier.predict` and `KNeighborsRegressor.predict` react the same way to `X=None`

### Describe the workflow you want to enable

Currently `KNeighborsRegressor.predict()` accepts `None` as input, in which case it returns prediction for all samples in the training set based on the nearest neighbors not including the sample itself (consistent with `NearestNeighbors` behavior). However, `KNeighborsClassifier.predict()` does not accept `None` as input. This is inconsistent and should arguably be harmonized:

```Python
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor, NearestNeighbors
import numpy as np

X = np.random.normal(size=(10, 5))
y = np.random.normal(size=(10, 1))

knn = NearestNeighbors(n_neighbors=3)
knn.fit(X)
knn.kneighbors() # works

knn = KNeighborsRegressor(n_neighbors=3)
knn.fit(X, y)
knn.predict(None) # works (NB: does not work without "None")

knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X, np.ravel(y) > 0)
knn.predict(None) # fails with an error
```

### Describe your proposed solution

My proposed solution is to make `KNeighborsClassifier.predict(None)` behave the same as `KNeighborsRegressor.predict(None)`. As explained in https://github.com/scikit-learn/scikit-learn/issues/27747, the necessary fix requires changing only two lines of code.


### Additional context

As explained in https://github.com/scikit-learn/scikit-learn/issues/27747, this would be a great feature, super useful and convenient for computing LOOCV accuracy simply via `score(None, y)`. Using `score(X, y)` where `X` is the training set used in `fit(X)` gives a biased result because each (training set) sample gets included into its own neighbors.

COMMENT:
Hello! I could take it to implement if nobody is working on it

Labels: New Feature
Make `KNeighborsClassifier.predict` and `KNeighborsRegressor.predict` react the same way to `X=None`

### Describe the workflow you want to enable

Currently `KNeighborsRegressor.predict()` accepts `None` as input, in which case it returns prediction for all samples in the training set based on the nearest neighbors not including the sample itself (consistent with `NearestNeighbors` behavior). However, `KNeighborsClassifier.predict()` does not accept `None` as input. This is inconsistent and should arguably be harmonized:

```Python
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor, NearestNeighbors
import numpy as np

X = np.random.normal(size=(10, 5))
y = np.random.normal(size=(10, 1))

knn = NearestNeighbors(n_neighbors=3)
knn.fit(X)
knn.kneighbors() # works

knn = KNeighborsRegressor(n_neighbors=3)
knn.fit(X, y)
knn.predict(None) # works (NB: does not work without "None")

knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X, np.ravel(y) > 0)
knn.predict(None) # fails with an error
```

### Describe your proposed solution

My proposed solution is to make `KNeighborsClassifier.predict(None)` behave the same as `KNeighborsRegressor.predict(None)`. As explained in https://github.com/scikit-learn/scikit-learn/issues/27747, the necessary fix requires changing only two lines of code.


### Additional context

As explained in https://github.com/scikit-learn/scikit-learn/issues/27747, this would be a great feature, super useful and convenient for computing LOOCV accuracy simply via `score(None, y)`. Using `score(X, y)` where `X` is the training set used in `fit(X)` gives a biased result because each (training set) sample gets included into its own neighbors.

COMMENT:
Thanks @ogrisel. I will try to prepare a PR in October.

Labels: New Feature
Split common tests into groups

With https://github.com/scikit-learn/scikit-learn/pull/29699 we start by having two groups of tests:

- API: the PR introduces a very basic start for this category from existing tests, but the idea is to add more here, and to properly document them in the developer guide as we go later on. This category is always ON and cannot be disabled.
- legacy: all other tests. The idea is to move those tests into their own dedicated categories and to eventually have nothing left in legacy.

Some other categories which seem reasonable to have:
- sample weight related tests
- array API
- pandas / polars / dataframe compat
- statistical / performance tests
- missing values

COMMENT:
I would need to see further the test but I would think that grouping `sample_weight` in the statistical test would make sense.

Labels: Developer API
Problem using RandomizedSearchCV

Hello, I am Yuvraj.

Today, I encountered an issue while running a model using RandomizedSearchCV. The process works fine when n_iter=2, but it gets stuck when n_iter=3. I am unsure why this happens.

![image](https://github.com/user-attachments/assets/c8da7183-276b-4bfa-b50d-4374a773d327)

COMMENT:
In order to assess what's the issue, a minimal reproducing example is helpful. In addition, it's unclear what is the issue even in this case (or if there is anything wrong at all).

 https://scikit-learn.org/stable/developers/minimal_reproducer.html

Labels: Needs Info, Needs Reproducible Code
Problem using RandomizedSearchCV

Hello, I am Yuvraj.

Today, I encountered an issue while running a model using RandomizedSearchCV. The process works fine when n_iter=2, but it gets stuck when n_iter=3. I am unsure why this happens.

![image](https://github.com/user-attachments/assets/c8da7183-276b-4bfa-b50d-4374a773d327)

COMMENT:
Below the the code 
```python

import numpy as np
from sklearn.model_selection import RandomizedSearchCV
from sklearn.base import BaseEstimator
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from fz import FuzzyART


class Model(BaseEstimator):
    def __init__(self):
        param_dist = {
            "rho": [0.80, 0.85, 0.90, 0.95, 1.0],
            "rho_ab": [0.80, 0.85, 0.90, 0.95, 1.0],
            "beta": [0.80, 0.85, 0.90, 0.95, 1.0],
            "committed_beta": [0.80, 0.85, 0.90, 0.95, 1.0]
        }
        self.random_search = RandomizedSearchCV(
                estimator=FuzzyART(),
                param_distributions=param_dist,
                n_iter=3,
                cv=5,
                random_state=42,
                n_jobs=1,
                verbose=3
            )

    def fit(self, X, y):
        self.model = self.random_search.fit(X, y).best_estimator_
        self.model.fit(X, y)
    
    def predict(self, X):
        return self.model.predict(X)


if __name__ == "__main__":
    np.random.seed(42)
    num_features = 28 

    layer2_X = np.random.rand(499, num_features)
    layer2_y = np.random.randint(0, 2, size=499) 

    unknown_X = np.random.rand(70, num_features)
    unknown_y = np.full(70, -1)

    # Create DataFrames
    layer2 = pd.DataFrame(layer2_X, columns=[f'feature_{i}' for i in range(num_features)])
    layer2['Label'] = layer2_y
    unknown = pd.DataFrame(unknown_X, columns=[f'feature_{i}' for i in range(num_features)])
    unknown['Label'] = unknown_y

    # Scaling
    scalar = MinMaxScaler(feature_range=(0, 1))
    layer2_X = layer2.drop(['Label'], axis=1)
    layer2_X = np.clip(scalar.fit_transform(layer2_X), 0, 1)
    layer2_y = LabelEncoder().fit_transform(layer2['Label'])
    layer2_unknown_X = np.clip(scalar.fit_transform(unknown.drop(columns=["Label"], axis=1)), 0, 1)
    layer2_unknown_y = unknown['Label']

    # Train-test split
    layer2_X_train, layer2_X_test, layer2_y_train, layer2_y_test = train_test_split(layer2_X, layer2_y, test_size=0.20, random_state=0)
    layer2_X_test_combined = np.concatenate((layer2_X_test, layer2_unknown_X), axis=0)
    layer2_y_test_combined = np.concatenate((layer2_y_test, layer2_unknown_y), axis=0)

    model = Model()
    model.fit(layer2_X_train, layer2_y_train)
    print(model)
    model.predict(layer2_X_test_combined, layer2_y_test_combined)
```
if you need FuzzyART code then let me know.

Labels: Needs Info, Needs Reproducible Code
Problem using RandomizedSearchCV

Hello, I am Yuvraj.

Today, I encountered an issue while running a model using RandomizedSearchCV. The process works fine when n_iter=2, but it gets stuck when n_iter=3. I am unsure why this happens.

![image](https://github.com/user-attachments/assets/c8da7183-276b-4bfa-b50d-4374a773d327)

COMMENT:
To be honest, quickly looking at the code this is quite likely that the issue is in your FuzzyART estimator. Of course this is a guess and it could well be wrong. Here is a few things you would need to do:
- give us a standalone snippet that we can run on our machine to see if we can reproduce and possibly debug if we think this is an issue in scikit-learn
- to simplify your example in particular not have any external dependency to convince us that the problem is likely in scikit-learn ...

Labels: Needs Info, Needs Reproducible Code
Problem using RandomizedSearchCV

Hello, I am Yuvraj.

Today, I encountered an issue while running a model using RandomizedSearchCV. The process works fine when n_iter=2, but it gets stuck when n_iter=3. I am unsure why this happens.

![image](https://github.com/user-attachments/assets/c8da7183-276b-4bfa-b50d-4374a773d327)

COMMENT:
@yuvrajeyes OK I am going to close this one because I tried to put together a stand-alone snippet from the pieces of code that you posted and I get a `RecursionError` ...

Just to be clear because maybe https://scikit-learn.org/stable/developers/minimal_reproducer.html is not clear enough or maybe you skipped the relevant sections:
- a standalone snippet is something that anyone can copy and paste and expect to run with 99% probability. Your snippets miss some imports, for example `typing.Tuple` so that's an issue
- it does not feel like you have not tried to make your example minimal, for example the tqdm dependency is probably not needed to reproduce the issue
- basically the easier you can make it to run your snippet and the simpler your snippet is, the more likely it is that you will get a relevant answer.

User questions are best asked on StackOverflow, unfortunately maintainers are already overwhelmed trying to improve scikit-learn.

There could be an underlying scikit-learn bug but I would say this is unlikely, in case I am wrong I am more than happy to revisit and reopen this issue.

Labels: Needs Info, Needs Reproducible Code
⚠️ CI failed on Wheel builder (last failure: Aug 21, 2024) ⚠️

**CI failed on [Wheel builder](https://github.com/scikit-learn/scikit-learn/actions/runs/10483139590)** (Aug 21, 2024)

COMMENT:
## CI is no longer failing! ✅

[Successful run](https://github.com/scikit-learn/scikit-learn/actions/runs/10501460588) on Aug 22, 2024

Labels: Needs Triage