@@ -650,6 +650,50 @@ void CBoostedTreeTest::testIntegerRegressor() {
650
650
CPPUNIT_ASSERT (modelRSquared > 0.99 );
651
651
}
652
652
653
+ void CBoostedTreeTest::testSingleSplit () {
654
+
655
+ // We were getting an out-of-bound read in initialization when running on
656
+ // data with only two distinct values for the target variable. This test
657
+ // fails intermittently without the fix.
658
+
659
+ test::CRandomNumbers rng;
660
+
661
+ std::size_t rows{100 };
662
+ std::size_t cols{2 };
663
+
664
+ TDoubleVec x;
665
+ rng.generateUniformSamples (0.0 , 1.0 , rows, x);
666
+ for (auto & xi : x) {
667
+ xi = std::floor (xi + 0.5 );
668
+ }
669
+
670
+ auto frame = core::makeMainStorageDataFrame (cols).first ;
671
+ frame->categoricalColumns ({false , false });
672
+ for (std::size_t i = 0 ; i < rows; ++i) {
673
+ frame->writeRow ([&](core::CDataFrame::TFloatVecItr column, std::int32_t &) {
674
+ *(column++) = x[i];
675
+ *column = 10.0 * x[i];
676
+ });
677
+ }
678
+ frame->finishWritingRows ();
679
+
680
+ auto regression = maths::CBoostedTreeFactory::constructFromParameters (
681
+ 1 , std::make_unique<maths::boosted_tree::CMse>())
682
+ .buildFor (*frame, cols - 1 );
683
+
684
+ regression->train ();
685
+
686
+ double modelBias;
687
+ double modelRSquared;
688
+ std::tie (modelBias, modelRSquared) = computeEvaluationMetrics (
689
+ *frame, 0 , rows, regression->columnHoldingPrediction (frame->numberColumns ()),
690
+ [](const TRowRef& row) { return 10.0 * row[0 ]; }, 0.0 );
691
+
692
+ LOG_DEBUG (<< " bias = " << modelBias);
693
+ LOG_DEBUG (<< " R^2 = " << modelRSquared);
694
+ CPPUNIT_ASSERT (modelRSquared > 0.99 );
695
+ }
696
+
653
697
void CBoostedTreeTest::testTranslationInvariance () {
654
698
655
699
// We should get similar performance independent of fixed shifts for the target.
@@ -1036,6 +1080,8 @@ CppUnit::Test* CBoostedTreeTest::suite() {
1036
1080
&CBoostedTreeTest::testCategoricalRegressors));
1037
1081
suiteOfTests->addTest (new CppUnit::TestCaller<CBoostedTreeTest>(
1038
1082
" CBoostedTreeTest::testIntegerRegressor" , &CBoostedTreeTest::testIntegerRegressor));
1083
+ suiteOfTests->addTest (new CppUnit::TestCaller<CBoostedTreeTest>(
1084
+ " CBoostedTreeTest::testSingleSplit" , &CBoostedTreeTest::testSingleSplit));
1039
1085
suiteOfTests->addTest (new CppUnit::TestCaller<CBoostedTreeTest>(
1040
1086
" CBoostedTreeTest::testTranslationInvariance" ,
1041
1087
&CBoostedTreeTest::testTranslationInvariance));
0 commit comments