Repository: scikit-learn/scikit-learn
File: sklearn/linear_model/tests/test_coordinate_descent.py (Python)

Code before:
    assert_allclose(reg.coef_, coef, rtol=1e-6)
    if fit_intercept:
        assert_allclose(reg.intercept_, intercept)


@pytest.mark.parametrize("X_is_sparse", [False, True])
@pytest.mark.parametrize("fit_intercept", [False, True])
@pytest.mark.parametrize("positive", [False, True])
@pytest.mark.parametrize("sample_weight", [np.array([10, 1, 10, 1]), None])
def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight):
    X = np.array([[3.0, -1.0], [2.0, -5.0], [5.0, -3.0], [1.0, -4.0]])
    beta = np.array([1, -2])
    y = X @ beta
    config = dict(fit_intercept=fit_intercept, positive=positive)

    # Need non-zero OLS coef to test alpha_max
    ols_coef = LinearRegression(**config).fit(X, y).coef_
    assert not np.allclose(ols_coef, 0), f"Test data gives zero OLS coef_ for {config=}"

    # alpha_max needs to be sensitive to positive
    flip_positive_ols_coef = (
        LinearRegression(**{**config, "positive": not positive}).fit(X, y).coef_
    )
    assert not np.isclose(max(ols_coef), max(flip_positive_ols_coef)), (
        f"Test data cannot distinguish alpha_max between positive=True and False "
        f"for {config=}"
    )

    if X_is_sparse:
        X = sparse.csc_matrix(X)
    # Test alpha_max makes coefs zero.
    reg = ElasticNetCV(alphas=1, cv=2, eps=1, **config)
    reg.fit(X, y, sample_weight=sample_weight)
    assert_allclose(reg.coef_, 0, atol=1e-5)
    alpha_max = reg.alpha_
    # Test smaller alpha makes coefs nonzero.
    reg = ElasticNet(alpha=0.99 * alpha_max, tol=1e-8, **config)
    reg.fit(X, y, sample_weight=sample_weight)
    assert_array_less(1e-3, np.max(np.abs(reg.coef_)))


@pytest.mark.parametrize("estimator", [ElasticNetCV, LassoCV])
def test_linear_models_cv_fit_with_loky(estimator):
    # LinearModelsCV.fit performs operations on fancy-indexed memmapped
    # data when using the loky backend, causing an error due to unexpected
    # behavior of fancy indexing of read-only memmaps (cf. numpy#14132).

    # Create a problem sufficiently large to cause memmapping (1MB).
    # Unfortunately the scikit-learn and joblib APIs do not make it possible to
    # change the max_nbyte of the inner Parallel call.
    X, y = make_regression(int(1e6) // 8 + 1, 1)

Review comment (suggestion):
```suggestion
if positive:
    # Make sure that flipping signs makes a difference, i.e. test the meaningfulness of the test data.
    X[:, -1] *= -1
    reg = ElasticNetCV(alphas=1, cv=2, eps=1, **config)
    assert alpha_max < reg.alpha_

```

Code after:
    if fit_intercept:
        assert_allclose(reg.intercept_, intercept)


@pytest.mark.parametrize("X_is_sparse", [False, True])
@pytest.mark.parametrize("fit_intercept", [False, True])
@pytest.mark.parametrize("positive", [False, True])
@pytest.mark.parametrize("sample_weight", [np.array([1, 10, 1, 10]), None])
def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight):
    X = np.array([[3.0, -1.0], [2.0, -5.0], [5.0, -3.0], [1.0, -4.0]])
    beta = np.array([1, -2])
    y = X @ beta
    params = dict(fit_intercept=fit_intercept, positive=positive)

    if X_is_sparse:
        X = sparse.csc_matrix(X)
    # Test alpha_max makes coefs zero.
    reg = ElasticNetCV(alphas=1, cv=2, eps=1, **params)
    reg.fit(X, y, sample_weight=sample_weight)
    assert_allclose(reg.coef_, 0, atol=1e-5)
    alpha_max = reg.alpha_
    # Test smaller alpha makes coefs nonzero.
    reg = ElasticNet(alpha=0.99 * alpha_max, tol=1e-8, **params)
    reg.fit(X, y, sample_weight=sample_weight)
    assert_array_less(1e-3, np.max(np.abs(reg.coef_)))

    if positive:
        # Make sure that the positive constraint changes alpha_max,
        # i.e. test the meaningfulness of the test data.
        not_positive_alpha_max = (
            ElasticNetCV(alphas=1, cv=2, eps=1, **{**params, "positive": not positive})
            .fit(X, y, sample_weight=sample_weight)
            .alpha_
        )
        assert not np.isclose(alpha_max, not_positive_alpha_max), (
            "Test data cannot distinguish alpha_max between positive=True and False."
        )


@pytest.mark.parametrize("estimator", [ElasticNetCV, LassoCV])
def test_linear_models_cv_fit_with_loky(estimator):
    # LinearModelsCV.fit performs operations on fancy-indexed memmapped
    # data when using the loky backend, causing an error due to unexpected
    # behavior of fancy indexing of read-only memmaps (cf. numpy#14132).

    # Create a problem sufficiently large to cause memmapping (1MB).
    # Unfortunately the scikit-learn and joblib APIs do not make it possible to
    # change the max_nbyte of the inner Parallel call.
    X, y = make_regression(int(1e6) // 8 + 1, 1)
    assert X.nbytes > 1e6  # 1 MB
    with joblib.parallel_backend("loky"):