[catboost] add test that shows that --random-strengths doesn't work for plain boosting on CPU;
[catboost] don't fix loss function
([arc::mergeid] 74733626-50692a09-5977f566-a3e18096)
#include <library/unittest/registar.h>
#include <util/folder/tempdir.h>
+#include <util/generic/array_ref.h>
+#include <util/random/fast.h>
#include <limits>
+template <typename Prng>
+static void FillWithRandom(TArrayRef<TVector<float>> matrix, Prng& prng) {
+ for (auto& row : matrix) {
+ for (auto& cell : row) {
+ cell = prng.GenRandReal1();
+ }
+ }
+}
+
+template <typename Prng>
+static void FillWithRandom(TArrayRef<float> array, Prng& prng) {
+ for (auto& v : array) {
+ v = prng.GenRandReal1();
+ }
+}
+
Y_UNIT_TEST_SUITE(TrainModelTests) {
Y_UNIT_TEST(TrainWithoutNansTestWithNans) {
// Train doesn't have NaNs, so TrainModel implicitly forbids them (during quantization), but
@@ -89,4 +107,56 @@ Y_UNIT_TEST_SUITE(TrainModelTests) {
const auto f = [&] { model.Calc(numeric, {}, predictions); };
UNIT_ASSERT_NO_EXCEPTION(f());
}
+
+ Y_UNIT_TEST(TrainWithDifferentRandomStrength) {
+ // In general models trained with different random strength (--random-strength) should be
+ // different.
+
+ const ui64 seed = 20181029;
+ const size_t objectCount = 100;
+ const size_t numericFeatureCount = 2;
+ const double randomStrength[2] = {2., 5000.};
+
+ TFullModel models[2];
+ for (size_t i = 0; i < 2; ++i) {
+ TTempDir trainDir;
+
+ TPool learn;
+ learn.Docs.Resize(objectCount, numericFeatureCount, /*baseline dimension*/ 0, /*has queryId*/ false, /*has subgroupId*/ false);
+
+ TFastRng<ui64> prng(seed);
+ FillWithRandom(learn.Docs.Factors, prng);
+ FillWithRandom(learn.Docs.Target, prng);
+
+ TEvalResult evalResult;
+ NJson::TJsonValue params;
+ params.InsertValue("iterations", 5);
+ params.InsertValue("random_seed", 1);
+ params.InsertValue("train_dir", trainDir.Name());
+ params.InsertValue("random_strength", randomStrength[i]);
+ params.InsertValue("boosting_type", "Plain");
+ TrainModel(
+ params,
+ {},
+ {},
+ TClearablePoolPtrs(learn, {&learn}),
+ "",
+ &models[i],
+ {&evalResult}
+ );
+ }
+
+ TVector<float> object(numericFeatureCount);
+ {
+ TFastRng<ui64> prng(seed);
+ prng.Advance(objectCount * numericFeatureCount);
+ FillWithRandom(object, prng);
+ }
+
+ double predictions[2][1];
+ models[0].Calc(object, {}, predictions[0]);
+ models[1].Calc(object, {}, predictions[1]);
+
+ UNIT_ASSERT_VALUES_UNEQUAL(predictions[0][0], predictions[1][0]);
+ }
}
