| 769 | } |
| 770 | |
| 771 | void SerialTreeLearner::Split(Tree* tree, int best_leaf, int* left_leaf, int* right_leaf) { |
| 772 | const SplitInfo& best_split_info = best_split_per_leaf_[best_leaf]; |
| 773 | const int inner_feature_index = train_data_->InnerFeatureIndex(best_split_info.feature); |
| 774 | if (cegb_ != nullptr) { |
| 775 | cegb_->UpdateLeafBestSplits(tree, best_leaf, &best_split_info, &best_split_per_leaf_); |
| 776 | } |
| 777 | // left = parent |
| 778 | *left_leaf = best_leaf; |
| 779 | bool is_numerical_split = train_data_->FeatureBinMapper(inner_feature_index)->bin_type() == BinType::NumericalBin; |
| 780 | if (is_numerical_split) { |
| 781 | auto threshold_double = train_data_->RealThreshold(inner_feature_index, best_split_info.threshold); |
| 782 | // split tree, will return right leaf |
| 783 | *right_leaf = tree->Split(best_leaf, |
| 784 | inner_feature_index, |
| 785 | best_split_info.feature, |
| 786 | best_split_info.threshold, |
| 787 | threshold_double, |
| 788 | static_cast<double>(best_split_info.left_output), |
| 789 | static_cast<double>(best_split_info.right_output), |
| 790 | static_cast<data_size_t>(best_split_info.left_count), |
| 791 | static_cast<data_size_t>(best_split_info.right_count), |
| 792 | static_cast<double>(best_split_info.left_sum_hessian), |
| 793 | static_cast<double>(best_split_info.right_sum_hessian), |
| 794 | static_cast<float>(best_split_info.gain), |
| 795 | train_data_->FeatureBinMapper(inner_feature_index)->missing_type(), |
| 796 | best_split_info.default_left); |
| 797 | data_partition_->Split(best_leaf, train_data_, inner_feature_index, |
| 798 | &best_split_info.threshold, 1, best_split_info.default_left, *right_leaf); |
| 799 | } else { |
| 800 | std::vector<uint32_t> cat_bitset_inner = Common::ConstructBitset(best_split_info.cat_threshold.data(), best_split_info.num_cat_threshold); |
| 801 | std::vector<int> threshold_int(best_split_info.num_cat_threshold); |
| 802 | for (int i = 0; i < best_split_info.num_cat_threshold; ++i) { |
| 803 | threshold_int[i] = static_cast<int>(train_data_->RealThreshold(inner_feature_index, best_split_info.cat_threshold[i])); |
| 804 | } |
| 805 | std::vector<uint32_t> cat_bitset = Common::ConstructBitset(threshold_int.data(), best_split_info.num_cat_threshold); |
| 806 | *right_leaf = tree->SplitCategorical(best_leaf, |
| 807 | inner_feature_index, |
| 808 | best_split_info.feature, |
| 809 | cat_bitset_inner.data(), |
| 810 | static_cast<int>(cat_bitset_inner.size()), |
| 811 | cat_bitset.data(), |
| 812 | static_cast<int>(cat_bitset.size()), |
| 813 | static_cast<double>(best_split_info.left_output), |
| 814 | static_cast<double>(best_split_info.right_output), |
| 815 | static_cast<data_size_t>(best_split_info.left_count), |
| 816 | static_cast<data_size_t>(best_split_info.right_count), |
| 817 | static_cast<double>(best_split_info.left_sum_hessian), |
| 818 | static_cast<double>(best_split_info.right_sum_hessian), |
| 819 | static_cast<float>(best_split_info.gain), |
| 820 | train_data_->FeatureBinMapper(inner_feature_index)->missing_type()); |
| 821 | data_partition_->Split(best_leaf, train_data_, inner_feature_index, |
| 822 | cat_bitset_inner.data(), static_cast<int>(cat_bitset_inner.size()), best_split_info.default_left, *right_leaf); |
| 823 | } |
| 824 | |
| 825 | #ifdef DEBUG |
| 826 | CHECK(best_split_info.left_count == data_partition_->leaf_count(best_leaf)); |
| 827 | #endif |
| 828 | auto p_left = smaller_leaf_splits_.get(); |
no test coverage detected