Talip7/scikit-learn-issues-multilabel huggingface dataset:
Store spectral embeddings in SpectralClustering

### Describe the workflow you want to enable

Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. `maps_`, to make easier post-processing on the clusters.

### Describe your proposed solution

Optionally return the maps in the [spectral_clustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L194) method with a new parameter:

```
def spectral_clustering(
    affinity,
    *,
    n_clusters=8,
    n_components=None,
    eigen_solver=None,
    random_state=None,
    n_init=10,
    eigen_tol="auto",
    assign_labels="kmeans",
    verbose=False,
    return_maps=False
):
    
    ...
    
    if return_maps:
        return maps, labels
    else:
        return labels
```

Store `maps_` attribute in the `fit` method of the `SpectralClustering` class:

```
self.maps_, self.labels_ = spectral_clustering(
            self.affinity_matrix_,
            n_clusters=self.n_clusters,
            n_components=self.n_components,
            eigen_solver=self.eigen_solver,
            random_state=random_state,
            n_init=self.n_init,
            eigen_tol=self.eigen_tol,
            assign_labels=self.assign_labels,
            verbose=self.verbose,
            return_maps=True
        )
```

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

_No response_

### Additional context

_No response_

COMMENT:
> Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. maps_, to make easier post-processing on the clusters.

@matteo-bastico it would help us decide if you could explain how you would use this.

Labels: New Feature, Needs Info
Store spectral embeddings in SpectralClustering

### Describe the workflow you want to enable

Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. `maps_`, to make easier post-processing on the clusters.

### Describe your proposed solution

Optionally return the maps in the [spectral_clustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L194) method with a new parameter:

```
def spectral_clustering(
    affinity,
    *,
    n_clusters=8,
    n_components=None,
    eigen_solver=None,
    random_state=None,
    n_init=10,
    eigen_tol="auto",
    assign_labels="kmeans",
    verbose=False,
    return_maps=False
):
    
    ...
    
    if return_maps:
        return maps, labels
    else:
        return labels
```

Store `maps_` attribute in the `fit` method of the `SpectralClustering` class:

```
self.maps_, self.labels_ = spectral_clustering(
            self.affinity_matrix_,
            n_clusters=self.n_clusters,
            n_components=self.n_components,
            eigen_solver=self.eigen_solver,
            random_state=random_state,
            n_init=self.n_init,
            eigen_tol=self.eigen_tol,
            assign_labels=self.assign_labels,
            verbose=self.verbose,
            return_maps=True
        )
```

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

_No response_

### Additional context

_No response_

COMMENT:
As a workaround, you may recompute the mapping after fitting `SpectralClustering`:

```python
from sklearn.cluster import SpectralClustering
from sklearn.manifold import spectral_embedding
import numpy as np

X = np.array([[1, 1], [2, 1], [1, 0],
              [4, 7], [3, 5], [3, 6]])
clustering = SpectralClustering(n_clusters=2,
        assign_labels='discretize',
        random_state=0).fit(X)

maps = spectral_embedding(
    clustering.affinity_matrix_,
    n_components=clustering.n_clusters,
    eigen_solver=clustering.eigen_solver,
    random_state=0,
    eigen_tol=clustering.eigen_tol,
    drop_first=False,
)
```

Labels: New Feature, Needs Info
Store spectral embeddings in SpectralClustering

### Describe the workflow you want to enable

Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. `maps_`, to make easier post-processing on the clusters.

### Describe your proposed solution

Optionally return the maps in the [spectral_clustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L194) method with a new parameter:

```
def spectral_clustering(
    affinity,
    *,
    n_clusters=8,
    n_components=None,
    eigen_solver=None,
    random_state=None,
    n_init=10,
    eigen_tol="auto",
    assign_labels="kmeans",
    verbose=False,
    return_maps=False
):
    
    ...
    
    if return_maps:
        return maps, labels
    else:
        return labels
```

Store `maps_` attribute in the `fit` method of the `SpectralClustering` class:

```
self.maps_, self.labels_ = spectral_clustering(
            self.affinity_matrix_,
            n_clusters=self.n_clusters,
            n_components=self.n_components,
            eigen_solver=self.eigen_solver,
            random_state=random_state,
            n_init=self.n_init,
            eigen_tol=self.eigen_tol,
            assign_labels=self.assign_labels,
            verbose=self.verbose,
            return_maps=True
        )
```

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

_No response_

### Additional context

_No response_

COMMENT:
> > Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. maps_, to make easier post-processing on the clusters.
> 
> @matteo-bastico it would help us decide if you could explain how you would use this.

In my case, I want to compute the medoids of the clusters using the distances in the spectral embedding space instead of the original Euclidean space. But there are others applications in which this feature can be useful.

> As a workaround, you may recompute the mapping after fitting `SpectralClustering`:
> 
> ```python
> from sklearn.cluster import SpectralClustering
> from sklearn.manifold import spectral_embedding
> import numpy as np
> 
> X = np.array([[1, 1], [2, 1], [1, 0],
>               [4, 7], [3, 5], [3, 6]])
> clustering = SpectralClustering(n_clusters=2,
>         assign_labels='discretize',
>         random_state=0).fit(X)
> 
> maps = spectral_embedding(
>     clustering.affinity_matrix_,
>     n_components=clustering.n_clusters,
>     eigen_solver=clustering.eigen_solver,
>     random_state=0,
>     eigen_tol=clustering.eigen_tol,
>     drop_first=False,
> )
> ```

Thank you, as a workaround it works but the spectral embeddings are computed twice and for large matrices it is time consuming.

Labels: New Feature, Needs Info
Store spectral embeddings in SpectralClustering

### Describe the workflow you want to enable

Save the spectral embeddings used for clustering in the [SpectralClustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L394) class and make them accessible through an attribute, e.g. `maps_`, to make easier post-processing on the clusters.

### Describe your proposed solution

Optionally return the maps in the [spectral_clustering](https://github.com/scikit-learn/scikit-learn/blob/9aaed4987/sklearn/cluster/_spectral.py#L194) method with a new parameter:

```
def spectral_clustering(
    affinity,
    *,
    n_clusters=8,
    n_components=None,
    eigen_solver=None,
    random_state=None,
    n_init=10,
    eigen_tol="auto",
    assign_labels="kmeans",
    verbose=False,
    return_maps=False
):
    
    ...
    
    if return_maps:
        return maps, labels
    else:
        return labels
```

Store `maps_` attribute in the `fit` method of the `SpectralClustering` class:

```
self.maps_, self.labels_ = spectral_clustering(
            self.affinity_matrix_,
            n_clusters=self.n_clusters,
            n_components=self.n_components,
            eigen_solver=self.eigen_solver,
            random_state=random_state,
            n_init=self.n_init,
            eigen_tol=self.eigen_tol,
            assign_labels=self.assign_labels,
            verbose=self.verbose,
            return_maps=True
        )
```

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

_No response_

### Additional context

_No response_

COMMENT:
There is an existing work-around and it's unlikely this is at the top of our priority in the foreseeable future, so I am going to close this one.

Happy to reopen if the situation changes significantly.

Labels: New Feature, Needs Info
Typo in HistGradientBoosting documentation | no_interaction should be no_interactions

### Describe the issue linked to the documentation

In documentation, the `interaction_cst` field of [HistGradientBoostingRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html) mentions `no_interaction` as an allowed value. This throws an error, as it needs to be `no_interactions`.

Same thing in `HistGradientBoostingClassifier`

### Suggest a potential alternative/fix

`no_interaction` -> `no_interactions`

COMMENT:
/take

Labels: Documentation, Needs Triage
Typo in HistGradientBoosting documentation | no_interaction should be no_interactions

### Describe the issue linked to the documentation

In documentation, the `interaction_cst` field of [HistGradientBoostingRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html) mentions `no_interaction` as an allowed value. This throws an error, as it needs to be `no_interactions`.

Same thing in `HistGradientBoostingClassifier`

### Suggest a potential alternative/fix

`no_interaction` -> `no_interactions`

COMMENT:
Solved in PR #26057

Labels: Documentation, Needs Triage
Typo in HistGradientBoosting documentation | no_interaction should be no_interactions

### Describe the issue linked to the documentation

In documentation, the `interaction_cst` field of [HistGradientBoostingRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html) mentions `no_interaction` as an allowed value. This throws an error, as it needs to be `no_interactions`.

Same thing in `HistGradientBoostingClassifier`

### Suggest a potential alternative/fix

`no_interaction` -> `no_interactions`

COMMENT:
Looks like this can be closed as https://github.com/scikit-learn/scikit-learn/pull/26057 was merged, thanks @ogencoglu and @ChVeen

Labels: Documentation, Needs Triage
Implementation of an additional patch extraction strategy.

### Describe the workflow you want to enable

I think it would be valuable to add a function that extracts non-overlapping patches from an image. This alternative patch extraction strategy might be more suitable for certain use cases where overlapping patches are not desired or could lead to redundant information. I propose adding the following function to the codebase:



With this new function, you could extract non-overlapping patches from an image. This would be a valuable addition to the existing code, as it provides an alternative patch extraction strategy that might be more suitable for certain use cases.

### Describe your proposed solution

Here's an example of how you could implement this new function:
def extract_non_overlapping_patches_2d(image, patch_size):
    """Extract non-overlapping patches from a 2D image.
    
    Parameters
    ----------
    image : ndarray of shape (image_height, image_width) or \
        (image_height, image_width, n_channels)
        The original image data. For color images, the last dimension specifies
        the channel: a RGB image would have `n_channels=3`.
    patch_size : tuple of int (patch_height, patch_width)
        The dimensions of one patch.

    Returns
    -------
    patches : array of shape (n_patches, patch_height, patch_width) or \
        (n_patches, patch_height, patch_width, n_channels)
        The collection of non-overlapping patches extracted from the image.
    """
    i_h, i_w = image.shape[:2]
    p_h, p_w = patch_size

    if p_h > i_h or p_w > i_w:
        raise ValueError("Patch dimensions should be smaller than the image dimensions.")

    n_rows = i_h // p_h
    n_cols = i_w // p_w
    n_patches = n_rows * n_cols

    image = image[:n_rows * p_h, :n_cols * p_w]  # Crop the image to fit the non-overlapping patches
    image = image.reshape((i_h, i_w, -1))
    n_colors = image.shape[-1]

    patches = np.empty((n_patches, p_h, p_w, n_colors))

    patch_idx = 0
    for row in range(n_rows):
        for col in range(n_cols):
            patch = image[row * p_h:(row + 1) * p_h, col * p_w:(col + 1) * p_w]
            patches[patch_idx] = patch
            patch_idx += 1

    if patches.shape[-1] == 1:
        return patches.reshape((n_patches, p_h, p_w))
    else:
        return patches

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

_No response_

### Additional context

_No response_

COMMENT:
Overall, I am -1 on adding more functions to `feature_extraction.image`. In the past 5 years, most of the advancements around ML+images are in pre-trained models and deep learning which is out of scope for scikit-learn.

Labels: New Feature, module:feature_extraction, Needs Decision - Include Feature
Implementation of an additional patch extraction strategy.

### Describe the workflow you want to enable

I think it would be valuable to add a function that extracts non-overlapping patches from an image. This alternative patch extraction strategy might be more suitable for certain use cases where overlapping patches are not desired or could lead to redundant information. I propose adding the following function to the codebase:



With this new function, you could extract non-overlapping patches from an image. This would be a valuable addition to the existing code, as it provides an alternative patch extraction strategy that might be more suitable for certain use cases.

### Describe your proposed solution

Here's an example of how you could implement this new function:
def extract_non_overlapping_patches_2d(image, patch_size):
    """Extract non-overlapping patches from a 2D image.
    
    Parameters
    ----------
    image : ndarray of shape (image_height, image_width) or \
        (image_height, image_width, n_channels)
        The original image data. For color images, the last dimension specifies
        the channel: a RGB image would have `n_channels=3`.
    patch_size : tuple of int (patch_height, patch_width)
        The dimensions of one patch.

    Returns
    -------
    patches : array of shape (n_patches, patch_height, patch_width) or \
        (n_patches, patch_height, patch_width, n_channels)
        The collection of non-overlapping patches extracted from the image.
    """
    i_h, i_w = image.shape[:2]
    p_h, p_w = patch_size

    if p_h > i_h or p_w > i_w:
        raise ValueError("Patch dimensions should be smaller than the image dimensions.")

    n_rows = i_h // p_h
    n_cols = i_w // p_w
    n_patches = n_rows * n_cols

    image = image[:n_rows * p_h, :n_cols * p_w]  # Crop the image to fit the non-overlapping patches
    image = image.reshape((i_h, i_w, -1))
    n_colors = image.shape[-1]

    patches = np.empty((n_patches, p_h, p_w, n_colors))

    patch_idx = 0
    for row in range(n_rows):
        for col in range(n_cols):
            patch = image[row * p_h:(row + 1) * p_h, col * p_w:(col + 1) * p_w]
            patches[patch_idx] = patch
            patch_idx += 1

    if patches.shape[-1] == 1:
        return patches.reshape((n_patches, p_h, p_w))
    else:
        return patches

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

_No response_

### Additional context

_No response_

COMMENT:
What Thomas said. Maybe there is something like this in https://scikit-image.org/ already? For people who don't want to do deep learning scikit-image is probably the tool to learn about/use for feature extraction/image processing. Instead of adding more tools to scikit-learn.

Labels: New Feature, module:feature_extraction, Needs Decision - Include Feature
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:
Hi, which category do you think that project is going to fall into on that webpage? I can add that project to the documentation if I am okay to take this issue. 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:
Hello, I think the correct category is [Domain specific packages](https://scikit-learn.org/stable/related_projects.html#domain-specific-packages), and the definition:

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...).

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:
Happy to review a PR adding this where `sktime` is also mentioned.

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:
/take

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:
Review for the PR please

Labels: Documentation