diff --git a/src/mlpack/methods/xgboost/loss_functions/sse_loss.hpp b/src/mlpack/methods/xgboost/loss_functions/sse_loss.hpp index eff0693951..4eba295a37 100644 --- a/src/mlpack/methods/xgboost/loss_functions/sse_loss.hpp +++ b/src/mlpack/methods/xgboost/loss_functions/sse_loss.hpp @@ -51,49 +51,6 @@ class SSELoss return arma::accu(values) / (typename VecType::elem_type) values.n_elem; } - /** - * Returns the first order gradient of the loss function with respect to the - * values. - * - * This is primarily used in calculating the residuals and split gain for the - * gradient boosted trees. - * - * @tparam T The type of input data. This can be both a vector or a scalar. - * @param observed The true observed values. - * @param values The values with respect to which the gradient will be - * calculated. - */ - template - T Gradients(const T& observed, const T& values) - { - return values - observed; - } - - /** - * Returns the second order gradient of the loss function with respect to the - * values. - */ - template - VecType Hessians(const VecType& /* observed */, const VecType& values) - { - VecType h(values.n_elem, arma::fill::ones); - return h; - } - - /** - * Returns the pseudo residuals of the predictions. - * This is equal to the negative gradient of the loss function with respect - * to the predicted values f. - * - * @param observed The true observed values. - * @param f The prediction at the current step of boosting. - */ - template - VecType Residuals(const VecType& observed, const VecType& f) - { - return observed - f; - } - /** * Returns the output value for the leaf in the tree. */ @@ -105,17 +62,10 @@ class SSELoss /** * Calculates the similarity score for evaluating the splits. */ - template - double SimilarityScore(const VecType& observed, const VecType& residuals, - const size_t begin, const size_t end) + double SimilarityScore(const size_t begin, const size_t end) { - VecType gradients = Gradients(observed.subvec(begin, end), - residuals.subvec(begin, end)); - VecType hessians = Hessians(observed.subvec(begin, end), - residuals.subvec(begin, end)); - - return std::pow(ApplyL1(arma::accu(gradients)), 2) / - (arma::accu(hessians) + lambda); + return std::pow(ApplyL1(arma::accu(gradients.subvec(begin, end))), 2) / + (arma::accu(hessians.subvec(begin, end)) + lambda); } /** diff --git a/src/mlpack/tests/xgboost_test.cpp b/src/mlpack/tests/xgboost_test.cpp index 6a147950fc..ed9b900b91 100644 --- a/src/mlpack/tests/xgboost_test.cpp +++ b/src/mlpack/tests/xgboost_test.cpp @@ -31,78 +31,20 @@ TEST_CASE("SSEInitialPredictionTest", "[XGBTest]") REQUIRE(Loss.InitialPrediction(values) == initPred); } -/** - * Test that gradients are calculated correctly for SSE Loss. - */ -TEST_CASE("SSEGradientsTest", "[XGBTest]") -{ - arma::vec observed = {1, 3, 2, 2, 5, 6, 9, 11, 8, 8}; - arma::vec predicted = {0.5, 1, 2.5, 1.5, 5, 8, 8, 10.75, 9, 9.5}; - - // Actual gradients. - arma::vec gradients = {-0.5, -2, 0.5, -0.5, 0, 2, -1, -0.25, 1, 1.5}; - - SSELoss Loss; - // Calculated gradients. - arma::vec calculatedGradients = Loss.Gradients(observed, predicted); - - for (int i = 0; i < 10; i++) - REQUIRE(calculatedGradients[i] == gradients[i]); -} - -/** - * Test that hessians are calculated correctly for SSE Loss. - */ -TEST_CASE("SSEHessiansTest", "[XGBTest]") -{ - arma::vec observed = {1, 3, 2, 2, 5, 6, 9, 11, 8, 8}; - arma::vec predicted = {0.5, 1, 2.5, 1.5, 5, 8, 8, 10.75, 9, 9.5}; - - // Actual hessians. - arma::vec hessians = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - - SSELoss Loss; - // Calculated hessians. - arma::vec calculatedHessians = Loss.Hessians(observed, predicted); - - for (int i = 0; i < 10; i++) - REQUIRE(calculatedHessians[i] == hessians[i]); -} - -/** - * Test that residuals are calculated correctly for SSE Loss. - */ -TEST_CASE("SSEResidualsTest", "[XGBTest]") -{ - arma::vec observed = {1, 3, 2, 2, 5, 6, 9, 11, 8, 8}; - arma::vec predicted = {0.5, 1, 2.5, 1.5, 5, 8, 8, 10.75, 9, 9.5}; - - // Actual residuals. - arma::vec residuals = {0.5, 2, -0.5, 0.5, 0, -2, 1, 0.25, -1, -1.5}; - - SSELoss Loss; - // Calculated residuals. - arma::vec calculatedResiduals = Loss.Residuals(observed, predicted); - - for (int i = 0; i < 10; i++) - REQUIRE(calculatedResiduals[i] == residuals[i]); -} - /** * Test that output leaf value is calculated correctly for SSE Loss. */ TEST_CASE("SSELeafValueTest", "[XGBTest]") { - arma::vec observed = {1, 3, 2, 2, 5, 6, 9, 11, 8, 8}; - arma::vec predicted = {0.5, 1, 2.5, 1.5, 5, 8, 8, 10.75, 9, 9.5}; + arma::mat input = { { 1, 3, 2, 2, 5, 6, 9, 11, 8, 8 }, + { 0.5, 1, 2.5, 1.5, 5, 8, 8, 10.75, 9, 9.5 } }; + arma::vec weights; // dummy weights not used. // Actual output leaf value. double leafValue = -0.075; SSELoss Loss; - // Calculating gradients and hessians for input to OutputLeafValue(). - arma::vec gradients = Loss.Gradients(observed, predicted); - arma::vec hessians = Loss.Hessians(observed, predicted); + double gain = Loss.Evaluate(input, weights); - REQUIRE(Loss.OutputLeafValue(gradients, hessians) == leafValue); + REQUIRE(Loss.OutputLeafValue() == leafValue); }