During ordered boosting skip folds for which loss function is not defined
#include <util/stream/format.h>
namespace NCatboostCuda {
+ namespace {
+ template <typename TTargetSlice>
+ inline bool IsMetricDefined(ELossFunction lossFunction, const TTargetSlice& targetSlice) {
+ if (IsPairwiseMetric(lossFunction) && !targetSlice.GetSamplesGrouping().HasPairs()) {
+ CATBOOST_DEBUG_LOG << "Dynamic boosting skipped some fold for some permutation because it did not have pairs; "
+ "this may happen if train or test datasets are very small" << Endl;
+ return false;
+ }
+ if (IsGroupwiseMetric(lossFunction)) {
+ const auto objectCount = targetSlice.GetTarget().GetSamplesMapping().GetObjectsSlice().Size();
+ if (targetSlice.GetSamplesGrouping().GetQueryCount() >= objectCount) {
+ CATBOOST_DEBUG_LOG << "Dynamic boosting skipped some fold for some permutation because all groups were trivial; "
+ "this may happen if train or test datasets are very small" << Endl;
+ return false;
+ }
+ }
+ return true;
+ }
+ }
template <template <class TMapping> class TTargetTemplate,
class TWeakLearner_>
class TDynamicBoosting {
@@ -361,11 +380,16 @@ namespace NCatboostCuda {
for (ui32 foldId = 0; foldId < folds.size(); ++foldId) {
const auto& estimationSlice = folds[foldId].EstimateSamples;
+ const auto& targetPermutation = target.GetTarget(permutation);
+ const auto& targetSlice = TargetSlice(targetPermutation, estimationSlice);
+ if (!IsMetricDefined(targetPermutation.GetType(), targetSlice)) {
+ continue;
+ }
+ const auto& cursorSlice = cursor.Get(permutation, foldId).SliceView(estimationSlice);
estimator.AddEstimationTask(*iterationCacheHolderPtr,
- TargetSlice(target.GetTarget(permutation),
- estimationSlice),
+ targetSlice,
permutationDataSet,
- cursor.Get(permutation, foldId).SliceView(estimationSlice),
+ cursorSlice,
&models.FoldData[permutation][foldId]);
}
}
