Medial Code Documentation
Loading...
Searching...
No Matches
test_rank_metric.h
1
4#pragma once
5#include <gtest/gtest.h> // for Test, EXPECT_NEAR, ASSERT_STREQ
6#include <xgboost/context.h> // for Context
7#include <xgboost/data.h> // for MetaInfo, DMatrix
8#include <xgboost/linalg.h> // for Matrix
9#include <xgboost/metric.h> // for Metric
10
11#include <algorithm> // for max
12#include <memory> // for unique_ptr
13#include <vector> // for vector
14
15#include "../helpers.h" // for GetMetricEval, CreateEmptyGe...
16#include "xgboost/base.h" // for bst_float, kRtEps
17#include "xgboost/host_device_vector.h" // for HostDeviceVector
18#include "xgboost/json.h" // for Json, String, Object
19
20namespace xgboost::metric {
21
22inline void VerifyPrecision(DataSplitMode data_split_mode = DataSplitMode::kRow) {
23 auto ctx = MakeCUDACtx(GPUIDX);
24 std::unique_ptr<xgboost::Metric> metric{Metric::Create("pre", &ctx)};
25 ASSERT_STREQ(metric->Name(), "pre");
26 EXPECT_NEAR(GetMetricEval(metric.get(), {0, 1}, {0, 1}, {}, {}, data_split_mode), 0.5, 1e-7);
27 EXPECT_NEAR(
28 GetMetricEval(metric.get(), {0.1f, 0.9f, 0.1f, 0.9f}, {0, 0, 1, 1}, {}, {}, data_split_mode),
29 0.5, 1e-7);
30
31 metric.reset(xgboost::Metric::Create("pre@2", &ctx));
32 ASSERT_STREQ(metric->Name(), "pre@2");
33 EXPECT_NEAR(GetMetricEval(metric.get(), {0, 1}, {0, 1}, {}, {}, data_split_mode), 0.5f, 1e-7);
34 EXPECT_NEAR(
35 GetMetricEval(metric.get(), {0.1f, 0.9f, 0.1f, 0.9f}, {0, 0, 1, 1}, {}, {}, data_split_mode),
36 0.5f, 0.001f);
37
38 EXPECT_ANY_THROW(GetMetricEval(metric.get(), {0, 1}, {}, {}, {}, data_split_mode));
39
40 metric.reset(xgboost::Metric::Create("pre@4", &ctx));
41 EXPECT_NEAR(GetMetricEval(metric.get(), {0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f},
42 {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}, {}, {}, data_split_mode),
43 0.5f, 1e-7);
44}
45
46inline void VerifyNDCG(DataSplitMode data_split_mode = DataSplitMode::kRow) {
47 auto ctx = MakeCUDACtx(GPUIDX);
48 Metric * metric = xgboost::Metric::Create("ndcg", &ctx);
49 ASSERT_STREQ(metric->Name(), "ndcg");
50 EXPECT_ANY_THROW(GetMetricEval(metric, {0, 1}, {}, {}, {}, data_split_mode));
51 ASSERT_NEAR(GetMetricEval(metric,
53 {}, {}, {}, data_split_mode), 1, 1e-10);
54 ASSERT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1, 1e-10);
55 EXPECT_NEAR(GetMetricEval(metric,
56 {0.1f, 0.9f, 0.1f, 0.9f},
57 { 0, 0, 1, 1}, {}, {}, data_split_mode),
58 0.6509f, 0.001f);
59
60 delete metric;
61 metric = xgboost::Metric::Create("ndcg@2", &ctx);
62 ASSERT_STREQ(metric->Name(), "ndcg@2");
63 EXPECT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1, 1e-10);
64 EXPECT_NEAR(GetMetricEval(metric,
65 {0.1f, 0.9f, 0.1f, 0.9f},
66 { 0, 0, 1, 1}, {}, {}, data_split_mode),
67 0.3868f, 0.001f);
68
69 delete metric;
70 metric = xgboost::Metric::Create("ndcg@-", &ctx);
71 ASSERT_STREQ(metric->Name(), "ndcg-");
72 EXPECT_NEAR(GetMetricEval(metric,
74 {}, {}, {}, data_split_mode), 0, 1e-10);
75 ASSERT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1.f, 1e-10);
76 EXPECT_NEAR(GetMetricEval(metric,
77 {0.1f, 0.9f, 0.1f, 0.9f},
78 { 0, 0, 1, 1}, {}, {}, data_split_mode),
79 0.6509f, 0.001f);
80 delete metric;
81 metric = xgboost::Metric::Create("ndcg-", &ctx);
82 ASSERT_STREQ(metric->Name(), "ndcg-");
83 EXPECT_NEAR(GetMetricEval(metric,
85 {}, {}, {}, data_split_mode), 0, 1e-10);
86 EXPECT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1.f, 1e-10);
87 EXPECT_NEAR(GetMetricEval(metric,
88 {0.1f, 0.9f, 0.1f, 0.9f},
89 { 0, 0, 1, 1}, {}, {}, data_split_mode),
90 0.6509f, 0.001f);
91
92 delete metric;
93 metric = xgboost::Metric::Create("ndcg@2-", &ctx);
94 ASSERT_STREQ(metric->Name(), "ndcg@2-");
95 EXPECT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1.f, 1e-10);
96 EXPECT_NEAR(GetMetricEval(metric,
97 {0.1f, 0.9f, 0.1f, 0.9f},
98 { 0, 0, 1, 1}, {}, {}, data_split_mode),
99 1.f - 0.3868f, 1.f - 0.001f);
100
101 delete metric;
102}
103
104inline void VerifyMAP(DataSplitMode data_split_mode = DataSplitMode::kRow) {
105 auto ctx = MakeCUDACtx(GPUIDX);
106 Metric * metric = xgboost::Metric::Create("map", &ctx);
107 ASSERT_STREQ(metric->Name(), "map");
108 EXPECT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1, kRtEps);
109
110 EXPECT_NEAR(GetMetricEval(metric,
111 {0.1f, 0.9f, 0.1f, 0.9f},
112 { 0, 0, 1, 1}, {}, {}, data_split_mode),
113 0.5f, 0.001f);
114 EXPECT_NEAR(GetMetricEval(metric,
116 std::vector<xgboost::bst_float>{}, {}, {}, data_split_mode), 1, 1e-10);
117
118 // Rank metric with group info
119 EXPECT_NEAR(GetMetricEval(metric,
120 {0.1f, 0.9f, 0.2f, 0.8f, 0.4f, 1.7f},
121 {1, 1, 1, 0, 1, 0}, // Labels
122 {}, // Weights
123 {0, 2, 5, 6}, // Group info
124 data_split_mode),
125 0.8611f, 0.001f);
126
127 delete metric;
128 metric = xgboost::Metric::Create("map@-", &ctx);
129 ASSERT_STREQ(metric->Name(), "map-");
130 EXPECT_NEAR(GetMetricEval(metric,
132 {}, {}, {}, data_split_mode), 0, 1e-10);
133
134 delete metric;
135 metric = xgboost::Metric::Create("map-", &ctx);
136 ASSERT_STREQ(metric->Name(), "map-");
137 EXPECT_NEAR(GetMetricEval(metric,
139 {}, {}, {}, data_split_mode), 0, 1e-10);
140
141 delete metric;
142 metric = xgboost::Metric::Create("map@2", &ctx);
143 ASSERT_STREQ(metric->Name(), "map@2");
144 EXPECT_NEAR(GetMetricEval(metric, {0, 1}, {0, 1}, {}, {}, data_split_mode), 1, 1e-10);
145 EXPECT_NEAR(GetMetricEval(metric,
146 {0.1f, 0.9f, 0.1f, 0.9f},
147 { 0, 0, 1, 1}, {}, {}, data_split_mode),
148 0.25f, 0.001f);
149 delete metric;
150}
151
152inline void VerifyNDCGExpGain(DataSplitMode data_split_mode = DataSplitMode::kRow) {
153 Context ctx = MakeCUDACtx(GPUIDX);
154
155 auto p_fmat = xgboost::RandomDataGenerator{0, 0, 0}.GenerateDMatrix();
156 MetaInfo& info = p_fmat->Info();
157 info.labels = linalg::Matrix<float>{{10.0f, 0.0f, 0.0f, 1.0f, 5.0f}, {5}, ctx.gpu_id};
158 info.num_row_ = info.labels.Shape(0);
159 info.group_ptr_.resize(2);
160 info.group_ptr_[0] = 0;
161 info.group_ptr_[1] = info.num_row_;
162 info.data_split_mode = data_split_mode;
163 HostDeviceVector<float> predt{{0.1f, 0.2f, 0.3f, 4.0f, 70.0f}};
164
165 std::unique_ptr<Metric> metric{Metric::Create("ndcg", &ctx)};
166 Json config{Object{}};
167 config["name"] = String{"ndcg"};
168 config["lambdarank_param"] = Object{};
169 config["lambdarank_param"]["ndcg_exp_gain"] = String{"true"};
170 config["lambdarank_param"]["lambdarank_num_pair_per_sample"] = String{"32"};
171 metric->LoadConfig(config);
172
173 auto ndcg = metric->Evaluate(predt, p_fmat);
174 ASSERT_NEAR(ndcg, 0.409738f, kRtEps);
175
176 config["lambdarank_param"]["ndcg_exp_gain"] = String{"false"};
177 metric->LoadConfig(config);
178
179 ndcg = metric->Evaluate(predt, p_fmat);
180 ASSERT_NEAR(ndcg, 0.695694f, kRtEps);
181
182 predt.HostVector() = info.labels.Data()->HostVector();
183 ndcg = metric->Evaluate(predt, p_fmat);
184 ASSERT_NEAR(ndcg, 1.0, kRtEps);
185}
186} // namespace xgboost::metric
Definition host_device_vector.h:87
static Metric * Create(const std::string &name, Context const *ctx)
create a metric according to name.
Definition metric.cc:46
Definition helpers.h:224
Copyright 2014-2023, XGBoost Contributors.
A device-and-host vector abstraction layer.
Copyright 2015-2023 by XGBoost Contributors.
Copyright 2015-2023 by XGBoost Contributors.
Copyright 2021-2023 by XGBoost Contributors.
Copyright 2016-2023 by XGBoost Contributors.
Definition auc.cc:27
Context MakeCUDACtx(std::int32_t device)
Make a context that uses CUDA if device >= 0.
Definition helpers.h:410
constexpr bst_float kRtEps
small eps gap for minimum split decision.
Definition base.h:319
Copyright 2014-2023 by XGBoost Contributors.