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
Add example to compare classifiers #171
Conversation
decision functions are bit weird no? for example I am surprised that the kNN decision function is not more irregular. |
Thanks, looks good! will include it @qbarthelemy |
On closer inspection, this will probably be very confusing, as we can only display two dimensions of the three dimensional space. it could be alleviated with a 3d-plot, but that plot couldn't show decision boundaries properly. I'll look into another way of including an example. |
Good catch! Digging into the code, I have discovered that current version of KNN does not implement
Ok, but do not merge this branch in yours. Wait the merge, and rebase your branch on the last master.
Previous example plots the decision boundary for the horizontal 2D plane going through the mean value of the third coordinates. |
for il, ll in enumerate(self.classes_): | ||
prob[m, il] = np.sum( | ||
probas[m, neighbors_classes[m, 0:self.n_neighbors] == ll] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you see how it differs from how sklearn does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I had checked: methods are very similar.
The difference is the definition of probabilities from distances:
pyRiemann uses a softmax of negative squared distances (this formula is derived from the Riemannian Gaussian distribution, as explained in #100),
whereas sklearn uses reciprocal of distances, and then divides by the sum (to have the sum of probas equal to 1) (but, I don't know the origin of this formula).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before committing and making a choice that differs from sklearn I would run a tiny benchmark on Gaussian data following LDA model to see what approach leads to the best calibrated probability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would run a tiny benchmark
Nice idea! But, who is "I"? you or me? ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Joking aside, I don't see how to do this benchmark.
Because inputs of sklearn are multivariate vectors (generated by a mixture of multivariate Gaussian distributions, ok), while inputs of pyRiemann are covariance matrices. So, results can't be compared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would do it in sklearn using euclidian data. Basically replace the
predict_proba in sklearn and see what works best
in sklearn. Then copy this in PyRiemann
I plot log-probabilities of kNN applied on bivariate Gaussian distributions:
- weights="max_lik" : computing softmax of negative squared distances, equivalent to an Euclidean Gaussian modelization (implem added in this branch).
- weights="distance" : computing reciprocal of distances, equivalent to a power law modelization (classical sklearn implem);
Results are really close, but I think that new option is better, because:
- it is derived from a Gaussian prior, more coherent than a power law prior;
- it naturally deals with the case when we attempt to classify a point that is zero distance from one or more training points, contrary to reciprocal computation giving a singularity in 0.
Moreover, this new option could be added in sklearn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agramfort , can we merge the branch?
I had a look into that, but I did not find a reason. Does the covariances are the same or is it only the resulting classification? |
c768166
to
7002cd1
Compare
Good catch for the missing RandomState in |
c57180e
to
cd1a033
Compare
I would do it in sklearn using euclidian data. Basically replace the
predict_proba in sklearn and see what works best
in sklearn. Then copy this in PyRiemann
… Message ID: ***@***.***>
|
thx @qbarthelemy ! sorry it had slipped through the cracks |
LGTM |
This PR adds an example to compare several Riemannian classifiers on low-dimensional synthetic datasets, adapted to SPD matrices from https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html
@gabelstein