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 Quic_SVD method in CF #3404
Conversation
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 for taking the time to add this! I agree with the changes to the QUIC_SVD
class itself. Do you think you could also add a test for this in cf_test.cpp
? It should be pretty simple, since there are already templated tests that are in use for the other decomposition policies.
arma::mat tempMat = w; | ||
w = h; | ||
h = tempMat; | ||
} |
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 fix the style here please? I'm guessing that there are some tab characters. mlpack code should be all spaces (no tabs). See also https://github.com/mlpack/mlpack/wiki/DesignGuidelines#style-guidelines 👍
src/mlpack/methods/cf/decomposition_policies/quic_svd_method.hpp
Outdated
Show resolved
Hide resolved
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Yes I will add some tests. Thanks for all suggestions. |
suggest to also add a corresponding item to HISTORY.md |
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 for adding this! The implementation looks mostly right, just a few minor comments throughout. 👍
* cf.GetRecommendations(10, recommendations); | ||
* @endcode | ||
*/ | ||
class QuicSVDPolicy |
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.
Since the original class is called QUIC_SVD
, I think we should call this QUIC_SVDPolicy
to be consistent. (I know that is harder to type...)
@@ -42,21 +42,20 @@ namespace mlpack { | |||
* const double epsilon = 0.01; // Relative error limit of data in subspace. | |||
* const double delta = 0.1 // Lower error bound for Monte Carlo estimate. | |||
* | |||
* // Make a QuicSVD object. | |||
* QuicSVD qSVD(); |
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.
Shouldn't this be QUIC_SVD
?
src/mlpack/tests/cf_test.cpp
Outdated
TEST_CASE("EmptyConstructorTrainQSVDTest", "[CFTest]") | ||
{ | ||
EmptyConstructorTrain<QuicSVDPolicy>(); | ||
} |
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.
Just an idea either for this or a future cleanup... I learned about TEMPLATE_TEST_CASE()
from Catch recently, and so we could combine all of these tests into something like this:
TEMPLATE_TEST_CASE("EmptyConstructorTrainTest", "[CFTest]", RandomizedSVDPolicy, RegSVDPolicy, ..., QuicSVDPolicy)
{
EmptyConstructorTrain<TestType>();
}
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.
Sure I will submit a fresh pr for this as it will cause some conflicts in #3413. Thanks for the idea.
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.
You don't need to do a fresh PR... you can just handle the merge conflicts in #3413, it shouldn't be too hard. But your call, either way is fine. 👍
|
||
// Do singular value decomposition using the quic SVD algorithm. | ||
QUIC_SVD quicsvd; | ||
quicsvd.Apply(data, w, h, sigma); |
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.
QUIC_SVD gives the approximate SVD data = u * diagmat(sigma) * v.t()
; but your code here ignores sigma
. I think that's incorrect and sigma
should be incorporated into either w
or h
, so that we can reconstruct as data = w * h.t()
.
@@ -64,6 +82,9 @@ inline void QUIC_SVD::ExtractSVD(arma::mat& u, | |||
arma::vec sigmaBar; | |||
arma::svd(uBar, sigmaBar, vBar, projectedMatSquared); | |||
|
|||
// vBar was tarnsposed of vBar | |||
vBar = arma::trans(vBar); |
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.
It is mentioned here that we get transposed of vBar after svd
link mentioned in 'quic_svd.hpp`.
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'm extremely surprised this change here doesn't break the tests in quic_svd_test.cpp
. I am not sure if the implementation returns exactly what the algorithm says, but we should not make this change: it fundamentally changes how QUIC_SVD
works and will break user expectations. As the implementation stands (see the test), the original matrix should be reconstructed as u * sigma * v.t()
. Let's not change that---instead if you need a transpose for CFType
, do it in QUIC_SVDPolicy
.
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.
One small implementation comment, and then just a bunch of style fixes. Everything is looking good to me. 👍
@@ -64,6 +82,9 @@ inline void QUIC_SVD::ExtractSVD(arma::mat& u, | |||
arma::vec sigmaBar; | |||
arma::svd(uBar, sigmaBar, vBar, projectedMatSquared); | |||
|
|||
// vBar was tarnsposed of vBar | |||
vBar = arma::trans(vBar); |
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'm extremely surprised this change here doesn't break the tests in quic_svd_test.cpp
. I am not sure if the implementation returns exactly what the algorithm says, but we should not make this change: it fundamentally changes how QUIC_SVD
works and will break user expectations. As the implementation stands (see the test), the original matrix should be reconstructed as u * sigma * v.t()
. Let's not change that---instead if you need a transpose for CFType
, do it in QUIC_SVDPolicy
.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
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.
Awesome---thank you for handling all the comments over the various rounds of review. This is a nice contribution! 👍
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.
Second approval provided automatically after 24 hours. 👍
Thanks @AdarshSantoria! 👍 |
As mentioned in #3398, Quic_SVD method is added in CF and some standard changes in 'methods/quic_svd` are performed so that it can be used in cf.