ronantakizawa/codereview-bench huggingface dataset:
Repository: scikit-learn/scikit-learn
File: sklearn/linear_model/tests/test_sgd.py (Python)

Code before:
import pickle
import warnings
from unittest.mock import Mock

import joblib
import numpy as np
import pytest
import scipy.sparse as sp
from scipy.optimize import minimize

from sklearn import datasets, linear_model, metrics
from sklearn.base import clone, is_classifier
from sklearn.datasets._samples_generator import make_blobs
from sklearn.exceptions import ConvergenceWarning
from sklearn.kernel_approximation import Nystroem
from sklearn.linear_model import _sgd_fast as sgd_fast
from sklearn.linear_model import _stochastic_gradient
from sklearn.model_selection import (
    RandomizedSearchCV,
    ShuffleSplit,
    StratifiedShuffleSplit,
)
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import LabelEncoder, MinMaxScaler, StandardScaler, scale
from sklearn.svm import OneClassSVM
from sklearn.utils import get_tags
from sklearn.utils._testing import (
    assert_allclose,
    assert_almost_equal,
    assert_array_almost_equal,
    assert_array_equal,
)


def _update_kwargs(kwargs):
    if "random_state" not in kwargs:
        kwargs["random_state"] = 42


Review comment (suggestion):
```suggestion
from sklearn.datasets import make_blobs
```

Code after:
import pickle
import warnings
from unittest.mock import Mock

import joblib
import numpy as np
import pytest
import scipy.sparse as sp
from scipy.optimize import minimize

from sklearn import datasets, linear_model, metrics
from sklearn.base import clone, is_classifier
from sklearn.datasets import make_blobs
from sklearn.exceptions import ConvergenceWarning
from sklearn.kernel_approximation import Nystroem
from sklearn.linear_model import _sgd_fast as sgd_fast
from sklearn.linear_model import _stochastic_gradient
from sklearn.model_selection import (
    RandomizedSearchCV,
    ShuffleSplit,
    StratifiedShuffleSplit,
)
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import LabelEncoder, MinMaxScaler, StandardScaler, scale
from sklearn.svm import OneClassSVM
from sklearn.utils import get_tags
from sklearn.utils._testing import (
    assert_allclose,
    assert_almost_equal,
    assert_array_almost_equal,
    assert_array_equal,
)


def _update_kwargs(kwargs):
    if "random_state" not in kwargs:
        kwargs["random_state"] = 42
Repository: scikit-learn/scikit-learn
File: sklearn/linear_model/tests/test_sgd.py (Python)

Code before:
    """Check that SGDOneClassSVM has the correct estimator type.

    Non-regression test for if the mixin was not on the left.
    """
    sgd_ocsvm = SGDOneClassSVM()
    assert get_tags(sgd_ocsvm).estimator_type == "outlier_detector"


def test_sgd_one_class_svm_formulation_with_scipy_minimize():
    """
    Test that the objective formulation of `SGDOneClassSVM` is appropriate by
    checking that the converged parameters are close enough to the ones output
    by scipy's `minimize` function using "L-BFGS-B".
    """
    nu = 0.5
    hinge_threshold = 1.0
    n_samples, n_features = 300, 3
    random_seed = 42

    def objective(w, X, y, alpha):
        weights = w[:-1]
        intercept = w[-1]
        p = X @ weights + intercept
        z = p * y
        n_samples = X.shape[0]
        sum_loss = np.maximum(hinge_threshold - z, 0.0).sum()
        avg_loss = sum_loss / n_samples
        reg = 0.5 * alpha * weights @ weights
        obj = avg_loss + reg + intercept * alpha
        return obj

    X, _ = make_blobs(
        n_samples=n_samples,
        n_features=n_features,
        random_state=random_seed,
    )
    y = np.ones(n_samples, dtype=X.dtype)
    w0 = np.zeros(n_features + 1)
    scipy_output = minimize(
        objective,
        w0,
        method="Nelder-Mead",
        args=(X, y, nu),
        options={"maxiter": 1000},
    )
    w_out = scipy_output.x
    expected_coef = w_out[:-1]
    expected_offset = 1 - w_out[-1]

    model = SGDOneClassSVM(
        nu=nu,

Review comment (suggestion):
```suggestion
        avg_loss = np.mean(np.maximum(hinge_threshold - z, 0.0))
```

Code after:
        obj = avg_loss + reg + intercept * alpha
        return obj

    X, _ = make_blobs(
        n_samples=n_samples,
        n_features=n_features,
        random_state=random_seed,
    )
    y = np.ones(n_samples, dtype=X.dtype)
    w0 = np.zeros(n_features + 1)
    scipy_output = minimize(
        objective,
        w0,
        method="Nelder-Mead",
        args=(X, y, nu),
        options={"maxiter": 1000},
    )
    w_out = scipy_output.x
    expected_coef = w_out[:-1]
    expected_offset = 1 - w_out[-1]

    model = SGDOneClassSVM(
        nu=nu,
        learning_rate="constant",
        max_iter=4000,
        tol=None,
        eta0=1e-4,
        random_state=random_seed,
    )
    model.fit(X, y)

    assert_allclose(model.coef_, expected_coef, rtol=5e-3)
    assert_allclose(model.offset_, expected_offset, rtol=1e-2)
Repository: scikit-learn/scikit-learn
File: sklearn/linear_model/tests/test_sgd.py (Python)

Code before:

    X_32 = X.astype(dtype=np.float32)
    Y_32 = np.array(Y, dtype=np.float32)

    sgd_64 = SGDEstimator(max_iter=22, shuffle=False)
    sgd_64.fit(X_64, Y_64)

    sgd_32 = SGDEstimator(max_iter=22, shuffle=False)
    sgd_32.fit(X_32, Y_32)

    assert_allclose(sgd_64.coef_, sgd_32.coef_)


def test_sgd_one_class_svm_estimator_type():
    """Check that SGDOneClassSVM has the correct estimator type.

    Non-regression test for if the mixin was not on the left.
    """
    sgd_ocsvm = SGDOneClassSVM()
    assert get_tags(sgd_ocsvm).estimator_type == "outlier_detector"


def test_sgd_one_class_svm_formulation_with_scipy_minimize():
    """
    Test that `SGDOneClassSVM` minimizes the correct objective function.
    """
    nu = 0.5
    hinge_threshold = 1.0
    n_samples, n_features = 300, 3
    random_seed = 42

    def objective(w, X, y, alpha):
        weights = w[:-1]
        intercept = w[-1]
        p = X @ weights + intercept
        z = p * y
        avg_loss = np.mean(np.maximum(hinge_threshold - z, 0.0))
        reg = 0.5 * alpha * weights @ weights
        obj = avg_loss + reg + intercept * alpha
        return obj

    X, _ = make_blobs(
        n_samples=n_samples,
        n_features=n_features,
        random_state=random_seed,
    )
    y = np.ones(n_samples, dtype=X.dtype)
    w0 = np.zeros(n_features + 1)
    scipy_output = minimize(
        objective,
        w0,

Review comment (suggestion):
```suggestion
    """Test that SGDOneClassSVM minimizes the correct objective function."""
```

Code after:

    X_32 = X.astype(dtype=np.float32)
    Y_32 = np.array(Y, dtype=np.float32)

    sgd_64 = SGDEstimator(max_iter=22, shuffle=False)
    sgd_64.fit(X_64, Y_64)

    sgd_32 = SGDEstimator(max_iter=22, shuffle=False)
    sgd_32.fit(X_32, Y_32)

    assert_allclose(sgd_64.coef_, sgd_32.coef_)


def test_sgd_one_class_svm_estimator_type():
    """Check that SGDOneClassSVM has the correct estimator type.

    Non-regression test for if the mixin was not on the left.
    """
    sgd_ocsvm = SGDOneClassSVM()
    assert get_tags(sgd_ocsvm).estimator_type == "outlier_detector"


def test_sgd_one_class_svm_formulation_with_scipy_minimize():
    """Test that SGDOneClassSVM minimizes the correct objective function."""
    nu = 0.5
    hinge_threshold = 1.0
    n_samples, n_features = 300, 3
    random_seed = 42

    def objective(w, X, y, alpha):
        weights = w[:-1]
        intercept = w[-1]
        p = X @ weights + intercept
        z = p * y
        avg_loss = np.mean(np.maximum(hinge_threshold - z, 0.0))
        reg = 0.5 * alpha * weights @ weights
        obj = avg_loss + reg + intercept * alpha
        return obj

    X, _ = make_blobs(
        n_samples=n_samples,
        n_features=n_features,
        random_state=random_seed,
    )
    y = np.ones(n_samples, dtype=X.dtype)
    w0 = np.zeros(n_features + 1)
    scipy_output = minimize(
        objective,
        w0,
        method="Nelder-Mead",
        args=(X, y, nu),
Repository: scikit-learn/scikit-learn
File: sklearn/tests/test_min_dependencies_readme.py (Python)

Code before:
"""Tests for the minimum dependencies in README.rst and pyproject.toml"""

import os
import re
import tomllib
from collections import defaultdict
from pathlib import Path

import pytest

import sklearn
from sklearn._min_dependencies import dependent_packages
from sklearn.utils.fixes import parse_version

# minimal dependencies and pyproject definitions for testing the pyproject tests

MIN_DEPENDENT_PACKAGES = {
    "joblib": ("1.3.0", "install"),
    "scipy": ("1.10.0", "build, install"),
}

MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """
[project]
dependencies = ["joblib>=1.3.0,<2.0", "scipy==1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0,<1.19.0"]
install = ["joblib>=1.3.0,<2.0", "scipy==1.10.0"]
[build-system]
requires = ["scipy>=1.10.0,<1.19.0"]
"""


def test_min_dependencies_readme():
    # Test that the minimum dependencies in the README.rst file are
    # consistent with the minimum dependencies defined at the file:
    # sklearn/_min_dependencies.py

    pattern = re.compile(
        r"\.\. \|"
        r"([A-Za-z-]+)"
        r"MinVersion\| replace::"
        r"( [0-9]+\.[0-9]+(\.[0-9]+)?)"

Review comment (suggestion):
I think we could use more explicit variable names to convey that those are not expected to match the currently used version numbers.

```suggestion
EXAMPLE_MIN_DEPENDENT_PACKAGES = {
```

Code after:
"""Tests for the minimum dependencies in README.rst and pyproject.toml"""

import os
import re
import tomllib
from collections import defaultdict
from pathlib import Path

import pytest

import sklearn
from sklearn._min_dependencies import dependent_packages
from sklearn.utils.fixes import parse_version

# minimal dependencies and pyproject definitions for testing the pyproject tests

TOY_MIN_DEPENDENCIES_PY_INFO = {
    "joblib": ("1.3.0", "install"),
    "scipy": ("1.10.0", "build, install"),
    "conda-lock": ("3.0.1", "maintenance"),
}

TOY_MATCHING_PYPROJECT_SECTIONS = """
[project]
dependencies = ["joblib>=1.3.0", "scipy>=1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0"]
install = ["joblib>=1.3.0", "scipy>=1.10.0"]
maintenance = ["conda-lock==3.0.1"]
[build-system]
requires = ["scipy>=1.10.0"]
"""

TOY_MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """
[project]
dependencies = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0,<1.19.0"]
install = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"]
maintenance = ["conda-lock==3.0.1"]
[build-system]
requires = ["scipy>=1.10.0,<1.19.0"]
Repository: scikit-learn/scikit-learn
File: sklearn/tests/test_min_dependencies_readme.py (Python)

Code before:
"""Tests for the minimum dependencies in README.rst and pyproject.toml"""

import os
import re
import tomllib
from collections import defaultdict
from pathlib import Path

import pytest

import sklearn
from sklearn._min_dependencies import dependent_packages
from sklearn.utils.fixes import parse_version

# minimal dependencies and pyproject definitions for testing the pyproject tests

MIN_DEPENDENT_PACKAGES = {
    "joblib": ("1.3.0", "install"),
    "scipy": ("1.10.0", "build, install"),
}

MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """
[project]
dependencies = ["joblib>=1.3.0,<2.0", "scipy==1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0,<1.19.0"]
install = ["joblib>=1.3.0,<2.0", "scipy==1.10.0"]
[build-system]
requires = ["scipy>=1.10.0,<1.19.0"]
"""


def test_min_dependencies_readme():
    # Test that the minimum dependencies in the README.rst file are
    # consistent with the minimum dependencies defined at the file:
    # sklearn/_min_dependencies.py

    pattern = re.compile(
        r"\.\. \|"
        r"([A-Za-z-]+)"
        r"MinVersion\| replace::"
        r"( [0-9]+\.[0-9]+(\.[0-9]+)?)"
    )

    readme_path = Path(sklearn.__file__).parent.parent
    readme_file = readme_path / "README.rst"


Review comment (suggestion):
```suggestion
EXAMPLE_EXPECTED_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """
```

Code after:
"""Tests for the minimum dependencies in README.rst and pyproject.toml"""

import os
import re
import tomllib
from collections import defaultdict
from pathlib import Path

import pytest

import sklearn
from sklearn._min_dependencies import dependent_packages
from sklearn.utils.fixes import parse_version

# minimal dependencies and pyproject definitions for testing the pyproject tests

TOY_MIN_DEPENDENCIES_PY_INFO = {
    "joblib": ("1.3.0", "install"),
    "scipy": ("1.10.0", "build, install"),
    "conda-lock": ("3.0.1", "maintenance"),
}

TOY_MATCHING_PYPROJECT_SECTIONS = """
[project]
dependencies = ["joblib>=1.3.0", "scipy>=1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0"]
install = ["joblib>=1.3.0", "scipy>=1.10.0"]
maintenance = ["conda-lock==3.0.1"]
[build-system]
requires = ["scipy>=1.10.0"]
"""

TOY_MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """
[project]
dependencies = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"]
[project.optional-dependencies]
build = ["scipy>=1.10.0,<1.19.0"]
install = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"]
maintenance = ["conda-lock==3.0.1"]
[build-system]
requires = ["scipy>=1.10.0,<1.19.0"]
"""

TOY_WRONG_SYMBOL_PYPROJECT_SECTIONS = """
[project]
dependencies = ["scipy<1.10.0"]
Repository: scikit-learn/scikit-learn
File: sklearn/utils/_array_api.py (Python)

Code before:
    ----------
    *arrays : array objects
        Array objects.

    remove_none : bool, default=True
        Whether to ignore None objects passed in arrays.

    remove_types : tuple or list, default=(str,)
        Types to ignore in the arrays.

    Returns
    -------
    filtered_arrays : list
        List of arrays filtered as requested. An empty list is returned if no input
        passes the filters.
    """
    filtered_arrays = []
    remove_types = tuple(remove_types)
    for array in arrays:
        if remove_none and array is None:
            continue
        if isinstance(array, remove_types):
            continue
        if sp.issparse(array):
            continue
        if _is_pandas_df_or_series(array):
            continue
        filtered_arrays.append(array)

    return filtered_arrays


def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None):
    """Get namespace of arrays.

    Introspect `arrays` arguments and return their common Array API compatible
    namespace object, if any.

    Note that sparse arrays are filtered by default.

    See: https://numpy.org/neps/nep-0047-array-api-standard.html

    If `arrays` are regular numpy arrays, `array_api_compat.numpy` is returned instead.

    Namespace support is not enabled by default. To enabled it call:

      sklearn.set_config(array_api_dispatch=True)

    or:

      with sklearn.config_context(array_api_dispatch=True):

Review comment (suggestion):
```suggestion
        if _is_any_supported_df_or_series(array):
```

Code after:
    Returns
    -------
    filtered_arrays : list
        List of arrays filtered as requested. An empty list is returned if no input
        passes the filters.
    """
    filtered_arrays = []
    remove_types = tuple(remove_types)
    for array in arrays:
        if remove_none and array is None:
            continue
        if isinstance(array, remove_types):
            continue
        if sp.issparse(array):
            continue
        if is_df_or_series(array):
            continue
        filtered_arrays.append(array)

    return filtered_arrays


def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None):
    """Get namespace of arrays.

    Introspect `arrays` arguments and return their common Array API compatible
    namespace object, if any.

    Note that sparse arrays are filtered by default.

    See: https://numpy.org/neps/nep-0047-array-api-standard.html

    If `arrays` are regular numpy arrays, `array_api_compat.numpy` is returned instead.

    Namespace support is not enabled by default. To enabled it call:

      sklearn.set_config(array_api_dispatch=True)

    or:

      with sklearn.config_context(array_api_dispatch=True):
          # your code here

    Otherwise `array_api_compat.numpy` is
    always returned irrespective of the fact that arrays implement the
    `__array_namespace__` protocol or not.

    Note that if no arrays pass the set filters, ``_NUMPY_API_WRAPPER_INSTANCE, False``
    is returned.

    Parameters
Repository: scikit-learn/scikit-learn
File: sklearn/utils/_array_api.py (Python)

Code before:
    )
    valid_float_dtypes = []
    for dtype_key in ("float64", "float32"):
        if dtype_key in dtypes_dict:
            valid_float_dtypes.append(dtypes_dict[dtype_key])

    if hasattr(xp, "float16"):
        valid_float_dtypes.append(xp.float16)

    return tuple(valid_float_dtypes)


def _remove_non_arrays(*arrays, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT):
    """Filter arrays to exclude None and/or specific types.

    Sparse arrays are always filtered out.

    Parameters
    ----------
    *arrays : array objects
        Array objects.

    remove_none : bool, default=True
        Whether to ignore None objects passed in arrays.

    remove_types : tuple or list, (str, list, tuple)
        Types to ignore in the arrays.

    Returns
    -------
    filtered_arrays : list
        List of arrays filtered as requested. An empty list is returned if no input
        passes the filters.
    """
    filtered_arrays = []
    remove_types = tuple(remove_types)
    for array in arrays:
        if remove_none and array is None:
            continue
        if isinstance(array, remove_types):
            continue
        if sp.issparse(array):
            continue
        if is_df_or_series(array):
            continue
        filtered_arrays.append(array)

    return filtered_arrays


def _unwrap_memoryviewslices(*arrays):

Review comment (suggestion):
```suggestion
    remove_types : tuple or list, default=(str, list, tuple)
```

Code after:
    )
    valid_float_dtypes = []
    for dtype_key in ("float64", "float32"):
        if dtype_key in dtypes_dict:
            valid_float_dtypes.append(dtypes_dict[dtype_key])

    if hasattr(xp, "float16"):
        valid_float_dtypes.append(xp.float16)

    return tuple(valid_float_dtypes)


def _remove_non_arrays(*arrays, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT):
    """Filter arrays to exclude None and/or specific types.

    Sparse arrays are always filtered out.

    Parameters
    ----------
    *arrays : array objects
        Array objects.

    remove_none : bool, default=True
        Whether to ignore None objects passed in arrays.

    remove_types : tuple or list, default=(str, list, tuple)
        Types to ignore in the arrays.

    Returns
    -------
    filtered_arrays : list
        List of arrays filtered as requested. An empty list is returned if no input
        passes the filters.
    """
    filtered_arrays = []
    remove_types = tuple(remove_types)
    for array in arrays:
        if remove_none and array is None:
            continue
        if isinstance(array, remove_types):
            continue
        if sp.issparse(array):
            continue
        if is_df_or_series(array):
            continue
        filtered_arrays.append(array)

    return filtered_arrays


def _unwrap_memoryviewslices(*arrays):
Repository: scikit-learn/scikit-learn
File: sklearn/metrics/_base.py (Python)

Code before:
"""
Common code for all metrics.

"""

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

from itertools import combinations

import numpy as np

import sklearn.externals.array_api_extra as xpx
from sklearn.utils import check_array, check_consistent_length
from sklearn.utils._array_api import _ravel, get_namespace_and_device
from sklearn.utils.multiclass import type_of_target


def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight=None):
    """Average a binary metric for multilabel classification.

    Parameters
    ----------
    binary_metric : callable, returns shape [n_classes]
        The binary metric function to use.

    y_true : array, shape = [n_samples] or [n_samples, n_classes]
        True binary labels in binary label indicators.

    y_score : array, shape = [n_samples] or [n_samples, n_classes]
        Target scores, can either be probability estimates of the positive
        class, confidence values, or binary decisions.

    average : {None, 'micro', 'macro', 'samples', 'weighted'}, default='macro'
        If ``None``, the scores for each class are returned. Otherwise,
        this determines the type of averaging performed on the data:

        ``'micro'``:
            Calculate metrics globally by considering each element of the label
            indicator matrix as a label.

Review comment (suggestion):
```suggestion
from sklearn.utils._array_api import _ravel, get_namespace_and_device, xpx
```

Code after:
"""
Common code for all metrics.

"""

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

from itertools import combinations

import numpy as np

import sklearn.externals.array_api_extra as xpx
from sklearn.utils import check_array, check_consistent_length
from sklearn.utils._array_api import _average, _ravel, get_namespace_and_device
from sklearn.utils.multiclass import type_of_target


def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight=None):
    """Average a binary metric for multilabel classification.

    Parameters
    ----------
    binary_metric : callable, returns shape [n_classes]
        The binary metric function to use.

    y_true : array, shape = [n_samples] or [n_samples, n_classes]
        True binary labels in binary label indicators.

    y_score : array, shape = [n_samples] or [n_samples, n_classes]
        Target scores, can either be probability estimates of the positive
        class, confidence values, or binary decisions.

    average : {None, 'micro', 'macro', 'samples', 'weighted'}, default='macro'
        If ``None``, the scores for each class are returned. Otherwise,
        this determines the type of averaging performed on the data:

        ``'micro'``:
            Calculate metrics globally by considering each element of the label
            indicator matrix as a label.