| 611 | } |
| 612 | |
| 613 | std::string GBDT::OutputMetric(int iter) { |
| 614 | bool need_output = (iter % config_->metric_freq) == 0; |
| 615 | std::string ret = ""; |
| 616 | std::stringstream msg_buf; |
| 617 | std::vector<std::pair<size_t, size_t>> meet_early_stopping_pairs; |
| 618 | // print training metric |
| 619 | if (need_output) { |
| 620 | for (auto& sub_metric : training_metrics_) { |
| 621 | auto name = sub_metric->GetName(); |
| 622 | auto scores = EvalOneMetric(sub_metric, train_score_updater_->score()); |
| 623 | for (size_t k = 0; k < name.size(); ++k) { |
| 624 | std::stringstream tmp_buf; |
| 625 | tmp_buf << "Iteration:" << iter |
| 626 | << ", training " << name[k] |
| 627 | << " : " << scores[k]; |
| 628 | Log::Info(tmp_buf.str().c_str()); |
| 629 | if (early_stopping_round_ > 0) { |
| 630 | msg_buf << tmp_buf.str() << '\n'; |
| 631 | } |
| 632 | } |
| 633 | } |
| 634 | } |
| 635 | // print validation metric |
| 636 | if (need_output || early_stopping_round_ > 0) { |
| 637 | for (size_t i = 0; i < valid_metrics_.size(); ++i) { |
| 638 | for (size_t j = 0; j < valid_metrics_[i].size(); ++j) { |
| 639 | auto test_scores = EvalOneMetric(valid_metrics_[i][j], valid_score_updater_[i]->score()); |
| 640 | auto name = valid_metrics_[i][j]->GetName(); |
| 641 | for (size_t k = 0; k < name.size(); ++k) { |
| 642 | std::stringstream tmp_buf; |
| 643 | tmp_buf << "Iteration:" << iter |
| 644 | << ", valid_" << i + 1 << " " << name[k] |
| 645 | << " : " << test_scores[k]; |
| 646 | if (need_output) { |
| 647 | Log::Info(tmp_buf.str().c_str()); |
| 648 | } |
| 649 | if (early_stopping_round_ > 0) { |
| 650 | msg_buf << tmp_buf.str() << '\n'; |
| 651 | } |
| 652 | } |
| 653 | if (es_first_metric_only_ && j > 0) { continue; } |
| 654 | if (ret.empty() && early_stopping_round_ > 0) { |
| 655 | auto cur_score = valid_metrics_[i][j]->factor_to_bigger_better() * test_scores.back(); |
| 656 | if (cur_score > best_score_[i][j]) { |
| 657 | best_score_[i][j] = cur_score; |
| 658 | best_iter_[i][j] = iter; |
| 659 | meet_early_stopping_pairs.emplace_back(i, j); |
| 660 | } else { |
| 661 | if (iter - best_iter_[i][j] >= early_stopping_round_) { ret = best_msg_[i][j]; } |
| 662 | } |
| 663 | } |
| 664 | } |
| 665 | } |
| 666 | } |
| 667 | for (auto& pair : meet_early_stopping_pairs) { |
| 668 | best_msg_[pair.first][pair.second] = msg_buf.str(); |
| 669 | } |
| 670 | return ret; |