| 89 | } |
| 90 | |
| 91 | data_size_t BaggingHelper(Random* cur_rand, data_size_t start, data_size_t cnt, data_size_t* buffer, data_size_t* buffer_right) { |
| 92 | if (cnt <= 0) { |
| 93 | return 0; |
| 94 | } |
| 95 | std::vector<score_t> tmp_gradients(cnt, 0.0f); |
| 96 | for (data_size_t i = 0; i < cnt; ++i) { |
| 97 | for (int cur_tree_id = 0; cur_tree_id < num_tree_per_iteration_; ++cur_tree_id) { |
| 98 | size_t idx = static_cast<size_t>(cur_tree_id) * num_data_ + start + i; |
| 99 | tmp_gradients[i] += std::fabs(gradients_[idx] * hessians_[idx]); |
| 100 | } |
| 101 | } |
| 102 | data_size_t top_k = static_cast<data_size_t>(cnt * config_->top_rate); |
| 103 | data_size_t other_k = static_cast<data_size_t>(cnt * config_->other_rate); |
| 104 | top_k = std::max(1, top_k); |
| 105 | ArrayArgs<score_t>::ArgMaxAtK(&tmp_gradients, 0, static_cast<int>(tmp_gradients.size()), top_k - 1); |
| 106 | score_t threshold = tmp_gradients[top_k - 1]; |
| 107 | |
| 108 | score_t multiply = static_cast<score_t>(cnt - top_k) / other_k; |
| 109 | data_size_t cur_left_cnt = 0; |
| 110 | data_size_t cur_right_cnt = 0; |
| 111 | data_size_t big_weight_cnt = 0; |
| 112 | for (data_size_t i = 0; i < cnt; ++i) { |
| 113 | score_t grad = 0.0f; |
| 114 | for (int cur_tree_id = 0; cur_tree_id < num_tree_per_iteration_; ++cur_tree_id) { |
| 115 | size_t idx = static_cast<size_t>(cur_tree_id) * num_data_ + start + i; |
| 116 | grad += std::fabs(gradients_[idx] * hessians_[idx]); |
| 117 | } |
| 118 | if (grad >= threshold) { |
| 119 | buffer[cur_left_cnt++] = start + i; |
| 120 | ++big_weight_cnt; |
| 121 | } else { |
| 122 | data_size_t sampled = cur_left_cnt - big_weight_cnt; |
| 123 | data_size_t rest_need = other_k - sampled; |
| 124 | data_size_t rest_all = (cnt - i) - (top_k - big_weight_cnt); |
| 125 | double prob = (rest_need) / static_cast<double>(rest_all); |
| 126 | if (cur_rand->NextFloat() < prob) { |
| 127 | buffer[cur_left_cnt++] = start + i; |
| 128 | for (int cur_tree_id = 0; cur_tree_id < num_tree_per_iteration_; ++cur_tree_id) { |
| 129 | size_t idx = static_cast<size_t>(cur_tree_id) * num_data_ + start + i; |
| 130 | gradients_[idx] *= multiply; |
| 131 | hessians_[idx] *= multiply; |
| 132 | } |
| 133 | } else { |
| 134 | buffer_right[cur_right_cnt++] = start + i; |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | return cur_left_cnt; |
| 139 | } |
| 140 | |
| 141 | void Bagging(int iter) override { |
| 142 | bag_data_cnt_ = num_data_; |