-
Notifications
You must be signed in to change notification settings - Fork 29k
SPARK-5017 [MLlib] - Use SVD to compute determinant and inverse of covariance matrix #3871
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
Conversation
|
Test build #24987 has started for PR 3871 at commit
|
|
Test build #24987 has finished for PR 3871 at commit
|
|
Test PASSed. |
|
@tgaloppo Could you please add a description? It can be based off of the JIRA, just enough to cover the main points of the PR. Thanks! |
… matrix. Code was calling both det() and pinv(), effectively performing two matrix decompositions. Futhermore, Breeze pinv() currently fails for singular matrices.
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.
Perhaps you could add a note here about how this behaves when sigma is singular, plus a reference like [http://en.wikipedia.org/wiki/Multivariate_normal_distribution#Degenerate_case]
The doc could be a short version of what you have below for calculateCovarianceConstants
|
@tgaloppo The logic looks good; my comments are basically about clarity (except for the log space question). Thanks for the PR! |
|
One more request: Could you please add a unit test with a singular matrix? Thank you! Perhaps in a new suite for MultivariateGaussian |
|
Test build #24998 has started for PR 3871 at commit
|
|
Test build #24998 has finished for PR 3871 at commit
|
|
Test PASSed. |
|
@jkbradley I think performing the pdf calculation in log-space (and providing a logpdf() method) is a good idea. Perhaps we can make this part of transitioning MultivariateGaussian to public scope? |
…ovariance matrix. Previous code called both pinv() and det(), effectively performing two matrix decompositions. Additionally, the pinv() implementation in Breeze is known to fail for singular matrices.
|
Test build #25001 has started for PR 3871 at commit
|
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.
"eigenvalues" --> "singular values" (here and in the next comment on line 79)
|
Test build #25001 has finished for PR 3871 at commit
|
|
Test build #25006 has finished for PR 3871 at commit
|
|
Test PASSed. |
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.
Good catch with the other var; could you please fix this and the test above too? var -> val
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.
@jkbradley No problem; fixed.
|
@tgaloppo thanks for verifying about the test pdf values |
|
Test build #25016 has started for PR 3871 at commit
|
|
Test build #25016 has finished for PR 3871 at commit
|
|
Test PASSed. |
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.
For link, use double-brackets:
(See [[http://en.wikipedia.org/wiki/Multivariate_normal_distribution#Degenerate_case]])
|
@tgaloppo 2 more small comments, but after those, I believe this will be ready. Thanks! |
Fixed comment in MultivariateGaussian
|
@jkbradley Good call on the test suite; I have added some non-center points to the tests. I also added the brackets to the in-comment link. |
|
Test build #25038 has started for PR 3871 at commit
|
|
Test build #25038 has finished for PR 3871 at commit
|
|
Test PASSed. |
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.
We can construct BDV and BDM directly.
MultivariateGaussianSuite - Create Breeze vectors and matrices directly instead of through MLlib vectors/matrices.
|
@mengxr Changes made. |
|
Test build #25069 has started for PR 3871 at commit
|
|
Test build #25069 has finished for PR 3871 at commit
|
|
Test PASSed. |
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.
U D^-1 * U.t => U D^(-1/2) D^(-1/2) U.t => (U D^(-1/2)) (D^(-1/2) U.t)
...both are U and D are symmetric, so...
(U D^(-1/2)) = (U.t (D^(-1/2)).t) => (D^(-1/2) U).t
and
(D^(-1/2) U.t) = (D^(-1/2) U)
thus
U D^-1 U.t => (D^(-1/2) U).t (D^(-1/2) U)
... bringing in the delta we get
delta.t (D^(-1/2) U).t (D^(-1/2) U) delta
=> ((D^(-1/2) U) delta).t (D^(-1/2) U) delta = norm(D^(-1/2) U delta)^2
as indicated by @mengxr
(phew, hope I did that OK! :) )
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.
@jkbradley Hmm. I am going to punt on this one. Perhaps @mengxr can point out my error. FWIW - Changing the code to U * D^(-1/2) causes the unit tests to fail.
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 agree; I see no reason why U should always be symmetric (as you have demonstrated). Before I roll back the change, I just want to make sure that I did not misinterpret @mengxr , and/or that we are not missing something that he sees.
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.
(u, d) is the eigendecomposition of sigma, so sigma = u * diag(d) * u^-1 ... but we have a special case since covariance matrices are always symmetric and positive semi-definite, in which case u * u.t = I, making it equivalent to the singular value decomposition... so sigma = u * diag(d) * u.t ... so in svd terms, v.t = u.t, then the inverse is v * inv(diag(d)) * u.t = u * inv(diag(d)) * u.t ...
Have I lost my bearings?
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.
Ugh, no, I have. I was confused about which were inverses, and what you wrote looks perfectly fine. Sorry for the trouble! I'll remove the comments.d
|
Merged into master. Thanks! |
MultivariateGaussian was calling both pinv() and det() on the covariance matrix, effectively performing two matrix decompositions. Both values are now computed using the singular value decompositon. Both the pseudo-inverse and the pseudo-determinant are used to guard against singular matrices.