Jiaming Yuan 9fbde21e9d
Rework the precision metric. (#9222)
- Rework the precision metric for both CPU and GPU.
- Mention it in the document.
- Cleanup old support code for GPU ranking metric.
- Deterministic GPU implementation.

* Drop support for classification.

* type.

* use batch shape.

* lint.

* cpu build.

* cpu build.

* lint.

* Tests.

* Fix.

* Cleanup error message.
2023-06-02 20:49:43 +08:00

80 lines
2.4 KiB
Python

"""Tests for evaluation metrics."""
from typing import Dict, List
import numpy as np
import pytest
import xgboost as xgb
from xgboost.compat import concat
from xgboost.core import _parse_eval_str
def check_precision_score(tree_method: str) -> None:
"""Test for precision with ranking and classification."""
datasets = pytest.importorskip("sklearn.datasets")
X, y = datasets.make_classification(
n_samples=1024, n_features=4, n_classes=2, random_state=2023
)
qid = np.zeros(shape=y.shape) # same group
ltr = xgb.XGBRanker(n_estimators=2, tree_method=tree_method)
ltr.fit(X, y, qid=qid)
# re-generate so that XGBoost doesn't evaluate the result to 1.0
X, y = datasets.make_classification(
n_samples=512, n_features=4, n_classes=2, random_state=1994
)
ltr.set_params(eval_metric="pre@32")
result = _parse_eval_str(
ltr.get_booster().eval_set(evals=[(xgb.DMatrix(X, y), "Xy")])
)
score_0 = result[1][1]
X_list = []
y_list = []
n_query_groups = 3
q_list: List[np.ndarray] = []
for i in range(n_query_groups):
# same for all groups
X, y = datasets.make_classification(
n_samples=512, n_features=4, n_classes=2, random_state=1994
)
X_list.append(X)
y_list.append(y)
q = np.full(shape=y.shape, fill_value=i, dtype=np.uint64)
q_list.append(q)
qid = concat(q_list)
X = concat(X_list)
y = concat(y_list)
result = _parse_eval_str(
ltr.get_booster().eval_set(evals=[(xgb.DMatrix(X, y, qid=qid), "Xy")])
)
assert result[1][0].endswith("pre@32")
score_1 = result[1][1]
assert score_1 == score_0
def check_quantile_error(tree_method: str) -> None:
"""Test for the `quantile` loss."""
from sklearn.datasets import make_regression
from sklearn.metrics import mean_pinball_loss
rng = np.random.RandomState(19)
# pylint: disable=unbalanced-tuple-unpacking
X, y = make_regression(128, 3, random_state=rng)
Xy = xgb.QuantileDMatrix(X, y)
evals_result: Dict[str, Dict] = {}
booster = xgb.train(
{"tree_method": tree_method, "eval_metric": "quantile", "quantile_alpha": 0.3},
Xy,
evals=[(Xy, "Train")],
evals_result=evals_result,
)
predt = booster.inplace_predict(X)
loss = mean_pinball_loss(y, predt, alpha=0.3)
np.testing.assert_allclose(evals_result["Train"]["quantile"][-1], loss)