[catboost] Add unittest where TFullModel::Calc fails for absolutely valid case (model with cat-only features)
[catboost] Add unittest where TFullModel::Calc fails for absolutely valid case (model with cat-only features)
([arc::mergeid] 31f22b00-18e7d0d4-a64c81b7-1)
#include <catboost/libs/model/formula_evaluator.h>
#include <catboost/libs/model/model.h>
+#include <catboost/libs/train_lib/train_model.h>
+
+#include <util/folder/tempdir.h>
static TFullModel SimpleFloatModel() {
TFullModel model;
@@ -62,6 +65,45 @@ static TFullModel MultiValueFloatModel() {
return model;
}
+// Deterministically train model that has only 3 categoric features.
+static TFullModel TrainCatOnlyModel() {
+ TTempDir trainDir;
+ TPool pool;
+ pool.Docs.Resize(/*doc count*/3, /*factors count*/ 3, /*baseline dimension*/ 0, /*has queryId*/ false, /*has subgroupId*/ false);
+ pool.Docs.Factors[0] = {
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("a")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("b")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("c"))};
+ pool.Docs.Factors[1] = {
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("d")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("e")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("f"))};
+ pool.Docs.Factors[2] = {
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("g")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("h")),
+ ConvertCatFeatureHashToFloat(CalcCatFeatureHash("k"))};
+ pool.Docs.Target = {1.0f, 0.0f, 0.2f};
+ pool.CatFeatures = {0, 1, 2};
+
+ TFullModel model;
+ TEvalResult evalResult;
+ NJson::TJsonValue params;
+ params.InsertValue("iterations", 5);
+ params.InsertValue("random_seed", 1);
+ params.InsertValue("train_dir", trainDir.Name());
+ TrainModel(
+ params,
+ {},
+ {},
+ TClearablePoolPtrs(pool, {&pool}),
+ "",
+ &model,
+ {&evalResult}
+ );
+
+ return model;
+}
+
Y_UNIT_TEST_SUITE(TObliviousTreeModel) {
Y_UNIT_TEST(TestFlatCalcFloat) {
auto modelCalcer = SimpleFloatModel();
@@ -112,4 +154,22 @@ Y_UNIT_TEST_SUITE(TObliviousTreeModel) {
};
UNIT_ASSERT_EQUAL(canonVals, result);
}
+
+ Y_UNIT_TEST(TestCatOnlyModel) {
+ const auto model = TrainCatOnlyModel();
+
+ const auto applySingle = [&] {
+ const TVector<TStringBuf> f[] = {{"a", "b", "c"}};
+ double result = 0.;
+ model.Calc({}, f, MakeArrayRef(&result, 1));
+ };
+ UNIT_ASSERT_NO_EXCEPTION(applySingle());
+
+ const auto applyBatch = [&] {
+ const TVector<TStringBuf> f[] = {{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "k"}};
+ double results[3];
+ model.Calc({}, f, results);
+ };
+ UNIT_ASSERT_NO_EXCEPTION(applyBatch());
+ }
}
