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

Code before:
    dec_ocsvm = clf.decision_function(X_test).reshape(1, -1)

    # SGDOneClassSVM using kernel approximation
    max_iter = 15
    transform = Nystroem(gamma=gamma, random_state=random_state)
    clf_sgd = SGDOneClassSVM(
        nu=nu,
        shuffle=True,
        fit_intercept=True,
        max_iter=max_iter,
        random_state=random_state,
        tol=None,
    )
    pipe_sgd = make_pipeline(transform, clf_sgd)
    pipe_sgd.fit(X_train)
    y_pred_sgdocsvm = pipe_sgd.predict(X_test)
    dec_sgdocsvm = pipe_sgd.decision_function(X_test).reshape(1, -1)

    assert np.mean(y_pred_sgdocsvm == y_pred_ocsvm) >= 0.99
    corrcoef = np.corrcoef(np.concatenate((dec_ocsvm, dec_sgdocsvm)))[0, 1]
    assert corrcoef >= 0.9


def test_sgd_oneclass_convergence():
    # Check that the optimization does not end early,
    # that the stopping criterion is working
    for nu in [0.1, 0.5, 0.9]:
        # no need for large max_iter
        model = SGDOneClassSVM(
            nu=nu, max_iter=100, tol=1e-3, learning_rate="constant", eta0=1e-3
        )
        model.fit(iris.data)
        # 6 is the minimal number of iterations, after which optimization can stop
        assert model.n_iter_ > 6


def test_sgd_oneclass_vs_linear_oneclass():
    # Test convergence vs. liblinear OCSVM with kernel="linear"
    for nu in [0.1, 0.5, 0.9]:
        # allow enough iterations, small dataset
        model = SGDOneClassSVM(
            nu=nu, max_iter=20000, tol=None, learning_rate="constant", eta0=1e-3
        )
        model_ref = OneClassSVM(kernel="linear", nu=nu, tol=1e-6)  # reference model
        model.fit(iris.data)
        model_ref.fit(iris.data)

        preds = model.predict(iris.data)
        dec_fn = model.decision_function(iris.data)

        preds_ref = model_ref.predict(iris.data)

Review comment (suggestion):
```suggestion
    # Check that the optimization does not end early and that the stopping criterion
    # is working. Non-regression test for 30027
```

Code after:
    dec_ocsvm = clf.decision_function(X_test).reshape(1, -1)

    # SGDOneClassSVM using kernel approximation
    max_iter = 15
    transform = Nystroem(gamma=gamma, random_state=random_state)
    clf_sgd = SGDOneClassSVM(
        nu=nu,
        shuffle=True,
        fit_intercept=True,
        max_iter=max_iter,
        random_state=random_state,
        tol=None,
    )
    pipe_sgd = make_pipeline(transform, clf_sgd)
    pipe_sgd.fit(X_train)
    y_pred_sgdocsvm = pipe_sgd.predict(X_test)
    dec_sgdocsvm = pipe_sgd.decision_function(X_test).reshape(1, -1)

    assert np.mean(y_pred_sgdocsvm == y_pred_ocsvm) >= 0.99
    corrcoef = np.corrcoef(np.concatenate((dec_ocsvm, dec_sgdocsvm)))[0, 1]
    assert corrcoef >= 0.9


def test_sgd_oneclass_convergence():
    # Check that the optimization does not end early and that the stopping criterion
    # is working. Non-regression test for #30027
    for nu in [0.1, 0.5, 0.9]:
        # no need for large max_iter
        model = SGDOneClassSVM(
            nu=nu, max_iter=100, tol=1e-3, learning_rate="constant", eta0=1e-3
        )
        model.fit(iris.data)
        # 6 is the minimal number of iterations that should be surpassed, after which
        # the optimization can stop
        assert model.n_iter_ > 6


def test_sgd_oneclass_vs_linear_oneclass():
    # Test convergence vs. liblinear `OneClassSVM` with kernel="linear"
    for nu in [0.1, 0.5, 0.9]:
        # allow enough iterations, small dataset
        model = SGDOneClassSVM(
            nu=nu, max_iter=20000, tol=None, learning_rate="constant", eta0=1e-3
        )
        model_ref = OneClassSVM(kernel="linear", nu=nu, tol=1e-6)  # reference model
        model.fit(iris.data)
        model_ref.fit(iris.data)

        preds = model.predict(iris.data)
        dec_fn = model.decision_function(iris.data)