rcppmlpack / rcppmlpack2

Rcpp Interface to mlpack (version 2.1.0 and up)
GNU General Public License v2.0
24 stars 9 forks source link

new example src/logisticRegression.cpp #5

Closed MHenderson closed 7 years ago

MHenderson commented 7 years ago

update header, also include generated RcppExports.R

MHenderson commented 7 years ago

This includes two new examples logisticRegressionand logisticRegressionParameters. The first function does binary classification. The second one just does the training and returns the parameters of the trained model.

eddelbuettel commented 7 years ago

Hm. We could make the test set 'Nullable' (I can help with an example, we have that in a few places now) and could then test for it, and just have one function. Better?

MHenderson commented 7 years ago

Yes, one function instead of two does sound better. Can you point me towards an example of the 'Nullable' test set approach?

I suppose that the return value ought then to be a list? So we can return both the parameter vector and the results.

eddelbuettel commented 7 years ago

Regarding Nullable<>: It is used in mvabund three times and also once here in Rblpapi. See how you need .isNotNull() to test before instantiating. Should work cleanly here too.

As for the return, I am confused. Aren't both just vectors? So we return a vector either way? Or too little coffee here?

MHenderson commented 7 years ago

Thanks for the examples!

As for the return, I was thinking that the user might like to have both the test set classification and the model parameters without having to call the function twice.

eddelbuettel commented 7 years ago

Yes, then we'd use a list. Minor downside is that you then need to 'unpack'. But eventually we'll need that anyway, possibly also for existing classes.

Nullable<> is still somewhat new but it can help here. Strikes a fine balance between the run-time payload of NULL in a SEXP and the fact that we need types in C++.

MHenderson commented 7 years ago

So I think I need to convert from Rcpp::Nullable<arma::mat> to arma::mat because Classify expects the latter.

if (test.isNotNull()) {
      arma::mat test2(test);
      lrc.Classify(test2, resultsur);
      arma::vec results = arma::conv_to<arma::irowvec>::from(resultsur);
    } else {
      arma::vec results = R_NilValue;
    }

But this doesn't work because I get the following error:

logisticRegression.cpp:26:27: error: no matching function for call to ‘arma::Mat<double>::Mat(const Rcpp::Nullable<arma::Mat<double> >&)’
eddelbuettel commented 7 years ago

Ah, yes -- Nullable<> can (I think) only wrap around SEXP types so that needs to be a Rcpp::Nullable<Rcpp::NumericMatrix> , and in the non-null case you can instantiate an Arma matrix from the NumericMatrix via as<>():

Rcpp::cppFunction("void foo(NumericMatrix m) { arma::mat am = Rcpp::as<arma::mat>(m); 
                                               am.print(); }",
                               depends="RcppArmadillo")

Doable?

MHenderson commented 7 years ago

Yes, that works. My code probably leaves a lot to be desired but it does (seem to) work, at least.

eddelbuettel commented 7 years ago

That looks good -- thanks for making those changes!