Repository: scikit-learn/scikit-learn
File: sklearn/svm/tests/test_svm.py (Python)

Code before:
    assert_array_equal(svm_cloned.predict(iris.data), svm_builtin.predict(iris.data))


def test_svc_bad_kernel():
    svc = svm.SVC(kernel=lambda x, y: x)
    with pytest.raises(ValueError):
        svc.fit(X, Y)


# XXX: this test is thread-unsafe because it uses probability=True:
# https://github.com/scikit-learn/scikit-learn/issues/31885
@pytest.mark.thread_unsafe
def test_libsvm_convergence_warnings(global_random_seed):
    a = svm.SVC(
        kernel=lambda x, y: np.dot(x, y.T),
        random_state=global_random_seed,
        max_iter=2,
    )
    warning_msg = (
        r"Solver terminated early \(max_iter=2\).  Consider pre-processing "
        r"your data with StandardScaler or MinMaxScaler."
    )
    with pytest.warns(ConvergenceWarning, match=warning_msg):
        a.fit(np.array(X), Y)
    assert np.all(a.n_iter_ == 2)


def test_unfitted():
    X = "foo!"  # input validation not required when SVM not fitted

    clf = svm.SVC()
    with pytest.raises(Exception, match=r".*\bSVC\b.*\bnot\b.*\bfitted\b"):
        clf.predict(X)

    clf = svm.NuSVR()
    with pytest.raises(Exception, match=r".*\bNuSVR\b.*\bnot\b.*\bfitted\b"):
        clf.predict(X)


# ignore convergence warnings from max_iter=1
# XXX: this test is thread-unsafe because it uses probability=True:
# https://github.com/scikit-learn/scikit-learn/issues/31885
@pytest.mark.thread_unsafe
@pytest.mark.filterwarnings("ignore::sklearn.exceptions.ConvergenceWarning")
# TODO(1.10): remove test entirely.
@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_consistent_proba(global_random_seed):
    a = svm.SVC(probability=True, max_iter=1, random_state=global_random_seed)
    proba_1 = a.fit(X, Y).predict_proba(X)
    a = svm.SVC(probability=True, max_iter=1, random_state=global_random_seed)
    proba_2 = a.fit(X, Y).predict_proba(X)

Review comment (suggestion):
We should keep the assertions about the uncalibrated `decision_function` values.

Code after:
    assert_array_almost_equal(svm_cloned.dual_coef_, svm_builtin.dual_coef_)
    assert_array_almost_equal(svm_cloned.intercept_, svm_builtin.intercept_)
    assert_array_equal(svm_cloned.predict(iris.data), svm_builtin.predict(iris.data))

    assert_array_almost_equal(
        svm_cloned.decision_function(iris.data),
        svm_builtin.decision_function(iris.data),
    )


def test_svc_bad_kernel():
    svc = svm.SVC(kernel=lambda x, y: x)
    with pytest.raises(ValueError):
        svc.fit(X, Y)


def test_libsvm_convergence_warnings(global_random_seed):
    a = svm.SVC(
        kernel=lambda x, y: np.dot(x, y.T),
        random_state=global_random_seed,
        max_iter=2,
    )
    warning_msg = (
        r"Solver terminated early \(max_iter=2\).  Consider pre-processing "
        r"your data with StandardScaler or MinMaxScaler."
    )
    with pytest.warns(ConvergenceWarning, match=warning_msg):
        a.fit(np.array(X), Y)
    assert np.all(a.n_iter_ == 2)


def test_unfitted():
    X = "foo!"  # input validation not required when SVM not fitted

    clf = svm.SVC()
    with pytest.raises(Exception, match=r".*\bSVC\b.*\bnot\b.*\bfitted\b"):
        clf.predict(X)

    clf = svm.NuSVR()
    with pytest.raises(Exception, match=r".*\bNuSVR\b.*\bnot\b.*\bfitted\b"):
        clf.predict(X)


def test_consistent_decision_function(global_random_seed):
    a = svm.SVC(max_iter=1, random_state=global_random_seed)
    proba_1 = a.fit(X, Y).decision_function(X)
    a = svm.SVC(max_iter=1, random_state=global_random_seed)
    proba_2 = a.fit(X, Y).decision_function(X)
    assert_array_almost_equal(proba_1, proba_2)