[catboost] unittest to check that we can apply model trained without NaNs to NaNs
@@ -47,4 +47,40 @@ Y_UNIT_TEST_SUITE(TrainModelTests) {
UNIT_ASSERT_EXCEPTION_CONTAINS(f(), TCatboostException, "There are NaNs in test dataset");
}
+
+ Y_UNIT_TEST(TrainWithoutNansApplyWithNans) {
+ // Train doesn't have NaNs, so TrainModel implicitly forbids them (during quantization), but
+ // during model application we allow NaNs (because it's too expensive to check for their
+ // presence)
+ //
+ TTempDir trainDir;
+
+ TPool learn;
+ learn.Docs.Resize(/*doc count*/3, /*factors count*/ 3, /*baseline dimension*/ 0, /*has queryId*/ false, /*has subgroupId*/ false);
+ learn.Docs.Factors[0] = {+0.5f, +1.5f, -2.5f};
+ learn.Docs.Factors[1] = {+0.7f, +6.4f, +2.4f};
+ learn.Docs.Factors[2] = {-2.0f, -1.0f, +6.0f};
+ learn.Docs.Target = {1.0f, 0.0f, 0.2f};
+
+ 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(learn, {&learn}),
+ "",
+ &model,
+ {&evalResult}
+ );
+
+ const float numeric[] = {std::numeric_limits<float>::quiet_NaN(), +1.5f, -2.5f};
+ double predictions[1];
+ const auto f = [&] { model.Calc(numeric, {}, predictions); };
+ UNIT_ASSERT_NO_EXCEPTION(f());
+ }
}
