Talip7/scikit-learn-issues-multilabel huggingface dataset:
Request for project inclusion in scikit-learn related projects: skforecast

### Describe the issue linked to the documentation

Hi! We have seen on the [Related Projects](https://scikit-learn.org/stable/related_projects.html) page that projects closely related to **scikit-learn** are mentioned. We would like to propose the inclusion of skforecast in that list.

Skforecast is not focused on developing new estimators, but rather on facilitating using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).

- **Project name:** skforecast
- **Project description:** skforecast is a python library that eases using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).
- **Authors:** Joaquín Amat Rodrigo (https://github.com/JoaquinAmatRodrigo), Javier Escobar Ortiz (https://github.com/JavierEscobarOrtiz)
- **Current repository:** https://github.com/JoaquinAmatRodrigo/skforecast

Thank you!

### Suggest a potential alternative/fix

_No response_

COMMENT:
Hello @vinodhkrishnaraju, I believe I am the person who requested to claim this issue, and I am currently working on it by assigning myself. I think you should have claimed this issue before if you want to ask pull request on this. Thank you

Labels: Documentation
Request for project inclusion in scikit-learn related projects: skforecast

### Describe the issue linked to the documentation

Hi! We have seen on the [Related Projects](https://scikit-learn.org/stable/related_projects.html) page that projects closely related to **scikit-learn** are mentioned. We would like to propose the inclusion of skforecast in that list.

Skforecast is not focused on developing new estimators, but rather on facilitating using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).

- **Project name:** skforecast
- **Project description:** skforecast is a python library that eases using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).
- **Authors:** Joaquín Amat Rodrigo (https://github.com/JoaquinAmatRodrigo), Javier Escobar Ortiz (https://github.com/JavierEscobarOrtiz)
- **Current repository:** https://github.com/JoaquinAmatRodrigo/skforecast

Thank you!

### Suggest a potential alternative/fix

_No response_

COMMENT:
@seoeunHong Oops. This was my first contribution and didn't know the procedure. I will close my PR. Hence on, I will assign myself before taking any issue. Thanks

Labels: Documentation
Request for project inclusion in scikit-learn related projects: skforecast

### Describe the issue linked to the documentation

Hi! We have seen on the [Related Projects](https://scikit-learn.org/stable/related_projects.html) page that projects closely related to **scikit-learn** are mentioned. We would like to propose the inclusion of skforecast in that list.

Skforecast is not focused on developing new estimators, but rather on facilitating using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).

- **Project name:** skforecast
- **Project description:** skforecast is a python library that eases using scikit-learn regressors as multi-step forecasters. It also works with any regressor compatible with the scikit-learn API (pipelines, CatBoost, LightGBM, XGBoost, Ranger...).
- **Authors:** Joaquín Amat Rodrigo (https://github.com/JoaquinAmatRodrigo), Javier Escobar Ortiz (https://github.com/JavierEscobarOrtiz)
- **Current repository:** https://github.com/JoaquinAmatRodrigo/skforecast

Thank you!

### Suggest a potential alternative/fix

_No response_

COMMENT:
Hello, @vinodhkrishnaraju, Thank you so much for responding to my comment, and good luck with your future contributions too!

Labels: Documentation
`Fmax` score (or maximum of F1/Fbeta)

### Describe the workflow you want to enable

The maximum of F1 across thresholds is a well-studied metric and it is both robust and valid in binary and multilabel classification problems.  Basically, it can be computed with `precision_recall_curve`, as shown below, for binary problems.  For multilabel problems, I'm not sure if there is an efficient way to do this without looping thru all labels.

### Describe your proposed solution

For binary:
```
def get_fmax(preds: np.ndarray, ys: np.ndarray, beta = 1.0, pos_label = 1):
    """
    Radivojac, P. et al. (2013). A Large-Scale Evaluation of Computational Protein Function Prediction. Nature Methods, 10(3), 221-227.
    """
    precision, recall, thresholds = precision_recall_curve(y_true = ys, probas_pred = preds, pos_label = pos_label)
    numerator = (1 + beta**2) * (precision * recall)
    denominator = ((beta**2 * precision) + recall)
    fbeta = np.divide(numerator, denominator, out=np.zeros_like(numerator), where=(denominator!=0))
    
    return np.nanmax(fbeta), thresholds[np.argmax(fbeta)]
```

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

_No response_

### Additional context

_No response_

COMMENT:
I had never heard of this. Is this used in other papers besides the one linked in the docstring?

Labels: New Feature, Needs Info, Needs Decision - Include Feature
`Fmax` score (or maximum of F1/Fbeta)

### Describe the workflow you want to enable

The maximum of F1 across thresholds is a well-studied metric and it is both robust and valid in binary and multilabel classification problems.  Basically, it can be computed with `precision_recall_curve`, as shown below, for binary problems.  For multilabel problems, I'm not sure if there is an efficient way to do this without looping thru all labels.

### Describe your proposed solution

For binary:
```
def get_fmax(preds: np.ndarray, ys: np.ndarray, beta = 1.0, pos_label = 1):
    """
    Radivojac, P. et al. (2013). A Large-Scale Evaluation of Computational Protein Function Prediction. Nature Methods, 10(3), 221-227.
    """
    precision, recall, thresholds = precision_recall_curve(y_true = ys, probas_pred = preds, pos_label = pos_label)
    numerator = (1 + beta**2) * (precision * recall)
    denominator = ((beta**2 * precision) + recall)
    fbeta = np.divide(numerator, denominator, out=np.zeros_like(numerator), where=(denominator!=0))
    
    return np.nanmax(fbeta), thresholds[np.argmax(fbeta)]
```

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

_No response_

### Additional context

_No response_

COMMENT:
> I had never heard of this. Is this used in other papers besides the one linked in the docstring?

I believe it's mainly used for highly imbalanced classification (as a supplement to AUPRC and various @K metrics).  Specifically, in bioinformatics, imbalanced problems are just so frequent -- especially for function predictions. For example, the CAFA challenge, the major competition in protein function prediction benchmarking, uses Fmax as the key metric for comparison, see https://genomebiology.biomedcentral.com/articles/10.1186/s13059-019-1835-8. There are also various standard tasks and high-profile papers in functional genomics that uses Fmax as a standard metric.

See some discussions over the idea of finding the optimal threshold for precision-recall curve at: 
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4442797/
https://towardsdatascience.com/optimal-threshold-for-imbalanced-classification-5884e870c293
https://machinelearningmastery.com/threshold-moving-for-imbalanced-classification/
https://stats.stackexchange.com/questions/182331/what-is-f1-optimal-threshold-how-to-calculate-it

Labels: New Feature, Needs Info, Needs Decision - Include Feature
`Fmax` score (or maximum of F1/Fbeta)

### Describe the workflow you want to enable

The maximum of F1 across thresholds is a well-studied metric and it is both robust and valid in binary and multilabel classification problems.  Basically, it can be computed with `precision_recall_curve`, as shown below, for binary problems.  For multilabel problems, I'm not sure if there is an efficient way to do this without looping thru all labels.

### Describe your proposed solution

For binary:
```
def get_fmax(preds: np.ndarray, ys: np.ndarray, beta = 1.0, pos_label = 1):
    """
    Radivojac, P. et al. (2013). A Large-Scale Evaluation of Computational Protein Function Prediction. Nature Methods, 10(3), 221-227.
    """
    precision, recall, thresholds = precision_recall_curve(y_true = ys, probas_pred = preds, pos_label = pos_label)
    numerator = (1 + beta**2) * (precision * recall)
    denominator = ((beta**2 * precision) + recall)
    fbeta = np.divide(numerator, denominator, out=np.zeros_like(numerator), where=(denominator!=0))
    
    return np.nanmax(fbeta), thresholds[np.argmax(fbeta)]
```

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

_No response_

### Additional context

_No response_

COMMENT:
Olivier never heard of this, nobody in 2+ years expressed interest, so it's very unlikely that it will be at the top of our priorities in the foreseeable future. I am going to close this one.

Happy to reopen in case the situation changes significantly somehow.

Labels: New Feature, Needs Info, Needs Decision - Include Feature
GaussianMixture is runnning too many computation when parameters are alredy provided

In `GaussianMixture`, if a user is passing some initial values for the weights, means, and precision then there is no need to run the initialization (via kmeans or random) and to estimate the gaussian parameters.

However, currently, we still run these two steps and then discard them.

I think that we can make the estimator more efficient by bypassing these steps in case we already have all the necessary statistics to start the EM algorithm.

COMMENT:
If it's acceptable, may I kindly take responsibility for addressing this issue?

Labels: Easy, Enhancement, Performance
GaussianMixture is runnning too many computation when parameters are alredy provided

In `GaussianMixture`, if a user is passing some initial values for the weights, means, and precision then there is no need to run the initialization (via kmeans or random) and to estimate the gaussian parameters.

However, currently, we still run these two steps and then discard them.

I think that we can make the estimator more efficient by bypassing these steps in case we already have all the necessary statistics to start the EM algorithm.

COMMENT:
@jiawei-zhang-a go ahead.

Labels: Easy, Enhancement, Performance
GaussianMixture is runnning too many computation when parameters are alredy provided

In `GaussianMixture`, if a user is passing some initial values for the weights, means, and precision then there is no need to run the initialization (via kmeans or random) and to estimate the gaussian parameters.

However, currently, we still run these two steps and then discard them.

I think that we can make the estimator more efficient by bypassing these steps in case we already have all the necessary statistics to start the EM algorithm.

COMMENT:
@glemaitre  Thank you so much!

Labels: Easy, Enhancement, Performance
GaussianMixture is runnning too many computation when parameters are alredy provided

In `GaussianMixture`, if a user is passing some initial values for the weights, means, and precision then there is no need to run the initialization (via kmeans or random) and to estimate the gaussian parameters.

However, currently, we still run these two steps and then discard them.

I think that we can make the estimator more efficient by bypassing these steps in case we already have all the necessary statistics to start the EM algorithm.

COMMENT:
/take

Labels: Easy, Enhancement, Performance
GaussianMixture is runnning too many computation when parameters are alredy provided

In `GaussianMixture`, if a user is passing some initial values for the weights, means, and precision then there is no need to run the initialization (via kmeans or random) and to estimate the gaussian parameters.

However, currently, we still run these two steps and then discard them.

I think that we can make the estimator more efficient by bypassing these steps in case we already have all the necessary statistics to start the EM algorithm.

COMMENT:
@glemaitre Sir, I have a question about adding private variable into class and where to add it. I do not know if I can add a private variable `_init_skipped` in base class `BaseMixture`. 

But it seems to be necessary because part of the initialization is in `BaseMixture `. This variable will be set to be True or False in subclass `GaussianMixture`, and  so I need one variable in base to know if the base class's `fit_transform` can skip the  initialization.

Labels: Easy, Enhancement, Performance
Add per feature "maximum category" counts to `OrdinalEncoder`

### Describe the workflow you want to enable

This is a follow up task for #25677

It would be nice to allow users to [specify a per feature number of maxcategories](https://github.com/scikit-learn/scikit-learn/pull/25677#discussion_r1132500192) instead of having a global limit as implemented in #25677.

More details in the linked comment.

### Describe your proposed solution

Allow users to pass a list of shape `(n_features,)` or a dict mapping column name to `max_categories` values to specify the number of maximum categories per feature.

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

_No response_

### Additional context

_No response_

COMMENT:
Dear @betatim,

I'm reaching out to express my interest in contributing to the scikit-learn project, specifically the issue #26013 that you opened regarding adding per feature maximum category counts to OrdinalEncoder.

I have experience with Python programming and machine learning, and I believe that I can make a meaningful contribution to this project. I'm excited about the idea of allowing users to specify the number of maximum categories per feature, and I'm eager to work on this feature.

I would appreciate it if you could guide me on how to get started with this project. Should I read any specific documentation or study any relevant code before diving in?

Thank you for your time and consideration.

Best regards,
Aryan Mishra

Labels: New Feature
Add per feature "maximum category" counts to `OrdinalEncoder`

### Describe the workflow you want to enable

This is a follow up task for #25677

It would be nice to allow users to [specify a per feature number of maxcategories](https://github.com/scikit-learn/scikit-learn/pull/25677#discussion_r1132500192) instead of having a global limit as implemented in #25677.

More details in the linked comment.

### Describe your proposed solution

Allow users to pass a list of shape `(n_features,)` or a dict mapping column name to `max_categories` values to specify the number of maximum categories per feature.

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

_No response_

### Additional context

_No response_

COMMENT:
Hi @betatim, if this feature can be considered for inclusion, I would like to work on this issue.

Labels: New Feature
Add per feature "maximum category" counts to `OrdinalEncoder`

### Describe the workflow you want to enable

This is a follow up task for #25677

It would be nice to allow users to [specify a per feature number of maxcategories](https://github.com/scikit-learn/scikit-learn/pull/25677#discussion_r1132500192) instead of having a global limit as implemented in #25677.

More details in the linked comment.

### Describe your proposed solution

Allow users to pass a list of shape `(n_features,)` or a dict mapping column name to `max_categories` values to specify the number of maximum categories per feature.

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

_No response_

### Additional context

_No response_

COMMENT:
If you want to work on this please do. Try and open a PR as soon as possible so that others can see that you are working on this and people can guide the work. You can mark the PR as "draft" if it isn't ready for reviewing yet.

Labels: New Feature
Add per feature "maximum category" counts to `OrdinalEncoder`

### Describe the workflow you want to enable

This is a follow up task for #25677

It would be nice to allow users to [specify a per feature number of maxcategories](https://github.com/scikit-learn/scikit-learn/pull/25677#discussion_r1132500192) instead of having a global limit as implemented in #25677.

More details in the linked comment.

### Describe your proposed solution

Allow users to pass a list of shape `(n_features,)` or a dict mapping column name to `max_categories` values to specify the number of maximum categories per feature.

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

_No response_

### Additional context

_No response_

COMMENT:
Hi @betatim, I would opened a working PR. The failures stem from the lack of an updated changelog and the fact that many files not changed by this PR are not properly linted.

Labels: New Feature
Introduce SIMD intrinsics for `_dist_metrics.pyx`

# Context
Pairwise distance computation is an essential part of many estimators in scikit-learn, and can take up a significant portion of run time in certain workflows. I believe that we may achieve significant performance gains in several (perhaps most) distance metric implementations by leveraging SIMD intrinsics.

# Proof of Concept

I built a quick proof of concept just to see what kinds of performance gains we could observe with a potentially-naive implementation of SIMD intrinsics. I chose to optimize the `ManhattanDistance.dist` function. This implementation uses intrinsics found in `SSE{1,2,3}`. To ensure that the instructions are supported, it checks for the presence of the `SSE3`  instruction set (`SSE3` implies `SSE{1,2}`) and provides the optimized implementation if so. Otherwise it provides a dummy implementation just to appease Cython, and the main function falls back to the current implementation on `main`. Note that on most modern hardware, support for `SSE3` is a reasonable expectation (indeed numpy assumes it is always present when optimization is enabled). For the specific implementation referred to here, please take a look at this PR: https://github.com/Micky774/scikit-learn/pull/11

Note that the full benefit of the intrinsics are gained when compiling with `-march="native"`, however the benefit is still significant when compiling with `-march="nocona"`, as is often default (e.g when following the scikit-learn development instructions on linux).

# Benchmarks
The following benchmarks were produced by this gist: https://gist.github.com/Micky774/567a5fa199c05d90c4c08625b077840e

### **Summary: The SIMD implementations are ~2x faster than the current implementation for `float32` and 1.5x faster for `float64`.**

<details>
<summary>Plots</summary>

![f2b1f1e8-59b0-4ec5-b91c-fe1d19abd9ec](https://user-images.githubusercontent.com/34613774/228374474-99ee13b3-228d-4c53-9dcc-3a8f8b639a9f.png)
</details>

# Discussion
I haven't looked too deeply into this yet, as first I wanted to see whether there was interest in the venture. I would love to hear what the other maintainers' thoughts are regarding exploring this route in a bit more detail. Obviously SIMD implementations will bring with them added complexity, but the performance gains are pretty compelling. In my opinion, the tradeoff is worth it.

CC: @scikit-learn/core-devs

COMMENT:
> Summary: The SIMD implementations are ~2x faster than the current implementation for float32 and 1.5x faster for float64.

What I am wondering is if these 2x and 1.5x are also obtained at the level of the estimator. My feeling here is that we will introduce a layer of complexity that we probably want to extend to a lot of subroutines. Is the complexity worth the 1.5x to 2x speed-up?

Labels: Enhancement, Needs Decision, cython
Introduce SIMD intrinsics for `_dist_metrics.pyx`

# Context
Pairwise distance computation is an essential part of many estimators in scikit-learn, and can take up a significant portion of run time in certain workflows. I believe that we may achieve significant performance gains in several (perhaps most) distance metric implementations by leveraging SIMD intrinsics.

# Proof of Concept

I built a quick proof of concept just to see what kinds of performance gains we could observe with a potentially-naive implementation of SIMD intrinsics. I chose to optimize the `ManhattanDistance.dist` function. This implementation uses intrinsics found in `SSE{1,2,3}`. To ensure that the instructions are supported, it checks for the presence of the `SSE3`  instruction set (`SSE3` implies `SSE{1,2}`) and provides the optimized implementation if so. Otherwise it provides a dummy implementation just to appease Cython, and the main function falls back to the current implementation on `main`. Note that on most modern hardware, support for `SSE3` is a reasonable expectation (indeed numpy assumes it is always present when optimization is enabled). For the specific implementation referred to here, please take a look at this PR: https://github.com/Micky774/scikit-learn/pull/11

Note that the full benefit of the intrinsics are gained when compiling with `-march="native"`, however the benefit is still significant when compiling with `-march="nocona"`, as is often default (e.g when following the scikit-learn development instructions on linux).

# Benchmarks
The following benchmarks were produced by this gist: https://gist.github.com/Micky774/567a5fa199c05d90c4c08625b077840e

### **Summary: The SIMD implementations are ~2x faster than the current implementation for `float32` and 1.5x faster for `float64`.**

<details>
<summary>Plots</summary>

![f2b1f1e8-59b0-4ec5-b91c-fe1d19abd9ec](https://user-images.githubusercontent.com/34613774/228374474-99ee13b3-228d-4c53-9dcc-3a8f8b639a9f.png)
</details>

# Discussion
I haven't looked too deeply into this yet, as first I wanted to see whether there was interest in the venture. I would love to hear what the other maintainers' thoughts are regarding exploring this route in a bit more detail. Obviously SIMD implementations will bring with them added complexity, but the performance gains are pretty compelling. In my opinion, the tradeoff is worth it.

CC: @scikit-learn/core-devs

COMMENT:
While thinking about this I came across some links that are interesting to read:
* https://numpy.org/devdocs/reference/simd/index.html
* https://numpy.org/neps/nep-0038-SIMD-optimizations.html

Labels: Enhancement, Needs Decision, cython