[POC] Experimental support for l1 error. (#7812)
Support adaptive tree, a feature supported by both sklearn and lightgbm. The tree leaf is recomputed based on residue of labels and predictions after construction. For l1 error, the optimal value is the median (50 percentile). This is marked as experimental support for the following reasons: - The value is not well defined for distributed training, where we might have empty leaves for local workers. Right now I just use the original leaf value for computing the average with other workers, which might cause significant errors. - Some follow-ups are required, for exact, pruner, and optimization for quantile function. Also, we need to calculate the initial estimation.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Copyright 2021 by XGBoost Contributors
|
||||
* Copyright 2021-2022 by XGBoost Contributors
|
||||
*/
|
||||
#include <thrust/scan.h>
|
||||
#include <cub/cub.cuh>
|
||||
@@ -201,14 +201,6 @@ void Transpose(common::Span<float const> in, common::Span<float> out, size_t m,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Last index of a group in a CSR style of index pointer.
|
||||
*/
|
||||
template <typename Idx>
|
||||
XGBOOST_DEVICE size_t LastOf(size_t group, common::Span<Idx> indptr) {
|
||||
return indptr[group + 1] - 1;
|
||||
}
|
||||
|
||||
double ScaleClasses(common::Span<double> results,
|
||||
common::Span<double> local_area, common::Span<double> fp,
|
||||
common::Span<double> tp, common::Span<double> auc,
|
||||
@@ -300,9 +292,9 @@ void SegmentedReduceAUC(common::Span<size_t const> d_unique_idx,
|
||||
double fp, tp, fp_prev, tp_prev;
|
||||
if (i == d_unique_class_ptr[class_id]) {
|
||||
// first item is ignored, we use this thread to calculate the last item
|
||||
thrust::tie(fp, tp) = d_fptp[LastOf(class_id, d_class_ptr)];
|
||||
thrust::tie(fp, tp) = d_fptp[common::LastOf(class_id, d_class_ptr)];
|
||||
thrust::tie(fp_prev, tp_prev) =
|
||||
d_neg_pos[d_unique_idx[LastOf(class_id, d_unique_class_ptr)]];
|
||||
d_neg_pos[d_unique_idx[common::LastOf(class_id, d_unique_class_ptr)]];
|
||||
} else {
|
||||
thrust::tie(fp, tp) = d_fptp[d_unique_idx[i] - 1];
|
||||
thrust::tie(fp_prev, tp_prev) = d_neg_pos[d_unique_idx[i - 1]];
|
||||
@@ -413,10 +405,10 @@ double GPUMultiClassAUCOVR(common::Span<float const> predts,
|
||||
}
|
||||
uint32_t class_id = d_unique_idx[i] / n_samples;
|
||||
d_neg_pos[d_unique_idx[i]] = d_fptp[d_unique_idx[i] - 1];
|
||||
if (i == LastOf(class_id, d_unique_class_ptr)) {
|
||||
if (i == common::LastOf(class_id, d_unique_class_ptr)) {
|
||||
// last one needs to be included.
|
||||
size_t last = d_unique_idx[LastOf(class_id, d_unique_class_ptr)];
|
||||
d_neg_pos[LastOf(class_id, d_class_ptr)] = d_fptp[last - 1];
|
||||
size_t last = d_unique_idx[common::LastOf(class_id, d_unique_class_ptr)];
|
||||
d_neg_pos[common::LastOf(class_id, d_class_ptr)] = d_fptp[last - 1];
|
||||
return;
|
||||
}
|
||||
});
|
||||
@@ -592,7 +584,7 @@ GPURankingAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
auto data_group_begin = d_group_ptr[group_id];
|
||||
size_t n_samples = d_group_ptr[group_id + 1] - data_group_begin;
|
||||
// last item of current group
|
||||
if (item.idx == LastOf(group_id, d_threads_group_ptr)) {
|
||||
if (item.idx == common::LastOf(group_id, d_threads_group_ptr)) {
|
||||
if (item.w > 0) {
|
||||
s_d_auc[group_id] = item.predt / item.w;
|
||||
} else {
|
||||
@@ -797,10 +789,10 @@ GPURankingPRAUCImpl(common::Span<float const> predts, MetaInfo const &info,
|
||||
}
|
||||
auto group_idx = dh::SegmentId(d_group_ptr, d_unique_idx[i]);
|
||||
d_neg_pos[d_unique_idx[i]] = d_fptp[d_unique_idx[i] - 1];
|
||||
if (i == LastOf(group_idx, d_unique_class_ptr)) {
|
||||
if (i == common::LastOf(group_idx, d_unique_class_ptr)) {
|
||||
// last one needs to be included.
|
||||
size_t last = d_unique_idx[LastOf(group_idx, d_unique_class_ptr)];
|
||||
d_neg_pos[LastOf(group_idx, d_group_ptr)] = d_fptp[last - 1];
|
||||
size_t last = d_unique_idx[common::LastOf(group_idx, d_unique_class_ptr)];
|
||||
d_neg_pos[common::LastOf(group_idx, d_group_ptr)] = d_fptp[last - 1];
|
||||
return;
|
||||
}
|
||||
});
|
||||
@@ -821,7 +813,7 @@ GPURankingPRAUCImpl(common::Span<float const> predts, MetaInfo const &info,
|
||||
auto it = dh::MakeTransformIterator<thrust::pair<double, uint32_t>>(
|
||||
thrust::make_counting_iterator(0ul), [=] XGBOOST_DEVICE(size_t g) {
|
||||
double fp, tp;
|
||||
thrust::tie(fp, tp) = d_fptp[LastOf(g, d_group_ptr)];
|
||||
thrust::tie(fp, tp) = d_fptp[common::LastOf(g, d_group_ptr)];
|
||||
double area = fp * tp;
|
||||
auto n_documents = d_group_ptr[g + 1] - d_group_ptr[g];
|
||||
if (area > 0 && n_documents >= 2) {
|
||||
|
||||
Reference in New Issue
Block a user