//prediction for external data Eigen::VectorXd Tree::predict(DataFrame &testSet, const bool verbose) { //starting at root level, then call makePredictions recursively double pi = 0.0; Eigen::VectorXd p(testSet.nrrows); for (int obs = 0; obs < testSet.nrrows; obs++) { //in some rare case we do have a terminal node at the 0th level if (root->isTerminal) { pi = root->cm; } else if (testSet.matrix(obs, root->feature) < root->splitvalue) { //makePrediction leftDF pi = makePrediction(testSet, root->left, obs, verbose); } else { //makePrediction rightDF pi = makePrediction(testSet, root->right, obs, verbose); } if (!probability && !regression) { //cout<<"Rounding "<<pi<<" to "<<LUtils::round(pi)<<endl; pi = LUtils::round(pi); } p(obs) = pi; if (verbose) { cout << "p(" << obs << "): " << p(obs) << " order:" << testSet.order[obs] <<endl; } } //original order for p Eigen::VectorXd tmp(testSet.nrrows); int idx_orig = 0; for (int i = 0; i < testSet.nrrows; i++) { idx_orig = testSet.order.at(i); tmp(idx_orig) = p(i); } for (int i = 0; i < testSet.nrrows; i++) { p(i) = tmp(i); } //after prediction we have to re-establish the original order testSet.restoreOrder(); if (verbose) cout << "###Tree size:" << tree_size + 1 << " nodes." << endl; return p; }