Ejemplo n.º 1
0
def test_svdd_decision_function():
    # For the RBF (stationary) kernel the SVDD and the OneClass SVM
    #  are identical. Therefore here the test is run on a non-stationary
    #  kernel.

    # Test SVDD decision function
    rnd = check_random_state(2)

    # Generate train data
    X = 0.3 * rnd.randn(100, 2)
    X_train = np.r_[X + 2, X - 2]

    # Generate some regular novel observations
    X = 0.3 * rnd.randn(20, 2)
    X_test = np.r_[X + 2, X - 2]

    # Generate some abnormal novel observations
    X_outliers = rnd.uniform(low=-4, high=4, size=(20, 2))

    # fit the model
    clf = svm.SVDD(gamma='scale', nu=0.1, kernel="poly", degree=2,
                   coef0=1.0).fit(X_train)

    # predict and validate things
    y_pred_test = clf.predict(X_test)
    assert_greater(np.mean(y_pred_test == 1), .9)

    y_pred_outliers = clf.predict(X_outliers)
    assert_greater(np.mean(y_pred_outliers == -1), .8)

    dec_func_test = clf.decision_function(X_test)
    assert_array_equal((dec_func_test > 0).ravel(), y_pred_test == 1)

    dec_func_outliers = clf.decision_function(X_outliers)
    assert_array_equal((dec_func_outliers > 0).ravel(), y_pred_outliers == 1)
Ejemplo n.º 2
0
def test_sparse_svdd():
    """Check that sparse SVDD gives the same result as dense SVDD
    """
    # many class dataset:
    X_blobs, _ = make_blobs(n_samples=100, centers=10, random_state=0)
    X_blobs = sparse.csr_matrix(X_blobs)

    datasets = [[X_sp, None, T], [X2_sp, None, T2],
                [X_blobs[:80], None, X_blobs[80:]],
                [iris.data, None, iris.data]]
    kernels = ["linear", "poly", "rbf", "sigmoid"]
    for dataset in datasets:
        for kernel in kernels:
            clf = svm.SVDD(gamma='scale', kernel=kernel)
            sp_clf = svm.SVDD(gamma='scale', kernel=kernel)
            check_svm_model_equal(clf, sp_clf, *dataset)
Ejemplo n.º 3
0
def test_svdd_score_samples():
    # Test the raw sample scores of the SVDD
    # Background: the theoretical decision function score of the SVDD is
    #  d(x) = R - \|\phi(x) - a\|^2
    #       = R - \alpha^T Q \alpha / (\nu W)^2 - K(x, x)
    #           + 2 / (\nu W) \sum_i \alpha_i K(z_i, x)
    #       = 2 / (\nu W) (-\rho + \sum_i \alpha_i (K(z_i, x) - 0.5 K(x, x)))
    # where \rho = 0.5 \nu W (\alpha^T Q \alpha / (\nu W)^2 - R), W is the
    # sum of sample weights and \sum_i \alpha_i = \nu W since \alpha is
    # feasible.
    # In contrast, the current implementation returns a scaled score:
    #  d(x) = 0.5 (\nu W) (R - \|\phi(x) - a\|^2)
    #       = -\rho + \sum_i \alpha_i (K(z_i, x) - 0.5 K(x, x))
    # Implicit scaling makes the raw decision function scores of the ocSVM
    # and SVDD identical when the models coincide (stationary kernel).

    # Generate train data
    rnd = check_random_state(2)
    X = 0.3 * rnd.randn(100, 2)
    X_train = np.r_[X + 2, X - 2]

    # Evaluate the scores on a small uniform 2-d mesh
    xx, yy = np.meshgrid(np.linspace(-5, 5, num=26), np.linspace(-5, 5,
                                                                 num=26))
    X_test = np.c_[xx.ravel(), yy.ravel()]

    # Fit the model for at least 10% support vectors
    clf = svm.SVDD(nu=0.1, kernel="poly", gamma='scale', degree=2, coef0=1.0)
    clf.fit(X_train)

    # Check score_samples() implementation
    assert_array_almost_equal(clf.score_samples(X_test),
                              clf.decision_function(X_test) + clf.offset_)

    # Test the gamma="scale"
    gamma = 1.0 / (X.shape[1] * X_train.std())

    assert_almost_equal(clf._gamma, gamma)

    # Compute the kernel matrices
    k_zx = polynomial_kernel(X_train[clf.support_],
                             X_test,
                             gamma=gamma,
                             degree=clf.degree,
                             coef0=clf.coef0)
    k_xx = polynomial_kernel(X_test,
                             gamma=gamma,
                             degree=clf.degree,
                             coef0=clf.coef0).diagonal()

    # Compute the sample scores = decision scores without `-\rho`
    scores_ = np.dot(clf.dual_coef_, k_zx - k_xx[np.newaxis] / 2).ravel()
    assert_array_almost_equal(clf.score_samples(X_test), scores_)

    # Get the decision function scores
    decision_ = scores_ + clf.intercept_  # intercept_ = - \rho
    assert_array_almost_equal(clf.decision_function(X_test), decision_)
Ejemplo n.º 4
0
def test_svdd():
    # Test the output of libsvm for the SVDD problem with default parameters
    clf = svm.SVDD(gamma='scale')
    clf.fit(X)
    pred = clf.predict(T)

    assert_array_equal(pred, [-1, -1, -1])
    assert_equal(pred.dtype, np.dtype('intp'))
    assert_array_almost_equal(clf.intercept_, [0.383], decimal=3)
    assert_array_almost_equal(clf.dual_coef_,
                              [[0.681, 0.139, 0.680, 0.140, 0.680, 0.680]],
                              decimal=3)
    assert_false(hasattr(clf, "coef_"))
Ejemplo n.º 5
0
def test_immutable_coef_property():
    # Check that primal coef modification are not silently ignored
    svms = [
        svm.SVC(kernel='linear').fit(iris.data, iris.target),
        svm.NuSVC(kernel='linear').fit(iris.data, iris.target),
        svm.SVR(kernel='linear').fit(iris.data, iris.target),
        svm.NuSVR(kernel='linear').fit(iris.data, iris.target),
        svm.OneClassSVM(kernel='linear').fit(iris.data),
        svm.SVDD(kernel='linear').fit(iris.data),
    ]
    for clf in svms:
        assert_raises(AttributeError, clf.__setattr__, 'coef_', np.arange(3))
        assert_raises((RuntimeError, ValueError), clf.coef_.__setitem__,
                      (0, 0), 0)
Ejemplo n.º 6
0
def test_oneclass_and_svdd():
    # Generate a sample: two symmetrically placed clusters
    rnd = check_random_state(2)

    X = 0.3 * rnd.randn(100, 2)
    X_train = np.r_[X + 2, X - 2]

    # Test the output of libsvm for the SVDD and the One-Class SVM
    nu = 0.15

    svdd = svm.SVDD(nu=nu, kernel="rbf", gamma="scale")
    svdd.fit(X_train)

    ocsvm = svm.OneClassSVM(nu=nu, kernel="rbf", gamma="scale")
    ocsvm.fit(X_train)

    # The intercept of the SVDD differs from that of the One-Class SVM:
    #   `rho_svdd = (aTQa * (nu * l)^(-2) - R) * (nu * l) / 2` ,
    # and
    #   `rho_oc = (C0 + aTQa * (nu * l)^(-2) - R) * (nu * l) / 2` ,
    # since `R = C0 - 2 rho_oc / (nu l) + aTQa * (nu l)^(-2)`,
    # where `C0 = K(x,x) = K(x-x)` for a stationary K.
    # >>> The intercept_ value is negative rho!
    # For the RBF kernel: K(x,y) = exp(-theta * |x-y|^2), the C0 is 1.
    C0 = 1.0
    svdd_intercept = (2 * ocsvm.intercept_ + C0 * (nu * X_train.shape[0])) / 2
    assert_array_almost_equal(svdd.intercept_, svdd_intercept, decimal=3)

    # Evaluate the decision function on a uniformly spaced 2-d mesh
    xx, yy = np.meshgrid(np.linspace(-5, 5, num=101),
                         np.linspace(-5, 5, num=101))
    mesh = np.c_[xx.ravel(), yy.ravel()]

    svdd_df = svdd.decision_function(mesh)
    ocsvm_df = ocsvm.decision_function(mesh).ravel()
    assert_array_almost_equal(svdd_df, ocsvm_df)
Ejemplo n.º 7
0
X_outliers = random_state.uniform(low=-4, high=4, size=(20, 2))

# Define the models
nu = .1
kernels = [
    ("RBF", dict(kernel="rbf", gamma=0.1)),
    ("Poly", dict(kernel="poly", degree=2, coef0=1.0)),
]

for kernel_name, kernel in kernels:

    # Use low tolerance to ensure better precision of the SVM
    # optimization procedure.
    classifiers = [
        ("OCSVM", svm.OneClassSVM(nu=nu, tol=1e-8, **kernel)),
        ("SVDD", svm.SVDD(nu=nu, tol=1e-8, **kernel)),
    ]

    fig = plt.figure(figsize=(12, 5))
    fig.suptitle("One-Class SVM versus SVDD "
                 "(error train, error novel regular, error novel abnormal)")

    for i, (model_name, clf) in enumerate(classifiers):
        clf.fit(X_train)

        y_pred_train = clf.predict(X_train)
        y_pred_test = clf.predict(X_test)
        y_pred_outliers = clf.predict(X_outliers)
        n_error_train = y_pred_train[y_pred_train == -1].size
        n_error_test = y_pred_test[y_pred_test == -1].size
        n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size