Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP decision_function for sparse SVC #1586

Closed
wants to merge 14 commits into from

Conversation

zaxtax
Copy link
Contributor

@zaxtax zaxtax commented Jan 16, 2013

This resolves issue #73, comes with new passing test.


"""
# multi class:
clf = svm.SVC(kernel='linear', C=0.1).fit(iris.data, iris.target)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the data is not sparse, is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a csr matrix, even if the data itself isn't exactly sparse. Is there a better dataset to use? Many other tests in the file make use of it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sorry for the noise. I didn't see that the data was converted to sparse at the top of the file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test would be more robust if the matrix actually contained some zeroes. You can force some features to zero, for example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g.

rng = check_random_state(42)
iris.data *= rng.random_integers(0, 1, iris.data.shape)

@GaelVaroquaux
Copy link
Member

Looks good from a quick review.

I am wondering: would it make sens to have a test checking that the sparse and dense version of the svm solver lead to the same predictions. We need to be really careful to have plenty of tests, or we'll let bugs go through.

@amueller
Copy link
Member

@GaelVaroquaux see #1572 ;)

@mblondel
Copy link
Member

Would feel safer if @larsmans could have a look.

@larsmans
Copy link
Member

I think this can effectively be combined with #1573 -- if we only implement decision_function, then we can get rid of the rest of the C/Cython prediction code. Will check the code.

@larsmans
Copy link
Member

I can't build this:

sklearn/svm/libsvm_sparse.pyx:370:25: Call with wrong number of arguments (expected 16, got 15)

@zaxtax
Copy link
Contributor Author

zaxtax commented Jan 23, 2013

I am still getting an off-by-one error in the test, but fixing now.

@zaxtax
Copy link
Contributor Author

zaxtax commented Jan 23, 2013

This should build fine now

prediction,
clf.classes_[(clf.decision_function(X) > 0).astype(np.int).ravel()])
expected = np.array([[-1.], [-0.66], [-1.], [0.66], [1.], [1.]])
assert_array_almost_equal(clf.decision_function(X), expected, 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure we want such a test. I think the one against dec and he other one above are the important ones.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does make sure we don't screw up in coef_ and decision_function at the same time :)

Hardcoded values aren't pretty, but since the SVM code is a bit shaky sometimes, it's ok with me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, lets keep it there.

@amueller
Copy link
Member

I think this looks good. Let's wait for @larsmans verdict, though.

@amueller
Copy link
Member

amueller commented Feb 4, 2013

@zaxtax could you please rebase again? Sorry for the inconvenience!

…into svm-sparse-decision-function

Conflicts:
	sklearn/svm/libsvm_sparse.c
@zaxtax
Copy link
Contributor Author

zaxtax commented Feb 4, 2013

Ok rebased

@amueller
Copy link
Member

@larsmans sorry for pestering you again, I think it would be great if you had the time to have a look...

@larsmans
Copy link
Member

The code looks good, but it needs a few more tests. A simple loop over the kernels (except linear) to check that clf.decision_function(iris.data) == sp_clf.decision_function(iris.data) would be sufficient. If that's implemented and it passes Travis, +1 from me.

@larsmans
Copy link
Member

(A check that decision_function agrees with predict would also be nice, but I don't actually expect that to pass. I've observed inconsistent results in the dense case.)

@@ -71,6 +71,15 @@ def test_svc():
sp_clf.predict_proba(T2), 4)


def test_kernels():
kernels = ["poly", "rbf", "sigmoid", "precomputed"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"precomputed" doesn't make sense here.

@larsmans
Copy link
Member

I just did some testing and it turns out the support_vectors_, intercept_ and dual_coef_ are all equal (except for sparse vs. dense) inside the test, so the problem is really in the prediction.

@larsmans
Copy link
Member

Aha:

In [46]: sp_clf.decision_function(iris.data[45:55])
Out[46]: 
array([[ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779],
       [ 1.13575837,  1.18438453,  7.00524779]])

In [47]: clf.decision_function(iris.data[45:55].toarray())
Out[47]: 
array([[  1.196648  ,   1.11769403,  15.13987207],
       [  1.50060384,   1.16958324,  19.41722257],
       [  1.31985864,   1.15688136,  15.35044727],
       [  1.54699485,   1.19714959,  20.01494234],
       [  1.38572268,   1.1721699 ,  17.23514292],
       [ -5.7582716 ,  -2.07146252,   8.17288356],
       [ -4.67235387,  -1.61247263,   5.80654236],
       [ -6.26120419,  -2.31025169,   5.07611298],
       [ -2.86265032,  -0.69043655,   4.41340914],
       [ -5.12835004,  -1.75884743,   4.05606444]])

@larsmans
Copy link
Member

I just tried to chase the bug, but I've no idea where in the jumbled mess of LibSVM and our wrapper code it is. Giving up for now.

@zaxtax
Copy link
Contributor Author

zaxtax commented Mar 17, 2013

Yea, I've been baffled by this error. I've been visualizing it all week to
see what's up.

On Sun, Mar 17, 2013 at 9:52 AM, Lars Buitinck notifications@github.comwrote:

I just tried to chase the bug, but I've no idea where in the jumbled mess
of LibSVM and our wrapper code it is. Giving up for now.


Reply to this email directly or view it on GitHubhttps://github.com//pull/1586#issuecomment-15026112
.

@jaquesgrobler
Copy link
Member

Any news on this guy? :)

@zaxtax
Copy link
Contributor Author

zaxtax commented Apr 19, 2013

I still can't figure it out. Help!!!!

On Fri, Apr 19, 2013 at 2:35 AM, Jaques Grobler notifications@github.comwrote:

Any news on this guy? :)


Reply to this email directly or view it on GitHubhttps://github.com//pull/1586#issuecomment-16644231
.

@Milchbart
Copy link

Hi!
Is this patch working? Kernel test fails but results are looking fine?!

@larsmans
Copy link
Member

No, it doesn't work, it doesn't pass the tests. Both @zaxtax and I have spent quite some time on this issue but neither of us could figure it out.

@amueller amueller added this to the 0.16 milestone Jan 27, 2015
@amueller amueller changed the title MRG decision_function for sparse SVC WIP decision_function for sparse SVC Jan 27, 2015
@amueller
Copy link
Member

@zaxtax I added a test for the binary case and that even core dumps. It looks to me as if you missed treating the dual_coef_ as a sparse matrix here: https://github.com/scikit-learn/scikit-learn/pull/1586/files#diff-3aef2c02307e00a0c770468911710470R352 you just pass data but not the rest.
Or am I overlooking something?

@amueller
Copy link
Member

It seems that is the way it is done in the other functions, too, though I don't really understand what is happening there....

@amueller
Copy link
Member

Maybe similarly stupid question / remark:
in the dense case, the copy_predict_values doesn't use model->nr_class because the shape of the decision function is actually n_class * (n_class - 1) / 2.... somewhere the two-class case should be handled, too. I can't find that at the moment.

@ogrisel
Copy link
Member

ogrisel commented Mar 3, 2015

Closing this PR in favor of the rebased #4189.

@ogrisel ogrisel closed this Mar 3, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants