@@ -35,10 +35,8 @@ class APLRRegressor
3535 double neg_gradient_nullmodel_errors_sum;
3636 size_t best_term;
3737 double lowest_error_sum;
38- double error_after_updating_intercept;
3938 VectorXd linear_predictor_update;
4039 VectorXd linear_predictor_update_validation;
41- double intercept_test;
4240 size_t number_of_eligible_terms;
4341 std::vector<std::vector<size_t >> distributed_terms;
4442 std::vector<Term> interactions_to_consider;
@@ -64,7 +62,7 @@ class APLRRegressor
6462 void estimate_split_points_for_interactions_to_consider ();
6563 void sort_errors_for_interactions_to_consider ();
6664 void add_promising_interactions_and_select_the_best_one ();
67- void consider_updating_intercept ( );
65+ void update_intercept ( size_t boosting_step );
6866 void select_the_best_term_and_update_errors (size_t boosting_step);
6967 void update_gradient_and_errors ();
7068 void add_new_term (size_t boosting_step);
@@ -506,15 +504,30 @@ void APLRRegressor::execute_boosting_steps()
506504
507505void APLRRegressor::execute_boosting_step (size_t boosting_step)
508506{
507+ update_intercept (boosting_step);
509508 find_best_split_for_each_eligible_term ();
510509 consider_interactions ();
511- consider_updating_intercept ();
512510 select_the_best_term_and_update_errors (boosting_step);
513511 if (abort_boosting) return ;
514512 update_term_eligibility ();
515513 print_summary_after_boosting_step (boosting_step);
516514}
517515
516+ void APLRRegressor::update_intercept (size_t boosting_step)
517+ {
518+ double intercept_update;
519+ if (sample_weight_train.size ()==0 )
520+ intercept_update=v*neg_gradient_current.mean ();
521+ else
522+ intercept_update=v*(neg_gradient_current.array ()*sample_weight_train.array ()).sum ()/sample_weight_train.array ().sum ();
523+ linear_predictor_update=VectorXd::Constant (neg_gradient_current.size (),intercept_update);
524+ linear_predictor_update_validation=VectorXd::Constant (y_validation.size (),intercept_update);
525+ intercept+=intercept_update;
526+ intercept_steps[boosting_step]=intercept;
527+ update_linear_predictor_and_predictors ();
528+ update_gradient_and_errors ();
529+ }
530+
518531void APLRRegressor::find_best_split_for_each_eligible_term ()
519532{
520533 best_term=std::numeric_limits<size_t >::max ();
@@ -713,78 +726,53 @@ void APLRRegressor::add_promising_interactions_and_select_the_best_one()
713726 }
714727}
715728
716- void APLRRegressor::consider_updating_intercept ()
717- {
718- if (sample_weight_train.size ()==0 )
719- intercept_test=neg_gradient_current.mean ();
720- else
721- intercept_test=(neg_gradient_current.array ()*sample_weight_train.array ()).sum ()/sample_weight_train.array ().sum ();
722- intercept_test=intercept_test*v;
723- linear_predictor_update=VectorXd::Constant (neg_gradient_current.size (),intercept_test);
724- linear_predictor_update_validation=VectorXd::Constant (y_validation.size (),intercept_test);
725- error_after_updating_intercept=calculate_sum_error (calculate_errors (neg_gradient_current,linear_predictor_update,sample_weight_train));
726- }
727-
728729void APLRRegressor::select_the_best_term_and_update_errors (size_t boosting_step)
729730{
730- // If intercept does best
731- if (std::islessequal (error_after_updating_intercept,lowest_error_sum))
731+ bool no_term_was_selected{best_term == std::numeric_limits< size_t >:: max ()};
732+ if (no_term_was_selected)
732733 {
733- // Updating intercept, current predictions, gradient and errors
734- lowest_error_sum=error_after_updating_intercept;
735- intercept=intercept+intercept_test;
736- intercept_steps[boosting_step]=intercept;
737- update_linear_predictor_and_predictors ();
738- update_gradient_and_errors ();
734+ abort_boosting=true ;
735+ return ;
739736 }
740- else // Choosing the next term and updating the model
741- {
742- bool no_term_was_selected{best_term == std::numeric_limits<size_t >::max ()};
743- if (no_term_was_selected)
744- {
745- abort_boosting=true ;
746- return ;
747- }
748737
749- // Updating current predictions
750- VectorXd values{terms_eligible_current[best_term].calculate (X_train)};
751- VectorXd values_validation{terms_eligible_current[best_term].calculate (X_validation)};
752- linear_predictor_update=values*terms_eligible_current[best_term].coefficient ;
753- linear_predictor_update_validation=values_validation*terms_eligible_current[best_term].coefficient ;
754- double error_after_updating_term=calculate_sum_error (calculate_errors (neg_gradient_current,linear_predictor_update,sample_weight_train));
755- if ( std::isgreaterequal (error_after_updating_term,neg_gradient_nullmodel_errors_sum)) // if no improvement or worse then terminate search
756- {
757- abort_boosting= true ;
758- return ;
759- }
760- else // if improvement
761- {
762- // Updating predictions_current, gradient and errors
763- update_linear_predictor_and_predictors ();
764- update_gradient_and_errors ();
738+ // Updating current predictions
739+ VectorXd values{terms_eligible_current[best_term].calculate (X_train)};
740+ VectorXd values_validation{terms_eligible_current[best_term].calculate (X_validation)};
741+ linear_predictor_update=values*terms_eligible_current[best_term].coefficient ;
742+ linear_predictor_update_validation=values_validation*terms_eligible_current[best_term].coefficient ;
743+ double error_after_updating_term=calculate_sum_error (calculate_errors (neg_gradient_current,linear_predictor_update,sample_weight_train));
744+ bool no_improvement{ std::isgreaterequal (error_after_updating_term,neg_gradient_nullmodel_errors_sum)};
745+ if (no_improvement)
746+ {
747+ abort_boosting= true ;
748+ return ;
749+ }
750+ else
751+ {
752+ update_linear_predictor_and_predictors ();
753+ update_gradient_and_errors ();
765754
766- // Has the term been entered into the model before?
767- if (terms.size ()==0 ) // If nothing is in the model add the term
768- add_new_term (boosting_step);
769- else // If at least one term was added before
770- {
771- // Searching in existing terms
772- bool found{false };
773- for (size_t j = 0 ; j < terms.size (); ++j)
774- {
775- if (terms[j]==terms_eligible_current[best_term]) // if term was found, update coefficient and coefficient_steps
776- {
777- terms[j].coefficient +=terms_eligible_current[best_term].coefficient ;
778- terms[j].coefficient_steps [boosting_step]=terms[j].coefficient ;
779- found=true ;
780- break ;
781- }
782- }
783- // term was not in the model and is added to the model
784- if (!found)
755+ // Has the term been entered into the model before?
756+ if (terms.size ()==0 ) // If nothing is in the model add the term
757+ add_new_term (boosting_step);
758+ else // If at least one term was added before
759+ {
760+ // Searching in existing terms
761+ bool found{false };
762+ for (size_t j = 0 ; j < terms.size (); ++j)
763+ {
764+ if (terms[j]==terms_eligible_current[best_term]) // if term was found, update coefficient and coefficient_steps
785765 {
786- add_new_term (boosting_step);
787- }
766+ terms[j].coefficient +=terms_eligible_current[best_term].coefficient ;
767+ terms[j].coefficient_steps [boosting_step]=terms[j].coefficient ;
768+ found=true ;
769+ break ;
770+ }
771+ }
772+ // term was not in the model and is added to the model
773+ if (!found)
774+ {
775+ add_new_term (boosting_step);
788776 }
789777 }
790778 }
0 commit comments