@@ -86,12 +86,13 @@ def __init__(self, vars=None, num_particles=10, max_stages=5000, chunk="auto", m
8686
8787 def astep (self , _ ):
8888 bart = self .bart
89+ inv_link = bart .inv_link
8990 num_observations = bart .num_observations
9091 variable_inclusion = np .zeros (bart .num_variates , dtype = "int" )
9192
9293 # For the tunning phase we restrict max_stages to a low number, otherwise it is almost sure
9394 # we will reach max_stages given that our first set of m trees is not good at all.
94- # Can set max_stages as a function of the number of variables/dimensions?
95+ # Can set max_stages as a function of the number of variables/dimensions? XXX
9596 if self .tune :
9697 max_stages = 5
9798 else :
@@ -105,10 +106,11 @@ def astep(self, _):
105106 break
106107 self .idx += 1
107108 tree = bart .trees [idx ]
108- R_j = bart .get_residuals_loo (tree )
109+ old_prediction = tree .predict_output ()
110+ bart .sum_trees_output -= old_prediction
109111 # Generate an initial set of SMC particles
110112 # at the end of the algorithm we return one of these particles as the new tree
111- particles = self .init_particles (tree .tree_id , R_j , num_observations )
113+ particles = self .init_particles (tree .tree_id , num_observations , inv_link )
112114
113115 for t in range (1 , max_stages ):
114116 # Get old particle at stage t
@@ -119,13 +121,12 @@ def astep(self, _):
119121 # Update weights. Since the prior is used as the proposal,the weights
120122 # are updated additively as the ratio of the new and old log_likelihoods
121123 for p_idx , p in enumerate (particles ):
122- new_likelihood = self .likelihood_logp (p .tree .predict_output (num_observations ))
124+ new_likelihood = self .likelihood_logp (inv_link ( p .tree .predict_output () ))
123125 p .log_weight += new_likelihood - p .old_likelihood_logp
124126 p .old_likelihood_logp = new_likelihood
125127
126128 # Normalize weights
127129 W , normalized_weights = self .normalize (particles )
128-
129130 # Resample all but first particle
130131 re_n_w = normalized_weights [1 :] / normalized_weights [1 :].sum ()
131132 new_indices = np .random .choice (self .indices , size = len (self .indices ), p = re_n_w )
@@ -148,8 +149,8 @@ def astep(self, _):
148149 new_tree = np .random .choice (particles , p = normalized_weights )
149150 self .old_trees_particles_list [tree .tree_id ] = new_tree
150151 bart .trees [idx ] = new_tree .tree
151- new_prediction = new_tree .tree .predict_output (num_observations )
152- bart .sum_trees_output = bart . Y - R_j + new_prediction
152+ new_prediction = new_tree .tree .predict_output ()
153+ bart .sum_trees_output += new_prediction
153154
154155 if not self .tune :
155156 self .iter += 1
@@ -161,8 +162,7 @@ def astep(self, _):
161162 variable_inclusion [index ] += 1
162163
163164 stats = {"variable_inclusion" : variable_inclusion }
164-
165- return bart .sum_trees_output , [stats ]
165+ return inv_link (bart .sum_trees_output ), [stats ]
166166
167167 @staticmethod
168168 def competence (var , has_grad ):
@@ -194,31 +194,26 @@ def get_old_tree_particle(self, tree_id, t):
194194 old_tree_particle .set_particle_to_step (t )
195195 return old_tree_particle
196196
197- def init_particles (self , tree_id , R_j , num_observations ):
197+ def init_particles (self , tree_id , num_observations , inv_link ):
198198 """
199199 Initialize particles
200200 """
201201 # The first particle is from the tree we are trying to replace
202202 prev_tree = self .get_old_tree_particle (tree_id , 0 )
203- likelihood = self .likelihood_logp (prev_tree .tree .predict_output (num_observations ))
203+ likelihood = self .likelihood_logp (inv_link ( prev_tree .tree .predict_output () ))
204204 prev_tree .old_likelihood_logp = likelihood
205205 prev_tree .log_weight = likelihood - self .log_num_particles
206206 particles = [prev_tree ]
207207
208208 # The rest of the particles are identically initialized
209- initial_value_leaf_nodes = R_j .mean ()
210209 initial_idx_data_points_leaf_nodes = np .arange (num_observations , dtype = "int32" )
211210 new_tree = Tree .init_tree (
212211 tree_id = tree_id ,
213- leaf_node_value = initial_value_leaf_nodes ,
212+ leaf_node_value = 0 ,
214213 idx_data_points = initial_idx_data_points_leaf_nodes ,
215214 )
216- likelihood_logp = self .likelihood_logp (new_tree .predict_output (num_observations ))
217- log_weight = likelihood_logp - self .log_num_particles
218215 for i in range (1 , self .num_particles ):
219- particles .append (
220- ParticleTree (new_tree , self .bart .prior_prob_leaf_node , log_weight , likelihood_logp )
221- )
216+ particles .append (ParticleTree (new_tree , self .bart .prior_prob_leaf_node , 0 , 0 ))
222217
223218 return np .array (particles )
224219
@@ -237,10 +232,10 @@ class ParticleTree:
237232
238233 def __init__ (self , tree , prior_prob_leaf_node , log_weight = 0 , likelihood = 0 ):
239234 self .tree = tree .copy () # keeps the tree that we care at the moment
240- self .expansion_nodes = tree . idx_leaf_nodes . copy () # This should be the array [0]
235+ self .expansion_nodes = [0 ]
241236 self .tree_history = [self .tree ]
242237 self .expansion_nodes_history = [self .expansion_nodes ]
243- self .log_weight = 0
238+ self .log_weight = log_weight
244239 self .prior_prob_leaf_node = prior_prob_leaf_node
245240 self .old_likelihood_logp = likelihood
246241 self .used_variates = []
@@ -253,7 +248,8 @@ def sample_tree_sequential(self, bart):
253248
254249 if prob_leaf < np .random .random ():
255250 grow_successful , index_selected_predictor = bart .grow_tree (
256- self .tree , index_leaf_node
251+ self .tree ,
252+ index_leaf_node ,
257253 )
258254 if grow_successful :
259255 # Add new leaf nodes indexes
0 commit comments