Skip to content

Commit

Permalink
Add MAPE metric (#6119)
Browse files Browse the repository at this point in the history
  • Loading branch information
hcho3 authored Sep 15, 2020
1 parent 47350f6 commit 33577ef
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 3 deletions.
2 changes: 2 additions & 0 deletions R-package/R/xgb.cv.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#' \item \code{error} binary classification error rate
#' \item \code{rmse} Rooted mean square error
#' \item \code{logloss} negative log-likelihood function
#' \item \code{mae} Mean absolute error
#' \item \code{mape} Mean absolute percentage error
#' \item \code{auc} Area under curve
#' \item \code{aucpr} Area under PR curve
#' \item \code{merror} Exact matching error, used to evaluate multi-class classification
Expand Down
2 changes: 2 additions & 0 deletions R-package/R/xgb.train.R
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
#' By default, it uses the 0.5 threshold for predicted values to define negative and positive instances.
#' Different threshold (e.g., 0.) could be specified as "error@0."
#' \item \code{merror} Multiclass classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
#' \item \code{mae} Mean absolute error
#' \item \code{mape} Mean absolute percentage error
#' \item \code{auc} Area under the curve. \url{https://en.wikipedia.org/wiki/Receiver_operating_characteristic#'Area_under_curve} for ranking evaluation.
#' \item \code{aucpr} Area under the PR curve. \url{https://en.wikipedia.org/wiki/Precision_and_recall} for ranking evaluation.
#' \item \code{ndcg} Normalized Discounted Cumulative Gain (for ranking task). \url{https://en.wikipedia.org/wiki/NDCG}
Expand Down
2 changes: 2 additions & 0 deletions R-package/man/xgb.cv.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions R-package/man/xgb.train.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/gpu/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ Following table shows current support status for evaluation metrics on the GPU.
+------------------------------+-------------+
| mae | |tick| |
+------------------------------+-------------+
| mape | |tick| |
+------------------------------+-------------+
| mphe | |tick| |
+------------------------------+-------------+
| logloss | |tick| |
Expand Down
1 change: 1 addition & 0 deletions doc/parameter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ Specify the learning task and the corresponding learning objective. The objectiv
- ``rmse``: `root mean square error <http://en.wikipedia.org/wiki/Root_mean_square_error>`_
- ``rmsle``: root mean square log error: :math:`\sqrt{\frac{1}{N}[log(pred + 1) - log(label + 1)]^2}`. Default metric of ``reg:squaredlogerror`` objective. This metric reduces errors generated by outliers in dataset. But because ``log`` function is employed, ``rmsle`` might output ``nan`` when prediction value is less than -1. See ``reg:squaredlogerror`` for other requirements.
- ``mae``: `mean absolute error <https://en.wikipedia.org/wiki/Mean_absolute_error>`_
- ``mape``: `mean absolute percentage error <https://en.wikipedia.org/wiki/Mean_absolute_percentage_error>`_
- ``mphe``: `mean Pseudo Huber error <https://en.wikipedia.org/wiki/Huber_loss>`_. Default metric of ``reg:pseudohubererror`` objective.
- ``logloss``: `negative log-likelihood <http://en.wikipedia.org/wiki/Log-likelihood>`_
- ``error``: Binary classification error rate. It is calculated as ``#(wrong cases)/#(all cases)``. For the predictions, the evaluation will regard the instances with prediction value larger than 0.5 as positive instances, and the others as negative instances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ private[spark] trait LearningTaskParams extends Params {
/**
* evaluation metrics for validation data, a default metric will be assigned according to
* objective(rmse for regression, and error for classification, mean average precision for
* ranking). options: rmse, rmsle, mae, logloss, error, merror, mlogloss, auc, aucpr, ndcg, map,
* gamma-deviance
* ranking). options: rmse, rmsle, mae, mape, logloss, error, merror, mlogloss, auc, aucpr, ndcg,
* map, gamma-deviance
*/
final val evalMetric = new Param[String](this, "evalMetric", "evaluation metrics for " +
"validation data, a default metric will be assigned according to objective " +
Expand Down Expand Up @@ -121,6 +121,6 @@ private[spark] object LearningTaskParams {

val evalMetricsToMaximize = HashSet("auc", "aucpr", "ndcg", "map")

val evalMetricsToMinimize = HashSet("rmse", "rmsle", "mae", "logloss", "error", "merror",
val evalMetricsToMinimize = HashSet("rmse", "rmsle", "mae", "mape", "logloss", "error", "merror",
"mlogloss", "gamma-deviance")
}
16 changes: 16 additions & 0 deletions src/metric/elementwise_metric.cu
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ struct EvalRowMAE {
}
};

struct EvalRowMAPE {
const char *Name() const {
return "mape";
}
XGBOOST_DEVICE bst_float EvalRow(bst_float label, bst_float pred) const {
return std::abs((label - pred) / label);
}
static bst_float GetFinal(bst_float esum, bst_float wsum) {
return wsum == 0 ? esum : esum / wsum;
}
};

struct EvalRowLogLoss {
const char *Name() const {
return "logloss";
Expand Down Expand Up @@ -369,6 +381,10 @@ XGBOOST_REGISTER_METRIC(MAE, "mae")
.describe("Mean absolute error.")
.set_body([](const char* param) { return new EvalEWiseBase<EvalRowMAE>(); });

XGBOOST_REGISTER_METRIC(MAPE, "mape")
.describe("Mean absolute percentage error.")
.set_body([](const char* param) { return new EvalEWiseBase<EvalRowMAPE>(); });

XGBOOST_REGISTER_METRIC(MPHE, "mphe")
.describe("Mean Pseudo Huber error.")
.set_body([](const char* param) { return new EvalEWiseBase<EvalRowMPHE>(); });
Expand Down
11 changes: 11 additions & 0 deletions tests/cpp/metric/test_elementwise_metric.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ TEST(Metric, DeclareUnifiedTest(MAE)) {
delete metric;
}

TEST(Metric, DeclareUnifiedTest(MAPE)) {
auto lparam = xgboost::CreateEmptyGenericParam(GPUIDX);
xgboost::Metric * metric = xgboost::Metric::Create("mape", &lparam);
metric->Configure({});
ASSERT_STREQ(metric->Name(), "mape");
EXPECT_NEAR(GetMetricEval(metric, {150, 300}, {100, 200}), 0.5f, 1e-10);
EXPECT_NEAR(GetMetricEval(metric, {50, 400, 500, 4000}, {100, 200, 500, 1000}),
1.125f, 0.001f);
delete metric;
}

TEST(Metric, DeclareUnifiedTest(MPHE)) {
auto lparam = xgboost::CreateEmptyGenericParam(GPUIDX);
xgboost::Metric * metric = xgboost::Metric::Create("mphe", &lparam);
Expand Down

0 comments on commit 33577ef

Please sign in to comment.