-
Notifications
You must be signed in to change notification settings - Fork 228
[MRG] Uniformize num_dims and add it for LMNN #193
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
[MRG] Uniformize num_dims and add it for LMNN #193
Conversation
# Conflicts: # test/test_utils.py
Note: For LMNN, if we have shogun, it will do a pca if asked so, but I couldn't find how the dimension of pca is chosen, so for now I didn't change anything... Also, maybe we'll not have to bother as soon as we have solved #124, because maybe we will chose that the 'pca' option triggers a scikit-learn PCA in both shogun/not shogun cases... |
Have you checked what is the pca option of Shogun for? It could be simply a preprocessing applied to the dataset, not an initialization of the algorithm. In which case we will set this option to false when solving #125 |
Yes, according to this page: http://shogun.ml/notebook/latest/LMNN.html, (in cell 5), they say PCA is used to find the initial matrix |
Indeed. Looking at this, I do not think they reduce the dimension anyway: |
metric_learn/_util.py
Outdated
"""Checks that num_dims is less that n_features and deal with the None | ||
case""" | ||
if num_dims is None: | ||
dim = n_features |
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.
As a style nitpick, I prefer early-return for cases like this:
if num_dims is None:
return n_features
if 0 < num_dims <= n_features:
return num_dims
raise ValueError(...)
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.
That's better I agree, done
metric_learn/_util.py
Outdated
|
||
|
||
def _check_num_dims(n_features, num_dims): | ||
"""Checks that num_dims is less that n_features and deal with the None |
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.
typo: "less than"
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.
Thanks, done
metric_learn/_util.py
Outdated
dim = n_features | ||
else: | ||
if not 0 < num_dims <= n_features: | ||
raise ValueError('Invalid num_dims, must be in [1, %d]' % n_features) |
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.
Some existing code would only warn if num_dims > n_features
. I think it's probably better to error out here, but we should keep in mind that this is technically a back-compat break.
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.
That's true, maybe adding it in the changelog is enough ? Something like "for all the algorithms that have a parameter num_dims
, it will now be checked to be between 1 and n_features
, with n_features
the number of dimensions of the input space" ?
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.
Also, I kept the name |
I agree that |
I investigated the travis fail and there seems to be an issue with some shapes mismatch for LMNN when doing dimensionality reduction. There seems to be a problem with the gradient: Looking into this line the gradient seems to be of the shape of an outer product of Xs (when it should be of the shape of L): Looking at the PR on LMNN in scikit-learn, there might be a dot product with L missing: I'll look into it |
# Conflicts: # metric_learn/rca.py # test/test_base_metric.py # test/test_utils.py
This reverts commit 81c9a8d.
if np.sign(res_1[0,0]) != np.sign(res_2[0,0]): | ||
res_2 *= -1 | ||
assert_array_almost_equal(res_1, res_2) | ||
assert_array_almost_equal(abs(res_1), abs(res_2)) |
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.
The tests were failing because of a sign error, I think it's because of the eigenvalue decomposition in LFDA, that can lead to different signs in the output. I did this modif because I thought that any sign switching of any column still keeps the result valid am I right (any symmetry wrt some of the axis are still valid right?) (Not just a global sign switching as before)? But maybe I should rather try to change the code to make LFDA deterministic ? What do you think @perimosocordiae @bellet ?
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 just raised an issue for that (#211), I guess maybe let's do like that for now and later fix this non deterministic problem ?
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.
The sign switch is expected, as each eigenvector may be negated independently of the others. The result is valid in the sense that the underlying optimization problem is still solved, and distances in the transformed space are equivalent. Individual points in the transformed space won't always be the same, though.
I don't think it's worth trying to enforce a deterministic result, but I could probably be persuaded otherwise.
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.
Let's discuss it in the issue you opened
If you agree with my last modifs (see comment #193 (review)), we should be ready to merge |
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.
LGTM. Merging
This solves #167 partially (only gives a num_dims argument to LMNN and ensures that the check is done uniformly between the algorithms)