Skip to content

Commit 0f1e82f

Browse files
committed
Find initial prediction using initial_prediction module
1 parent baa1480 commit 0f1e82f

File tree

5 files changed

+124
-6
lines changed

5 files changed

+124
-6
lines changed

R-package/inst/include/agtboost.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <iostream>
1313
#include <fstream>
14+
#include <functional>
1415

1516
// Internal
1617
#include "cir.hpp"
@@ -21,6 +22,7 @@
2122
#include "optimization.hpp"
2223
#include "loss_functions.hpp"
2324
#include "gbt_count_auto.hpp"
25+
#include "initial_prediction.hpp"
2426

2527

2628
#endif // __GMGTB_HPP_INCLUDED__

R-package/inst/include/ensemble.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class ENSEMBLE
3636
double loss(Tvec<double> &y, Tvec<double> &pred, Tvec<double> &w);
3737
Tvec<double> dloss(Tvec<double> &y, Tvec<double> &pred);
3838
Tvec<double> ddloss(Tvec<double> &y, Tvec<double> &pred);
39+
double link_function(double pred_observed);
40+
double inverse_link_function(double pred);
3941

4042
double initial_prediction(Tvec<double> &y, std::string loss_function, Tvec<double> &w);
4143
void train(Tvec<double> &y, Tmat<double> &X, int verbose, bool greedy_complexities,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// initial_prediction.hpp
2+
3+
#ifndef __INITIAL_PREDICTION_HPP_INCLUDED__
4+
#define __INITIAL_PREDICTION_HPP_INCLUDED__
5+
6+
7+
#include "external_rcpp.hpp"
8+
9+
10+
double learn_initial_prediction(
11+
Tvec<double>& y,
12+
Tvec<double>& offset,
13+
std::function<Tvec<double> (Tvec<double>&,Tvec<double>&)> dloss,
14+
std::function<Tvec<double> (Tvec<double>&,Tvec<double>&)> ddloss,
15+
std::function<double (double)> link_function,
16+
std::function<double (double)> inverse_link_function,
17+
int verbose
18+
){
19+
// Newton opt settings
20+
double tolerance = 1E-9;
21+
double step_length = 0.2;
22+
double step=0.0;
23+
int niter = 50; // Max iterations
24+
// Data specific settings
25+
int n = y.size();
26+
double y_average = y.sum() / n;
27+
double initial_prediction = link_function(y_average);
28+
Tvec<double> pred = offset.array() + initial_prediction;
29+
// Iterate until optimal starting point found
30+
for(int i=0; i<niter; i++){
31+
// Gradient descent
32+
step = - step_length * dloss(y, pred).sum() / ddloss(y, pred).sum();
33+
initial_prediction += step;
34+
pred = pred.array() + step;
35+
// Check precision
36+
if(std::abs(step) <= tolerance){
37+
break;
38+
}
39+
}
40+
// Verbose?
41+
if(verbose>0){
42+
Rcpp::Rcout <<
43+
std::setprecision(4) <<
44+
"Initial prediction and raw-prediction estimated to :" <<
45+
inverse_link_function(initial_prediction) <<
46+
" and " <<
47+
initial_prediction <<
48+
" respectively" <<
49+
std::endl;
50+
}
51+
// Retun optimal starting point
52+
return initial_prediction;
53+
}
54+
55+
56+
#endif

R-package/inst/include/loss_functions.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@
77

88
// ----------- LOSS --------------
99
namespace loss_functions {
10+
11+
12+
double link_function(double pred_observed, std::string loss_function){
13+
// Returns g(mu)
14+
double pred_transformed=0.0;
15+
if(loss_function=="mse"){
16+
pred_transformed = pred_observed;
17+
}else if(loss_function=="logloss"){
18+
pred_transformed = log(pred_observed) - log(1 - pred_observed);
19+
}else if(loss_function=="poisson"){
20+
pred_transformed = log(pred_observed);
21+
}else if(loss_function=="gamma::neginv"){
22+
pred_transformed = - 1.0 / pred_observed;
23+
}else if(loss_function=="gamma::log"){
24+
pred_transformed = log(pred_observed);
25+
}else if(loss_function=="negbinom"){
26+
pred_transformed = log(pred_observed);
27+
}
28+
return pred_transformed;
29+
}
30+
31+
32+
double inverse_link_function(double pred_transformed, std::string loss_function){
33+
// Returns g^{-1}(pred)
34+
double pred_observed = 0.0;
35+
if(loss_function=="mse"){
36+
pred_observed = pred_transformed;
37+
}else if(loss_function=="logloss"){
38+
pred_observed = 1.0 / (1.0+exp(-pred_transformed));
39+
}else if(loss_function=="poisson"){
40+
pred_observed = exp(pred_transformed);
41+
}else if(loss_function=="gamma::neginv"){
42+
pred_observed = -1.0 / pred_transformed;;
43+
}else if(loss_function=="gamma::log"){
44+
pred_observed = exp(pred_transformed);
45+
}else if(loss_function=="negbinom"){
46+
pred_observed = exp(pred_transformed);
47+
}
48+
return pred_observed;
49+
}
50+
51+
1052
double loss(
1153
Tvec<double> &y,
1254
Tvec<double> &pred,

R-package/src/agtboost.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,17 @@ Tvec<double> ENSEMBLE::dloss(Tvec<double> &y, Tvec<double> &pred){
159159
Tvec<double> ENSEMBLE::ddloss(Tvec<double> &y, Tvec<double> &pred){
160160
return loss_functions::ddloss(y, pred, loss_function, extra_param);
161161
}
162-
162+
163+
164+
double ENSEMBLE::link_function(double pred_observed){
165+
return loss_functions::link_function(pred_observed, loss_function);
166+
}
167+
168+
169+
double ENSEMBLE::inverse_link_function(double pred){
170+
return loss_functions::inverse_link_function(pred, loss_function);
171+
}
172+
163173

164174
void ENSEMBLE::train(
165175
Tvec<double> &y,
@@ -170,6 +180,8 @@ void ENSEMBLE::train(
170180
Tvec<double> &w, Tvec<double> &offset, // Defaults to a zero-vector
171181
bool has_offset // Should be removed
172182
){
183+
using namespace std::placeholders;
184+
173185
// Set initials and declare variables
174186
int MAXITER = nrounds;
175187
int n = y.size();
@@ -182,11 +194,15 @@ void ENSEMBLE::train(
182194
Tmat<double> cir_sim = cir_sim_mat(100, 100); // nsim=100, nobs=100
183195

184196
// Initial constant prediction: arg min l(y,constant)
185-
if(has_offset){
186-
this->initialPred = 0.0;
187-
}else{
188-
this->initialPred = this->initial_prediction(y, loss_function, w); //y.sum()/n;
189-
}
197+
this->initialPred = learn_initial_prediction(
198+
y,
199+
offset,
200+
std::bind(&ENSEMBLE::dloss, this, _1, _2),
201+
std::bind(&ENSEMBLE::ddloss, this, _1, _2),
202+
std::bind(&ENSEMBLE::link_function, this, _1),
203+
std::bind(&ENSEMBLE::inverse_link_function, this, _1),
204+
verbose
205+
);
190206
pred.setConstant(this->initialPred);
191207
pred += offset;
192208
this->initial_score = loss_functions::loss(y, pred, loss_function, w, extra_param);

0 commit comments

Comments
 (0)