diff --git a/scikits/learn/svm.py b/scikits/learn/svm.py index 6606cfa59668472602e1ad24f094e2138489118a..606c327355e03b369bf3f53b6176f7c987011d97 100644 --- a/scikits/learn/svm.py +++ b/scikits/learn/svm.py @@ -261,23 +261,47 @@ class LinearSVC(object): """ Linear Support Vector Classification. + Similar to SVC with parameter kernel='linear', but uses internally + liblinear rather than libsvm, so it has more flexibility in the + choice of penalties and loss functions and should be faster for + huge datasets. Parameters ---------- + X : array-like, shape = [nsamples, nfeatures] + Training vector, where nsamples in the number of samples and + nfeatures is the number of features. + Y : array, shape = [nsamples] + Target vector relative to X - Also accepts parameter penalty, that can have values 'l1' or 'l2' + loss : string, 'l1' or 'l2' (default 'l2') + Specifies the loss function. With 'l1' it is the standard SVM + loss (a.k.a. hinge Loss) while with 'l2' it is the squared loss. + (a.k.a. squared hinge Loss) - Similar to SVC with parameter kernel='linear', but uses internally - liblinear rather than libsvm, so it has more flexibility in the - choice of penalties and loss functions and should be faster for - huge datasets. + penalty : string, 'l1' or 'l2' (default 'l2') + Specifies the norm used in the penalization. The 'l2' + penalty is the standard used in SVC. The 'l1' leads to coef_ + vectors that are sparse. + + dual : bool, (default True) + Specifies the norm used in the penalization. The 'l2' + penalty is the standard used in SVC. The 'l1' leads to coef_ + vectors that are sparse. TODO: wrap Cramer & Singer + + References + ---------- + LIBLINEAR -- A Library for Large Linear Classification + http://www.csie.ntu.edu.tw/~cjlin/liblinear/ + """ _solver_type = {'l2l2_1': 1, 'l2l2_0' : 2, 'l2l1_1' : 3, 'l1l2_0' : 5} - def __init__(self, penalty='l2', loss='l2', dual=False, eps=1e-4, C=1.0): + def __init__(self, penalty='l2', loss='l2', dual=True, eps=1e-4, C=1.0): s = penalty + loss + '_' + str(int(dual)) + print s try: self.solver_type = self._solver_type[s] except KeyError: raise ValueError('Not supported set of arguments') diff --git a/scikits/learn/tests/test_svm.py b/scikits/learn/tests/test_svm.py index 9d309333e53a6b2a4d15411a7952a6ce0aa143c4..c6a694be51ca675e998dc3f2ee61d71ea9295065 100644 --- a/scikits/learn/tests/test_svm.py +++ b/scikits/learn/tests/test_svm.py @@ -89,11 +89,11 @@ def test_predict_multiclass(): """ this example is from libsvm/README """ - X = [[0, 0.1, 0.2, 0, 0], - [ 0, 0.1, 0.3, -1.2, 0], - [0.4, 0, 0, 0, 0], - [0, 0.1, 0, 1.4, 0.5], - [-0.1,-0.2, 0.1, 1.1, 0.1]] + X = [[0, 0.1, 0.2, 0, 0], + [ 0, 0.1, 0.3, -1.2, 0], + [0.4, 0, 0, 0, 0], + [0, 0.1, 0, 1.4, 0.5], + [-0.1,-0.2, 0.1, 1.1, 0.1]] Y = [1,2,1,2,3] test = [[0, 1, 0, -1, 0]] clf = svm.SVC() @@ -124,7 +124,7 @@ def test_LinearSVC(): assert_array_equal(clf.predict(T), true_result) # the same with l1 penalty - clf = svm.LinearSVC(penalty='l1') + clf = svm.LinearSVC(penalty='l1', dual=False) clf.fit(X, Y) assert_array_equal(clf.predict(T), true_result) @@ -138,14 +138,17 @@ def test_LinearSVC(): clf.fit(X, Y) assert_array_equal(clf.predict(T), true_result) -def test_coef_SVC_vs_LinearSVC(): +def test_coef_and_intercept_SVC_vs_LinearSVC(): + """ + Test that SVC and LinearSVC return the same coef_ and intercept_ + """ svc = svm.SVC(kernel='linear', C=1) svc.fit(X, Y) - print svc.coef_ - linsvc = svm.LinearSVC(C=1) + linsvc = svm.LinearSVC(C=1, penalty='l2', loss='l1', dual=True) linsvc.fit(X, Y) - print linsvc.coef_ assert_array_equal(linsvc.coef_.shape, svc.coef_.shape) + assert_array_almost_equal(linsvc.coef_, svc.coef_, 5) + assert_array_almost_equal(linsvc.intercept_, svc.intercept_, 6) \ No newline at end of file