Vowpal Wabbit
Classes | Typedefs | Enumerations | Functions | Variables
CCB Namespace Reference

Classes

struct  conditional_contextual_bandit_outcome
 
struct  label
 

Typedefs

typedef v_array< ACTION_SCORE::action_scoresdecision_scores_t
 

Enumerations

enum  example_type : uint8_t { unset = 0, shared = 1, action = 2, slot = 3 }
 

Functions

void default_label (void *v)
 
size_t read_cached_label (shared_data *, void *v, io_buf &cache)
 
float ccb_weight (void *v)
 
void cache_label (void *v, io_buf &cache)
 
bool test_label (void *v)
 
void delete_label (void *v)
 
void copy_label (void *dst, void *src)
 
ACTION_SCORE::action_score convert_to_score (const substring &action_id_str, const substring &probability_str)
 
CCB::conditional_contextual_bandit_outcomeparse_outcome (substring &outcome)
 
void parse_explicit_inclusions (CCB::label *ld, v_array< substring > &split_inclusions)
 
void parse_label (parser *p, shared_data *, void *v, v_array< substring > &words)
 
void clear_all (ccb &data)
 
bool split_multi_example_and_stash_labels (const multi_ex &examples, ccb &data)
 
template<bool is_learn>
bool sanity_checks (ccb &data)
 
void create_cb_labels (ccb &data)
 
void delete_cb_labels (ccb &data)
 
void attach_label_to_example (uint32_t action_index_one_based, example *example, conditional_contextual_bandit_outcome *outcome, ccb &data)
 
void save_action_scores (ccb &data, decision_scores_t &decision_scores)
 
void clear_pred_and_label (ccb &data)
 
bool has_action (multi_ex &cb_ex)
 
void inject_slot_features (example *shared, example *slot)
 
template<bool audit>
void inject_slot_id (ccb &data, example *shared, size_t id)
 
template<bool audit>
void remove_slot_id (example *shared)
 
void remove_slot_features (example *shared, example *slot)
 
void calculate_and_insert_interactions (example *shared, std::vector< example *> actions, std::vector< std::string > &generated_interactions)
 
template<bool is_learn>
void build_cb_example (multi_ex &cb_ex, example *slot, ccb &data)
 
template<bool is_learn>
void learn_or_predict (ccb &data, multi_learner &base, multi_ex &examples)
 
void print_decision_scores (int f, decision_scores_t &decision_scores)
 
void print_update (vw &all, std::vector< example *> &slots, decision_scores_t &decision_scores, size_t num_features)
 
void output_example (vw &all, ccb &, multi_ex &ec_seq)
 
void finish_multiline_example (vw &all, ccb &data, multi_ex &ec_seq)
 
base_learnerccb_explore_adf_setup (options_i &options, vw &all)
 
bool ec_is_example_header (example const &ec)
 

Variables

label_parser ccb_label_parser
 
static constexpr uint32_t SHARED_EX_INDEX = 0
 
static constexpr uint32_t TOP_ACTION_INDEX = 0
 

Typedef Documentation

◆ decision_scores_t

Definition at line 28 of file conditional_contextual_bandit.h.

Enumeration Type Documentation

◆ example_type

enum CCB::example_type : uint8_t
Enumerator
unset 
shared 
action 
slot 

Definition at line 22 of file ccb_label.h.

22  : uint8_t
23 {
24  unset = 0,
25  shared = 1,
26  action = 2,
27  slot = 3
28 };
uint32_t action
Definition: search.h:19

Function Documentation

◆ attach_label_to_example()

void CCB::attach_label_to_example ( uint32_t  action_index_one_based,
example example,
conditional_contextual_bandit_outcome outcome,
ccb data 
)

Definition at line 147 of file conditional_contextual_bandit.cc.

References CB::cb_class::action, polylabel::cb, ccb::cb_label, CCB::conditional_contextual_bandit_outcome::cost, CB::cb_class::cost, CB::label::costs, example::l, CCB::conditional_contextual_bandit_outcome::probabilities, and CB::cb_class::probability.

Referenced by build_cb_example().

149 {
150  // save the cb label
151  // Action is unused in cb
152  data.cb_label.action = action_index_one_based;
153  data.cb_label.probability = outcome->probabilities[0].score;
154  data.cb_label.cost = outcome->cost;
155 
156  example->l.cb.costs.push_back(data.cb_label);
157 }
CB::cb_class cb_label
CB::label cb
Definition: example.h:31
v_array< cb_class > costs
Definition: cb.h:27
uint32_t action
Definition: cb.h:18
float probability
Definition: cb.h:19
polylabel l
Definition: example.h:57
float cost
Definition: cb.h:17

◆ build_cb_example()

template<bool is_learn>
void CCB::build_cb_example ( multi_ex cb_ex,
example slot,
ccb data 
)

Definition at line 320 of file conditional_contextual_bandit.cc.

References polyprediction::a_s, ccb::action_score_pool, ccb::action_with_label, ccb::actions, attach_label_to_example(), polylabel::conditional_contextual_bandit, ccb::exclude_list, CCB::label::explicit_included_actions, ccb::include_list, inject_slot_features(), example::l, ccb::origin_index, CCB::label::outcome, example::pred, CCB::conditional_contextual_bandit_outcome::probabilities, ccb::shared, and example::tag.

321 {
322  bool slot_has_label = slot->l.conditional_contextual_bandit.outcome != nullptr;
323 
324  // Merge the slot features with the shared example and set it in the cb multi-example
325  // TODO is it imporant for total_sum_feat_sq and num_features to be correct at this point?
326  inject_slot_features(data.shared, slot);
327  cb_ex.push_back(data.shared);
328 
329  // Retrieve the action index whitelist (if the list is empty, then all actions are white-listed)
330  auto& explicit_includes = slot->l.conditional_contextual_bandit.explicit_included_actions;
331  if (explicit_includes.size() != 0)
332  {
333  // First time seeing this, initialize the vector with falses so we can start setting each included action.
334  if (data.include_list.size() == 0)
335  {
336  data.include_list.assign(data.actions.size(), false);
337  }
338 
339  for (uint32_t included_action_id : explicit_includes)
340  {
341  data.include_list[included_action_id] = true;
342  }
343  }
344 
345  // set the available actions in the cb multi-example
346  uint32_t index = 0;
347  data.origin_index.clear();
348  data.origin_index.resize(data.actions.size(), 0);
349  for (size_t i = 0; i < data.actions.size(); i++)
350  {
351  // Filter actions that are not explicitly included. If the list is empty though, everything is included.
352  if (!data.include_list.empty() && !data.include_list[i])
353  continue;
354 
355  // Filter actions chosen by previous slots
356  if (data.exclude_list[i])
357  continue;
358 
359  // Select the action
360  cb_ex.push_back(data.actions[i]);
361 
362  // Save the original index from the root multi-example
363  data.origin_index[index++] = (uint32_t)i;
364 
365  // Remember the index of the chosen action
366  if (is_learn && slot_has_label && i == slot->l.conditional_contextual_bandit.outcome->probabilities[0].action)
367  {
368  // This is used to remove the label later.
369  data.action_with_label = (uint32_t)i;
371  }
372  }
373 
374  // Must provide a prediction that cb can write into, this will be saved into the decision scores object later.
375  data.shared->pred.a_s = data.action_score_pool.get_object();
376 
377  // Tag can be used for specifying the sampling seed per slot. For it to be used it must be inserted into the shared
378  // example.
379  std::swap(data.shared->tag, slot->tag);
380 }
v_array< char > tag
Definition: example.h:63
ACTION_SCORE::action_scores a_s
Definition: example.h:47
void attach_label_to_example(uint32_t action_index_one_based, example *example, conditional_contextual_bandit_outcome *outcome, ccb &data)
VW::v_array_pool< ACTION_SCORE::action_score > action_score_pool
std::vector< example * > actions
std::vector< bool > exclude_list
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
std::vector< uint32_t > origin_index
polylabel l
Definition: example.h:57
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
CCB::label conditional_contextual_bandit
Definition: example.h:32
void inject_slot_features(example *shared, example *slot)
std::vector< bool > include_list
polyprediction pred
Definition: example.h:60
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ cache_label()

void CCB::cache_label ( void *  v,
io_buf cache 
)

Definition at line 116 of file ccb_label.cc.

References io_buf::buf_write(), c, VW::convert(), CCB::conditional_contextual_bandit_outcome::cost, CCB::label::explicit_included_actions, CCB::label::outcome, CCB::conditional_contextual_bandit_outcome::probabilities, v_array< T >::size(), CCB::label::type, and CCB::label::weight.

117 {
118  char* c;
119  CCB::label* ld = static_cast<CCB::label*>(v);
120  size_t size = sizeof(uint8_t) // type
121  + sizeof(bool) // outcome exists?
122  + (ld->outcome == nullptr ? 0
123  : sizeof(ld->outcome->cost) // cost
124  + sizeof(uint32_t) // probabilities size
125  + sizeof(ACTION_SCORE::action_score) * ld->outcome->probabilities.size()) // probabilities
126  + sizeof(uint32_t) // explicit_included_actions size
127  + sizeof(uint32_t) * ld->explicit_included_actions.size() + sizeof(ld->weight);
128 
129  cache.buf_write(c, size);
130 
131  *(uint8_t*)c = static_cast<uint8_t>(ld->type);
132  c += sizeof(ld->type);
133 
134  *(bool*)c = ld->outcome != nullptr;
135  c += sizeof(bool);
136 
137  if (ld->outcome != nullptr)
138  {
139  *(float*)c = ld->outcome->cost;
140  c += sizeof(ld->outcome->cost);
141 
142  *(uint32_t*)c = convert(ld->outcome->probabilities.size());
143  c += sizeof(uint32_t);
144 
145  for (const auto& score : ld->outcome->probabilities)
146  {
147  *(ACTION_SCORE::action_score*)c = score;
148  c += sizeof(ACTION_SCORE::action_score);
149  }
150  }
151 
152  *(uint32_t*)c = convert(ld->explicit_included_actions.size());
153  c += sizeof(uint32_t);
154 
155  for (const auto& included_action : ld->explicit_included_actions)
156  {
157  *(uint32_t*)c = included_action;
158  c += sizeof(included_action);
159  }
160 
161  *(float*)c = ld->weight;
162  c += sizeof(ld->weight);
163 }
float weight
Definition: ccb_label.h:36
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
size_t size() const
Definition: v_array.h:68
example_type type
Definition: ccb_label.h:32
void buf_write(char *&pointer, size_t n)
Definition: io_buf.cc:94
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
uint32_t convert(size_t number)
Definition: cache.cc:211
constexpr uint64_t c
Definition: rand48.cc:12
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ calculate_and_insert_interactions()

void CCB::calculate_and_insert_interactions ( example shared,
std::vector< example *>  actions,
std::vector< std::string > &  generated_interactions 
)

Definition at line 281 of file conditional_contextual_bandit.cc.

References ccb_id_namespace, example_predict::indices, INTERACTIONS::is_printable_namespace(), and INTERACTIONS::printable_start.

Referenced by learn_or_predict().

283 {
284  std::bitset<INTERACTIONS::printable_ns_size> found_namespaces;
285 
286  const auto original_size = generated_interactions.size();
287  for (size_t i = 0; i < original_size; i++)
288  {
289  auto interaction_copy = generated_interactions[i];
290  interaction_copy.push_back((char)ccb_id_namespace);
291  generated_interactions.push_back(interaction_copy);
292  }
293 
294  for (const auto& action : actions)
295  {
296  for (const auto& action_index : action->indices)
297  {
298  if (INTERACTIONS::is_printable_namespace(action_index) &&
299  !found_namespaces[action_index - INTERACTIONS::printable_start])
300  {
301  found_namespaces[action_index - INTERACTIONS::printable_start] = true;
302  generated_interactions.push_back({(char)action_index, (char)ccb_id_namespace});
303  }
304  }
305  }
306 
307  for (const auto& shared_index : shared->indices)
308  {
309  if (INTERACTIONS::is_printable_namespace(shared_index) &&
310  !found_namespaces[shared_index - INTERACTIONS::printable_start])
311  {
312  found_namespaces[shared_index - INTERACTIONS::printable_start] = true;
313  generated_interactions.push_back({(char)shared_index, (char)ccb_id_namespace});
314  }
315  }
316 }
v_array< namespace_index > indices
uint32_t action
Definition: search.h:19
constexpr bool is_printable_namespace(const unsigned char ns)
Definition: interactions.h:22
constexpr unsigned char printable_start
Definition: interactions.h:16
constexpr unsigned char ccb_id_namespace
Definition: constant.h:34

◆ ccb_explore_adf_setup()

LEARNER::base_learner * CCB::ccb_explore_adf_setup ( options_i options,
vw all 
)

Definition at line 626 of file conditional_contextual_bandit.cc.

References VW::config::option_group_definition::add(), VW::config::options_i::add_and_parse(), LEARNER::as_multiline(), label_type::ccb, ccb_id_namespace, ccb_label_parser, prediction_type::decision_probs, ACTION_SCORE::delete_action_scores(), vw::delete_prediction, finish_multiline_example(), VW::hash_space(), LEARNER::init_learner(), VW::config::options_i::insert(), vw::interactions, vw::label_type, parser::lp, LEARNER::make_base(), VW::config::make_option(), vw::p, LEARNER::learner< T, E >::set_finish_example(), setup_base(), parameters::stride_shift(), THROW, VW::config::options_i::was_supplied(), and vw::weights.

Referenced by parse_reductions().

627 {
628  auto data = scoped_calloc_or_throw<ccb>();
629  bool ccb_explore_adf_option = false;
630  bool slate = false;
631  option_group_definition new_options(
632  "EXPERIMENTAL: Conditional Contextual Bandit Exploration with Action Dependent Features");
633  new_options.add(
634  make_option("ccb_explore_adf", ccb_explore_adf_option)
635  .keep()
636  .help("EXPERIMENTAL: Do Conditional Contextual Bandit learning with multiline action dependent features."));
637  new_options.add(make_option("slate", slate).keep().help("EXPERIMENTAL - MAY CHANGE: Enable slate mode in CCB."));
638  options.add_and_parse(new_options);
639 
640  if (!ccb_explore_adf_option)
641  return nullptr;
642 
643  if (!options.was_supplied("cb_explore_adf"))
644  {
645  options.insert("cb_explore_adf", "");
646  options.add_and_parse(new_options);
647  }
648 
649  if (options.was_supplied("cb_sample") && slate)
650  {
651  THROW("--slate and --cb_sample cannot be supplied together");
652  }
653 
654  if (!options.was_supplied("cb_sample") && !slate)
655  {
656  options.insert("cb_sample", "");
657  options.add_and_parse(new_options);
658  }
659 
660  auto base = as_multiline(setup_base(options, all));
661  all.p->lp = CCB::ccb_label_parser;
663 
664  // Stash the base learners stride_shift so we can properly add a feature later.
665  data->base_learner_stride_shift = all.weights.stride_shift();
666 
667  // Extract from lower level reductions
668  data->default_cb_label = {FLT_MAX, 0, -1.f, 0.f};
669  data->shared = nullptr;
670  data->original_interactions = &all.interactions;
671  data->all = &all;
672 
673  data->id_namespace_str.push_back((char)ccb_id_namespace);
674  data->id_namespace_str.append("_id");
675  data->id_namespace_hash = VW::hash_space(all, data->id_namespace_str);
676 
678  init_learner(data, base, learn_or_predict<true>, learn_or_predict<false>, 1, prediction_type::decision_probs);
679 
681 
683  return make_base(l);
684 }
parameters weights
Definition: global_data.h:537
void(* delete_prediction)(void *)
Definition: global_data.h:485
void finish_multiline_example(vw &all, cbify &, multi_ex &ec_seq)
Definition: cbify.cc:373
label_type::label_type_t label_type
Definition: global_data.h:550
base_learner * make_base(learner< T, E > &base)
Definition: learner.h:462
virtual void add_and_parse(const option_group_definition &group)=0
label_parser ccb_label_parser
Definition: ccb_label.cc:358
parser * p
Definition: global_data.h:377
void set_finish_example(void(*f)(vw &all, T &, E &))
Definition: learner.h:307
learner< T, E > & init_learner(free_ptr< T > &dat, L *base, void(*learn)(T &, L &, E &), void(*predict)(T &, L &, E &), size_t ws, prediction_type::prediction_type_t pred_type)
Definition: learner.h:369
void delete_action_scores(void *v)
Definition: action_score.cc:29
virtual bool was_supplied(const std::string &key)=0
virtual void insert(const std::string &key, const std::string &value)=0
typed_option< T > make_option(std::string name, T &location)
Definition: options.h:80
std::vector< std::string > interactions
Definition: global_data.h:457
uint64_t hash_space(vw &all, const std::string &s)
Definition: vw.h:138
uint32_t stride_shift()
LEARNER::base_learner * setup_base(options_i &options, vw &all)
Definition: parse_args.cc:1222
#define THROW(args)
Definition: vw_exception.h:181
multi_learner * as_multiline(learner< T, E > *l)
Definition: learner.h:468
constexpr unsigned char ccb_id_namespace
Definition: constant.h:34
label_parser lp
Definition: parser.h:102

◆ ccb_weight()

float CCB::ccb_weight ( void *  v)

Definition at line 110 of file ccb_label.cc.

References CCB::label::weight.

111 {
112  CCB::label* ld = (CCB::label*)v;
113  return ld->weight;
114 }
float weight
Definition: ccb_label.h:36

◆ clear_all()

void CCB::clear_all ( ccb data)

Definition at line 60 of file conditional_contextual_bandit.cc.

References ccb::action_with_label, ccb::actions, ccb::shared, ccb::slots, and ccb::stored_labels.

Referenced by learn_or_predict().

61 {
62  // data.include_list and data.exclude_list aren't cleared here but are assigned in the predict/learn function
63  data.shared = nullptr;
64  data.actions.clear();
65  data.slots.clear();
66  data.action_with_label = 0;
67  data.stored_labels.clear();
68 }
std::vector< CCB::label > stored_labels
std::vector< example * > actions
std::vector< example * > slots

◆ clear_pred_and_label()

void CCB::clear_pred_and_label ( ccb data)

Definition at line 175 of file conditional_contextual_bandit.cc.

References ccb::action_with_label, and ccb::actions.

Referenced by learn_or_predict().

176 {
177  // Don't need to return to pool, as that will be done when the example is output.
178 
179  // This just needs to be cleared as it is reused.
180  data.actions[data.action_with_label]->l.cb.costs.clear();
181 }
std::vector< example * > actions

◆ convert_to_score()

ACTION_SCORE::action_score CCB::convert_to_score ( const substring action_id_str,
const substring probability_str 
)

Definition at line 219 of file ccb_label.cc.

References float_of_substring(), int_of_substring(), and THROW.

Referenced by parse_outcome().

220 {
221  auto action_id = static_cast<uint32_t>(int_of_substring(action_id_str));
222  auto probability = float_of_substring(probability_str);
223  if (std::isnan(probability))
224  THROW("error NaN probability: " << probability_str);
225 
226  if (probability > 1.0)
227  {
228  std::cerr << "invalid probability > 1 specified for an outcome, resetting to 1.\n";
229  probability = 1.0;
230  }
231  if (probability < 0.0)
232  {
233  std::cerr << "invalid probability < 0 specified for an outcome, resetting to 0.\n";
234  probability = .0;
235  }
236 
237  return {action_id, probability};
238 }
int int_of_substring(substring s)
float float_of_substring(substring s)
#define THROW(args)
Definition: vw_exception.h:181

◆ copy_label()

void CCB::copy_label ( void *  dst,
void *  src 
)

Definition at line 200 of file ccb_label.cc.

References copy_array(), CCB::conditional_contextual_bandit_outcome::cost, CCB::label::explicit_included_actions, CCB::label::outcome, CCB::conditional_contextual_bandit_outcome::probabilities, CCB::label::type, and CCB::label::weight.

201 {
202  CCB::label* ldDst = static_cast<CCB::label*>(dst);
203  CCB::label* ldSrc = static_cast<CCB::label*>(src);
204 
205  if (ldSrc->outcome)
206  {
208  ldDst->outcome->probabilities = v_init<ACTION_SCORE::action_score>();
209 
210  ldDst->outcome->cost = ldSrc->outcome->cost;
212  }
213 
215  ldDst->type = ldSrc->type;
216  ldDst->weight = ldSrc->weight;
217 }
void copy_array(v_array< T > &dst, const v_array< T > &src)
Definition: v_array.h:185
float weight
Definition: ccb_label.h:36
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
example_type type
Definition: ccb_label.h:32
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ create_cb_labels()

void CCB::create_cb_labels ( ccb data)

Definition at line 125 of file conditional_contextual_bandit.cc.

References ccb::actions, polylabel::cb, ccb::cb_label_pool, CB::label::costs, ccb::default_cb_label, example::l, ccb::shared, and CB::label::weight.

Referenced by learn_or_predict().

126 {
127  data.shared->l.cb.costs = data.cb_label_pool.get_object();
128  data.shared->l.cb.costs.push_back(data.default_cb_label);
129  for (example* action : data.actions)
130  {
131  action->l.cb.costs = data.cb_label_pool.get_object();
132  }
133  data.shared->l.cb.weight = 1.0;
134 }
VW::v_array_pool< CB::cb_class > cb_label_pool
CB::cb_class default_cb_label
float weight
Definition: cb.h:28
CB::label cb
Definition: example.h:31
v_array< cb_class > costs
Definition: cb.h:27
std::vector< example * > actions
uint32_t action
Definition: search.h:19
polylabel l
Definition: example.h:57

◆ default_label()

void CCB::default_label ( void *  v)

Definition at line 165 of file ccb_label.cc.

References v_array< T >::clear(), v_array< T >::delete_v(), CCB::label::explicit_included_actions, CCB::label::outcome, CCB::conditional_contextual_bandit_outcome::probabilities, CCB::label::type, unset, and CCB::label::weight.

Referenced by read_cached_label().

166 {
167  CCB::label* ld = static_cast<CCB::label*>(v);
168 
169  // This is tested against nullptr, so unfortunately as things are this must be deleted when not used.
170  if (ld->outcome)
171  {
173  delete ld->outcome;
174  ld->outcome = nullptr;
175  }
176 
179  ld->weight = 1.0;
180 }
float weight
Definition: ccb_label.h:36
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
void clear()
Definition: v_array.h:88
example_type type
Definition: ccb_label.h:32
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
void delete_v()
Definition: v_array.h:98
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ delete_cb_labels()

void CCB::delete_cb_labels ( ccb data)

Definition at line 137 of file conditional_contextual_bandit.cc.

References ccb::actions, polylabel::cb, ccb::cb_label_pool, CB::label::costs, example::l, return_v_array(), and ccb::shared.

Referenced by learn_or_predict().

138 {
140 
141  for (example* action : data.actions)
142  {
143  return_v_array(action->l.cb.costs, data.cb_label_pool);
144  }
145 }
VW::v_array_pool< CB::cb_class > cb_label_pool
void return_v_array(v_array< T > &array, VW::v_array_pool< T > &pool)
CB::label cb
Definition: example.h:31
v_array< cb_class > costs
Definition: cb.h:27
std::vector< example * > actions
uint32_t action
Definition: search.h:19
polylabel l
Definition: example.h:57

◆ delete_label()

void CCB::delete_label ( void *  v)

Definition at line 188 of file ccb_label.cc.

References v_array< T >::delete_v(), CCB::label::explicit_included_actions, CCB::label::outcome, and CCB::conditional_contextual_bandit_outcome::probabilities.

189 {
190  CCB::label* ld = static_cast<CCB::label*>(v);
191  if (ld->outcome)
192  {
194  delete ld->outcome;
195  ld->outcome = nullptr;
196  }
198 }
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
void delete_v()
Definition: v_array.h:98
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ ec_is_example_header()

bool CCB::ec_is_example_header ( example const &  ec)

Definition at line 686 of file conditional_contextual_bandit.cc.

References polylabel::conditional_contextual_bandit, example::l, shared, and CCB::label::type.

Referenced by LEARNER::example_is_newline_not_header().

686 { return ec.l.conditional_contextual_bandit.type == example_type::shared; }

◆ finish_multiline_example()

void CCB::finish_multiline_example ( vw all,
ccb data,
multi_ex ec_seq 
)

Definition at line 609 of file conditional_contextual_bandit.cc.

References ccb::action_score_pool, vw::final_prediction_sink, VW::finish_example(), CB_ADF::global_print_newline(), output_example(), and return_v_array().

610 {
611  if (ec_seq.size() > 0)
612  {
613  output_example(all, data, ec_seq);
615  }
616 
617  for (auto& a_s : ec_seq[0]->pred.decision_scores)
618  {
620  }
621  ec_seq[0]->pred.decision_scores.clear();
622 
623  VW::finish_example(all, ec_seq);
624 }
void return_v_array(v_array< T > &array, VW::v_array_pool< T > &pool)
VW::v_array_pool< ACTION_SCORE::action_score > action_score_pool
v_array< int > final_prediction_sink
Definition: global_data.h:518
void global_print_newline(const v_array< int > &final_prediction_sink)
Definition: cb_adf.cc:342
void finish_example(vw &, example &)
Definition: parser.cc:881
void output_example(vw &all, ccb &, multi_ex &ec_seq)

◆ has_action()

bool CCB::has_action ( multi_ex cb_ex)

Definition at line 184 of file conditional_contextual_bandit.cc.

Referenced by learn_or_predict().

184 { return !cb_ex.empty(); }

◆ inject_slot_features()

void CCB::inject_slot_features ( example shared,
example slot 
)

Definition at line 190 of file conditional_contextual_bandit.cc.

References LabelDict::add_example_namespace(), ccb_slot_namespace, constant_namespace, default_namespace, example_predict::feature_space, and example_predict::indices.

Referenced by build_cb_example().

191 {
192  for (auto index : slot->indices)
193  {
194  // constant namespace should be ignored, as it already exists and we don't want to double it up.
195  if (index == constant_namespace)
196  {
197  continue;
198  }
199  else if (index == default_namespace) // slot default namespace has a special namespace in shared
200  {
202  }
203  else
204  {
205  LabelDict::add_example_namespace(*shared, index, slot->feature_space[index]);
206  }
207  }
208 }
v_array< namespace_index > indices
constexpr unsigned char default_namespace
Definition: constant.h:19
constexpr unsigned char ccb_slot_namespace
Definition: constant.h:33
std::array< features, NUM_NAMESPACES > feature_space
void add_example_namespace(example &ec, namespace_index ns, features &fs)
constexpr unsigned char constant_namespace
Definition: constant.h:22

◆ inject_slot_id()

template<bool audit>
void CCB::inject_slot_id ( ccb data,
example shared,
size_t  id 
)

Definition at line 211 of file conditional_contextual_bandit.cc.

References ccb::all, ccb::base_learner_stride_shift, ccb_id_namespace, example_predict::feature_space, VW::hash_feature(), id(), ccb::id_namespace_hash, ccb::id_namespace_str, example_predict::indices, v_array< T >::push_back(), ccb::slot_id_hashes, prediction_type::to_string(), and vw::wpp.

212 {
213  // id is zero based, so the vector must be of size id + 1
214  if (id + 1 > data.slot_id_hashes.size())
215  {
216  data.slot_id_hashes.resize(id + 1, 0);
217  }
218 
219  uint64_t index;
220  if (data.slot_id_hashes[id] == 0)
221  {
222  auto current_index_str = "index" + std::to_string(id);
223  index = VW::hash_feature(*data.all, current_index_str, data.id_namespace_hash);
224 
225  // To maintain indicies consistent with what the parser does we must scale.
226  index *= static_cast<uint64_t>(data.all->wpp) << data.base_learner_stride_shift;
227  data.slot_id_hashes[id] = index;
228  }
229  else
230  {
231  index = data.slot_id_hashes[id];
232  }
233 
234  shared->feature_space[ccb_id_namespace].push_back(1., index);
236 
237  if (audit)
238  {
239  auto current_index_str = "index" + std::to_string(id);
240  shared->feature_space[ccb_id_namespace].space_names.push_back(
241  audit_strings_ptr(new audit_strings(data.id_namespace_str, current_index_str)));
242  }
243 }
v_array< namespace_index > indices
std::shared_ptr< audit_strings > audit_strings_ptr
Definition: feature_group.h:23
std::array< features, NUM_NAMESPACES > feature_space
void push_back(const T &new_ele)
Definition: v_array.h:107
float id(float in)
Definition: scorer.cc:51
uint32_t wpp
Definition: global_data.h:432
uint64_t id_namespace_hash
size_t base_learner_stride_shift
uint64_t hash_feature(vw &all, const std::string &s, uint64_t u)
Definition: vw.h:153
std::vector< uint64_t > slot_id_hashes
std::string id_namespace_str
const char * to_string(prediction_type_t prediction_type)
Definition: learner.cc:12
constexpr unsigned char ccb_id_namespace
Definition: constant.h:34
std::pair< std::string, std::string > audit_strings
Definition: feature_group.h:22

◆ learn_or_predict()

template<bool is_learn>
void CCB::learn_or_predict ( ccb data,
multi_learner base,
multi_ex examples 
)

Definition at line 385 of file conditional_contextual_bandit.cc.

References ccb::actions, ccb::all, vw::audit, calculate_and_insert_interactions(), ccb::cb_ex, clear_all(), clear_pred_and_label(), create_cb_labels(), delete_cb_labels(), ccb::exclude_list, ccb::generated_interactions, has_action(), ccb::include_list, example_predict::interactions, ccb::original_interactions, remove_slot_features(), save_action_scores(), ccb::shared, slot, ccb::slots, split_multi_example_and_stash_labels(), ccb::stored_labels, and example::tag.

386 {
387  clear_all(data);
388  if (!split_multi_example_and_stash_labels(examples, data)) // split shared, actions and slots
389  return;
390 
391 #ifndef NDEBUG
392  if (!sanity_checks<is_learn>(data))
393  return;
394 #endif
395 
396  // This will overwrite the labels with CB.
397  create_cb_labels(data);
398 
399  // Reset exclusion list for this example.
400  data.exclude_list.assign(data.actions.size(), false);
401 
402  auto decision_scores = examples[0]->pred.decision_scores;
403 
404  // for each slot, re-build the cb example and call cb_explore_adf
405  size_t slot_id = 0;
406  for (example* slot : data.slots)
407  {
408  // Namespace crossing for slot features.
409  data.generated_interactions.clear();
410  std::copy(data.original_interactions->begin(), data.original_interactions->end(),
411  std::back_inserter(data.generated_interactions));
414  for (auto ex : data.actions)
415  {
416  ex->interactions = &data.generated_interactions;
417  }
418 
419  data.include_list.clear();
420  build_cb_example<is_learn>(data.cb_ex, slot, data);
421 
422  if (data.all->audit)
423  inject_slot_id<true>(data, data.shared, slot_id);
424  else
425  inject_slot_id<false>(data, data.shared, slot_id);
426 
427  if (has_action(data.cb_ex))
428  {
429  // the cb example contains at least 1 action
430  multiline_learn_or_predict<is_learn>(base, data.cb_ex, examples[0]->ft_offset);
431  save_action_scores(data, decision_scores);
432  clear_pred_and_label(data);
433  }
434  else
435  {
436  // the cb example contains no action => cannot decide
437  decision_scores.push_back(data.action_score_pool.get_object());
438  }
439 
440  data.shared->interactions = data.original_interactions;
441  for (auto ex : data.actions)
442  {
443  ex->interactions = data.original_interactions;
444  }
445  remove_slot_features(data.shared, slot);
446 
447  if (data.all->audit)
448  remove_slot_id<true>(data.shared);
449  else
450  remove_slot_id<false>(data.shared);
451 
452  // Put back the original shared example tag.
453  std::swap(data.shared->tag, slot->tag);
454  slot_id++;
455  data.cb_ex.clear();
456  }
457 
458  delete_cb_labels(data);
459 
460  // Restore ccb labels to the example objects.
461  for (size_t i = 0; i < examples.size(); i++)
462  {
463  examples[i]->l.conditional_contextual_bandit = {
464  data.stored_labels[i].type, data.stored_labels[i].outcome, data.stored_labels[i].explicit_included_actions, 0.};
465  }
466 
467  // Save the predictions
468  examples[0]->pred.decision_scores = decision_scores;
469 }
v_array< char > tag
Definition: example.h:63
void clear_all(ccb &data)
std::vector< std::string > * interactions
std::vector< example * > actions
std::vector< bool > exclude_list
std::vector< example * > slots
bool split_multi_example_and_stash_labels(const multi_ex &examples, ccb &data)
void delete_cb_labels(ccb &data)
bool has_action(multi_ex &cb_ex)
void clear_pred_and_label(ccb &data)
void create_cb_labels(ccb &data)
void save_action_scores(ccb &data, decision_scores_t &decision_scores)
std::vector< bool > include_list
bool audit
Definition: global_data.h:486
std::vector< std::string > * original_interactions
void remove_slot_features(example *shared, example *slot)
std::vector< std::string > generated_interactions
void calculate_and_insert_interactions(example *shared, std::vector< example *> actions, std::vector< std::string > &generated_interactions)

◆ output_example()

void CCB::output_example ( vw all,
ccb ,
multi_ex ec_seq 
)

Definition at line 557 of file conditional_contextual_bandit.cc.

References vw::final_prediction_sink, CB_ALGS::get_cost_estimate(), loss(), print_decision_scores(), print_update(), vw::sd, slot, TOP_ACTION_INDEX, and shared_data::update().

Referenced by finish_multiline_example().

558 {
559  if (ec_seq.size() <= 0)
560  return;
561 
562  std::vector<example*> slots;
563  size_t num_features = 0;
564  float loss = 0.;
565 
566  // Should this be done for shared, action and slot?
567  for (auto ec : ec_seq)
568  {
569  num_features += ec->num_features;
570 
571  if (ec->l.conditional_contextual_bandit.type == CCB::example_type::slot)
572  {
573  slots.push_back(ec);
574  }
575  }
576 
577  // Is it hold out?
578  size_t num_labelled = 0;
579  auto preds = ec_seq[0]->pred.decision_scores;
580  for (size_t i = 0; i < slots.size(); i++)
581  {
582  auto outcome = slots[i]->l.conditional_contextual_bandit.outcome;
583  if (outcome != nullptr)
584  {
585  num_labelled++;
586  float l = CB_ALGS::get_cost_estimate(
587  outcome->probabilities[TOP_ACTION_INDEX], outcome->cost, preds[i][TOP_ACTION_INDEX].action);
588  loss += l * preds[i][TOP_ACTION_INDEX].score;
589  }
590  }
591 
592  if (num_labelled > 0 && num_labelled < slots.size())
593  {
594  std::cerr << "Warning: Unlabeled example in train set, was this intentional?\n";
595  }
596 
597  bool holdout_example = num_labelled > 0;
598  for (size_t i = 0; i < ec_seq.size(); i++) holdout_example &= ec_seq[i]->test_only;
599 
600  // TODO what does weight mean here?
601  all.sd->update(holdout_example, num_labelled > 0, loss, ec_seq[SHARED_EX_INDEX]->weight, num_features);
602 
603  for (auto sink : all.final_prediction_sink)
604  print_decision_scores(sink, ec_seq[SHARED_EX_INDEX]->pred.decision_scores);
605 
606  CCB::print_update(all, slots, preds, num_features);
607 }
void print_decision_scores(int f, decision_scores_t &decision_scores)
v_array< int > final_prediction_sink
Definition: global_data.h:518
float loss(cbify &data, uint32_t label, uint32_t final_prediction)
Definition: cbify.cc:60
float get_cost_estimate(CB::cb_class *observation, uint32_t action, float offset=0.)
Definition: cb_algs.h:58
void print_update(vw &all, std::vector< example *> &slots, decision_scores_t &decision_scores, size_t num_features)
static constexpr uint32_t TOP_ACTION_INDEX
shared_data * sd
Definition: global_data.h:375
void update(bool test_example, bool labeled_example, float loss, float weight, size_t num_features)
Definition: global_data.h:190
static constexpr uint32_t SHARED_EX_INDEX
float weight

◆ parse_explicit_inclusions()

void CCB::parse_explicit_inclusions ( CCB::label ld,
v_array< substring > &  split_inclusions 
)

Definition at line 277 of file ccb_label.cc.

References CCB::label::explicit_included_actions, int_of_substring(), and v_array< T >::push_back().

Referenced by parse_label().

278 {
279  for (const auto& inclusion : split_inclusions)
280  {
282  }
283 }
int int_of_substring(substring s)
void push_back(const T &new_ele)
Definition: v_array.h:107
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35

◆ parse_label()

void CCB::parse_label ( parser p,
shared_data ,
void *  v,
v_array< substring > &  words 
)

Definition at line 285 of file ccb_label.cc.

References accumulate(), v_array< T >::begin(), v_array< T >::end(), f, recall_tree_ns::find(), CCB::label::outcome, parse_explicit_inclusions(), parser::parse_name, parse_outcome(), CCB::conditional_contextual_bandit_outcome::probabilities, shared, v_array< T >::size(), slot, substring_equal(), THROW, tokenize(), CCB::label::type, and CCB::label::weight.

286 {
287  CCB::label* ld = static_cast<CCB::label*>(v);
288  ld->weight = 1.0;
289 
290  if (words.size() < 2)
291  THROW("ccb labels may not be empty");
292  if (!substring_equal(words[0], "ccb"))
293  {
294  THROW("ccb labels require the first word to be ccb");
295  }
296 
297  auto type = words[1];
298  if (substring_equal(type, "shared"))
299  {
300  if (words.size() > 2)
301  THROW("shared labels may not have a cost");
303  }
304  else if (substring_equal(type, "action"))
305  {
306  if (words.size() > 2)
307  THROW("action labels may not have a cost");
309  }
310  else if (substring_equal(type, "slot"))
311  {
312  if (words.size() > 4)
313  THROW("ccb slot label can only have a type cost and exclude list");
315 
316  // Skip the first two words "ccb <type>"
317  for (size_t i = 2; i < words.size(); i++)
318  {
319  auto is_outcome = std::find(words[i].begin, words[i].end, ':');
320  if (is_outcome != words[i].end)
321  {
322  if (ld->outcome != nullptr)
323  {
324  THROW("There may be only 1 outcome associated with a slot.")
325  }
326 
327  ld->outcome = parse_outcome(words[i]);
328  }
329  else
330  {
331  tokenize(',', words[i], p->parse_name);
333  }
334  }
335 
336  // If a full distribution has been given, check if it sums to 1, otherwise throw.
337  if (ld->outcome && ld->outcome->probabilities.size() > 1)
338  {
339  float total_pred = std::accumulate(ld->outcome->probabilities.begin(), ld->outcome->probabilities.end(), 0.f,
340  [](float result_so_far, ACTION_SCORE::action_score action_pred) {
341  return result_so_far + action_pred.score;
342  });
343 
344  // TODO do a proper comparison here.
345  if (total_pred > 1.1f || total_pred < 0.9f)
346  {
347  THROW("When providing all predicition probabilties they must add up to 1.f");
348  }
349  }
350  }
351  else
352  {
353  THROW("unknown label type: " << type);
354  }
355 }
void accumulate(vw &all, parameters &weights, size_t offset)
Definition: accumulate.cc:20
CCB::conditional_contextual_bandit_outcome * parse_outcome(substring &outcome)
Definition: ccb_label.cc:241
uint32_t action
Definition: search.h:19
float weight
Definition: ccb_label.h:36
v_array< substring > parse_name
Definition: parser.h:100
T *& begin()
Definition: v_array.h:42
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
size_t size() const
Definition: v_array.h:68
void parse_explicit_inclusions(CCB::label *ld, v_array< substring > &split_inclusions)
Definition: ccb_label.cc:277
void tokenize(char delim, substring s, ContainerT &ret, bool allow_empty=false)
T *& end()
Definition: v_array.h:43
example_type type
Definition: ccb_label.h:32
node_pred * find(recall_tree &b, uint32_t cn, example &ec)
Definition: recall_tree.cc:126
bool substring_equal(const substring &a, const substring &b)
#define THROW(args)
Definition: vw_exception.h:181
float f
Definition: cache.cc:40
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

◆ parse_outcome()

CCB::conditional_contextual_bandit_outcome* CCB::parse_outcome ( substring outcome)

Definition at line 241 of file ccb_label.cc.

References convert_to_score(), float_of_substring(), THROW, and tokenize().

Referenced by parse_label().

242 {
243  auto& ccb_outcome = *(new CCB::conditional_contextual_bandit_outcome());
244 
245  auto split_commas = v_init<substring>();
246  tokenize(',', outcome, split_commas);
247 
248  auto split_colons = v_init<substring>();
249  tokenize(':', split_commas[0], split_colons);
250 
251  if (split_colons.size() != 3)
252  THROW("Malformed ccb label");
253 
254  ccb_outcome.probabilities = v_init<ACTION_SCORE::action_score>();
255  ccb_outcome.probabilities.push_back(convert_to_score(split_colons[0], split_colons[2]));
256 
257  ccb_outcome.cost = float_of_substring(split_colons[1]);
258  if (std::isnan(ccb_outcome.cost))
259  THROW("error NaN cost: " << split_colons[1]);
260 
261  split_colons.clear();
262 
263  for (size_t i = 1; i < split_commas.size(); i++)
264  {
265  tokenize(':', split_commas[i], split_colons);
266  if (split_colons.size() != 2)
267  THROW("Must be action probability pairs");
268  ccb_outcome.probabilities.push_back(convert_to_score(split_colons[0], split_colons[1]));
269  }
270 
271  split_colons.delete_v();
272  split_commas.delete_v();
273 
274  return &ccb_outcome;
275 }
float float_of_substring(substring s)
void tokenize(char delim, substring s, ContainerT &ret, bool allow_empty=false)
ACTION_SCORE::action_score convert_to_score(const substring &action_id_str, const substring &probability_str)
Definition: ccb_label.cc:219
#define THROW(args)
Definition: vw_exception.h:181

◆ print_decision_scores()

void CCB::print_decision_scores ( int  f,
decision_scores_t decision_scores 
)

Definition at line 471 of file conditional_contextual_bandit.cc.

References slot, and io_buf::write_file_or_socket().

Referenced by output_example().

472 {
473  if (f >= 0)
474  {
475  std::stringstream ss;
476  for (auto slot : decision_scores)
477  {
478  std::string delimiter = "";
479  for (auto action_score : slot)
480  {
481  ss << delimiter << action_score.action << ':' << action_score.score;
482  delimiter = ",";
483  }
484  ss << '\n';
485  }
486  ssize_t len = ss.str().size();
487  ssize_t t = io_buf::write_file_or_socket(f, ss.str().c_str(), (unsigned int)len);
488  if (t != len)
489  std::cerr << "write error: " << strerror(errno) << std::endl;
490  }
491 }
static ssize_t write_file_or_socket(int f, const void *buf, size_t nbytes)
Definition: io_buf.cc:140
float f
Definition: cache.cc:40

◆ print_update()

void CCB::print_update ( vw all,
std::vector< example *> &  slots,
decision_scores_t decision_scores,
size_t  num_features 
)

Definition at line 493 of file conditional_contextual_bandit.cc.

References vw::bfgs, shared_data::col_current_label, shared_data::col_current_predict, vw::current_pass, shared_data::dump_interval, vw::holdout_set_off, shared_data::print_update(), vw::progress_add, vw::progress_arg, vw::quiet, vw::sd, slot, prediction_type::to_string(), and shared_data::weighted_examples().

Referenced by output_example().

494 {
495  if (all.sd->weighted_examples() >= all.sd->dump_interval && !all.quiet && !all.bfgs)
496  {
497  std::string label_str = "";
498  std::string delim = "";
499  int counter = 0;
500  for (auto slot : slots)
501  {
502  counter++;
503 
504  auto outcome = slot->l.conditional_contextual_bandit.outcome;
505  if (outcome == nullptr)
506  {
507  label_str += delim;
508  label_str += "?";
509  }
510  else
511  {
512  label_str += delim;
513  label_str += std::to_string(outcome->probabilities[0].action);
514  label_str += ":";
515  label_str += std::to_string(outcome->cost);
516  }
517 
518  delim = ",";
519 
520  // Stop after 2...
521  if (counter > 1 && slots.size() > 2)
522  {
523  label_str += delim;
524  label_str += "...";
525  break;
526  }
527  }
528  std::ostringstream label_buf;
529  label_buf << std::setw(all.sd->col_current_label) << std::right << std::setfill(' ') << label_str;
530 
531  std::string pred_str = "";
532  delim = "";
533  counter = 0;
534  for (auto slot : decision_scores)
535  {
536  counter++;
537  pred_str += delim;
538  pred_str += std::to_string(slot[0].action);
539  delim = ",";
540 
541  // Stop after 3...
542  if (counter > 2)
543  {
544  pred_str += delim;
545  pred_str += "...";
546  break;
547  }
548  }
549  std::ostringstream pred_buf;
550  pred_buf << std::setw(all.sd->col_current_predict) << std::right << std::setfill(' ') << pred_str;
551 
552  all.sd->print_update(all.holdout_set_off, all.current_pass, label_buf.str(), pred_buf.str(), num_features,
553  all.progress_add, all.progress_arg);
554  }
555 }
static constexpr int col_current_label
Definition: global_data.h:182
uint32_t action
Definition: search.h:19
bool quiet
Definition: global_data.h:487
bool holdout_set_off
Definition: global_data.h:499
bool progress_add
Definition: global_data.h:545
shared_data * sd
Definition: global_data.h:375
float progress_arg
Definition: global_data.h:546
void print_update(bool holdout_set_off, size_t current_pass, float label, float prediction, size_t num_features, bool progress_add, float progress_arg)
Definition: global_data.h:225
bool bfgs
Definition: global_data.h:412
uint64_t current_pass
Definition: global_data.h:396
static constexpr int col_current_predict
Definition: global_data.h:184
double weighted_examples()
Definition: global_data.h:188
float dump_interval
Definition: global_data.h:147
const char * to_string(prediction_type_t prediction_type)
Definition: learner.cc:12

◆ read_cached_label()

size_t CCB::read_cached_label ( shared_data ,
void *  v,
io_buf cache 
)

Definition at line 26 of file ccb_label.cc.

References io_buf::buf_read(), v_array< T >::clear(), CCB::conditional_contextual_bandit_outcome::cost, default_label(), CCB::label::explicit_included_actions, CCB::label::outcome, CCB::conditional_contextual_bandit_outcome::probabilities, v_array< T >::push_back(), CCB::label::type, and CCB::label::weight.

27 {
28  // Since read_cached_features doesn't default the label we must do it here.
29  default_label(v);
30  CCB::label* ld = static_cast<CCB::label*>(v);
31 
32  if (ld->outcome)
33  {
35  }
37 
38  size_t read_count = 0;
39  char* read_ptr;
40 
41  size_t next_read_size = sizeof(ld->type);
42  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
43  return 0;
44  ld->type = *(CCB::example_type*)read_ptr;
45  read_count += sizeof(ld->type);
46 
47  bool is_outcome_present;
48  next_read_size = sizeof(bool);
49  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
50  return 0;
51  is_outcome_present = *(bool*)read_ptr;
52  read_count += sizeof(is_outcome_present);
53 
54  if (is_outcome_present)
55  {
57  ld->outcome->probabilities = v_init<ACTION_SCORE::action_score>();
58 
59  next_read_size = sizeof(ld->outcome->cost);
60  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
61  return 0;
62  ld->outcome->cost = *(float*)read_ptr;
63  read_count += sizeof(ld->outcome->cost);
64 
65  uint32_t size_probs;
66  next_read_size = sizeof(size_probs);
67  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
68  return 0;
69  size_probs = *(uint32_t*)read_ptr;
70  read_count += sizeof(size_probs);
71 
72  for (uint32_t i = 0; i < size_probs; i++)
73  {
75  next_read_size = sizeof(a_s);
76  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
77  return 0;
78  a_s = *(ACTION_SCORE::action_score*)read_ptr;
79  read_count += sizeof(a_s);
80 
82  }
83  }
84 
85  uint32_t size_includes;
86  next_read_size = sizeof(size_includes);
87  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
88  return 0;
89  size_includes = *(uint32_t*)read_ptr;
90  read_count += sizeof(size_includes);
91 
92  for (uint32_t i = 0; i < size_includes; i++)
93  {
94  uint32_t include;
95  next_read_size = sizeof(include);
96  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
97  return 0;
98  include = *(uint32_t*)read_ptr;
99  read_count += sizeof(include);
101  }
102 
103  next_read_size = sizeof(ld->weight);
104  if (cache.buf_read(read_ptr, next_read_size) < next_read_size)
105  return 0;
106  ld->weight = *(float*)read_ptr;
107  return read_count;
108 }
example_type
Definition: ccb_label.h:22
float weight
Definition: ccb_label.h:36
ACTION_SCORE::action_scores probabilities
Definition: ccb_label.h:19
void push_back(const T &new_ele)
Definition: v_array.h:107
void clear()
Definition: v_array.h:88
void default_label(void *v)
Definition: ccb_label.cc:165
example_type type
Definition: ccb_label.h:32
v_array< uint32_t > explicit_included_actions
Definition: ccb_label.h:35
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34
size_t buf_read(char *&pointer, size_t n)
Definition: io_buf.cc:12

◆ remove_slot_features()

void CCB::remove_slot_features ( example shared,
example slot 
)

Definition at line 259 of file conditional_contextual_bandit.cc.

References ccb_slot_namespace, constant_namespace, default_namespace, LabelDict::del_example_namespace(), example_predict::feature_space, and example_predict::indices.

Referenced by learn_or_predict().

260 {
261  for (auto index : slot->indices)
262  {
263  // constant namespace should be ignored, as it already exists and we don't want to double it up.
264  if (index == constant_namespace)
265  {
266  continue;
267  }
268 
269  else if (index == default_namespace) // slot default namespace has a special namespace in shared
270  {
272  }
273  else
274  {
275  LabelDict::del_example_namespace(*shared, index, slot->feature_space[index]);
276  }
277  }
278 }
v_array< namespace_index > indices
constexpr unsigned char default_namespace
Definition: constant.h:19
void del_example_namespace(example &ec, namespace_index ns, features &fs)
constexpr unsigned char ccb_slot_namespace
Definition: constant.h:33
std::array< features, NUM_NAMESPACES > feature_space
constexpr unsigned char constant_namespace
Definition: constant.h:22

◆ remove_slot_id()

template<bool audit>
void CCB::remove_slot_id ( example shared)

Definition at line 247 of file conditional_contextual_bandit.cc.

References ccb_id_namespace, example_predict::feature_space, example_predict::indices, and v_array< T >::pop().

248 {
249  shared->feature_space[ccb_id_namespace].indicies.pop();
250  shared->feature_space[ccb_id_namespace].values.pop();
251  shared->indices.pop();
252 
253  if (audit)
254  {
255  shared->feature_space[ccb_id_namespace].space_names.pop();
256  }
257 }
v_array< namespace_index > indices
T pop()
Definition: v_array.h:58
std::array< features, NUM_NAMESPACES > feature_space
constexpr unsigned char ccb_id_namespace
Definition: constant.h:34

◆ sanity_checks()

template<bool is_learn>
bool CCB::sanity_checks ( ccb data)

Definition at line 100 of file conditional_contextual_bandit.cc.

References ccb::actions, slot, and ccb::slots.

101 {
102  if (data.slots.size() > data.actions.size())
103  {
104  std::cerr << "ccb_adf_explore: badly formatted example - number of actions " << data.actions.size()
105  << " must be greater than the number of slots " << data.slots.size();
106  return false;
107  }
108 
109  if (is_learn)
110  {
111  for (auto slot : data.slots)
112  {
113  if (slot->l.conditional_contextual_bandit.outcome != nullptr &&
114  slot->l.conditional_contextual_bandit.outcome->probabilities.size() == 0)
115  {
116  std::cerr << "ccb_adf_explore: badly formatted example - missing label probability";
117  return false;
118  }
119  }
120  }
121  return true;
122 }
std::vector< example * > actions
std::vector< example * > slots

◆ save_action_scores()

void CCB::save_action_scores ( ccb data,
decision_scores_t decision_scores 
)

Definition at line 159 of file conditional_contextual_bandit.cc.

References polyprediction::a_s, ccb::exclude_list, ccb::origin_index, example::pred, v_array< T >::push_back(), and ccb::shared.

Referenced by learn_or_predict().

160 {
161  auto& pred = data.shared->pred.a_s;
162  decision_scores.push_back(pred);
163 
164  // correct indices: we want index relative to the original ccb multi-example, with no actions filtered
165  for (auto& action_score : pred)
166  {
167  action_score.action = data.origin_index[action_score.action];
168  }
169 
170  // Exclude the chosen action from next slots.
171  auto original_index_of_chosen_action = pred[0].action;
172  data.exclude_list[original_index_of_chosen_action] = true;
173 }
ACTION_SCORE::action_scores a_s
Definition: example.h:47
std::vector< bool > exclude_list
std::vector< uint32_t > origin_index
void push_back(const T &new_ele)
Definition: v_array.h:107
polyprediction pred
Definition: example.h:60

◆ split_multi_example_and_stash_labels()

bool CCB::split_multi_example_and_stash_labels ( const multi_ex examples,
ccb data 
)

Definition at line 71 of file conditional_contextual_bandit.cc.

References ccb::actions, shared, ccb::shared, slot, ccb::slots, and ccb::stored_labels.

Referenced by learn_or_predict().

72 {
73  for (auto ex : examples)
74  {
75  switch (ex->l.conditional_contextual_bandit.type)
76  {
78  data.shared = ex;
79  break;
81  data.actions.push_back(ex);
82  break;
83  case example_type::slot:
84  data.slots.push_back(ex);
85  break;
86  default:
87  std::cout << "ccb_adf_explore: badly formatted example - invalid example type";
88  return false;
89  }
90 
91  // Stash the CCB labels before rewriting them.
92  data.stored_labels.push_back({ex->l.conditional_contextual_bandit.type, ex->l.conditional_contextual_bandit.outcome,
93  ex->l.conditional_contextual_bandit.explicit_included_actions, 0.});
94  }
95 
96  return true;
97 }
std::vector< CCB::label > stored_labels
std::vector< example * > actions
uint32_t action
Definition: search.h:19
std::vector< example * > slots

◆ test_label()

bool CCB::test_label ( void *  v)

Definition at line 182 of file ccb_label.cc.

References CCB::label::outcome.

183 {
184  CCB::label* ld = static_cast<CCB::label*>(v);
185  return ld->outcome == nullptr;
186 }
conditional_contextual_bandit_outcome * outcome
Definition: ccb_label.h:34

Variable Documentation

◆ ccb_label_parser

label_parser CCB::ccb_label_parser
Initial value:
void delete_label(void *v)
Definition: ccb_label.cc:188
void parse_label(parser *p, shared_data *, void *v, v_array< substring > &words)
Definition: ccb_label.cc:285
size_t read_cached_label(shared_data *, void *v, io_buf &cache)
Definition: ccb_label.cc:26
void copy_label(void *dst, void *src)
Definition: ccb_label.cc:200
void default_label(void *v)
Definition: ccb_label.cc:165
void cache_label(void *v, io_buf &cache)
Definition: ccb_label.cc:116
bool test_label(void *v)
Definition: simple_label.cc:70
float ccb_weight(void *v)
Definition: ccb_label.cc:110

Definition at line 358 of file ccb_label.cc.

Referenced by ccb_explore_adf_setup().

◆ SHARED_EX_INDEX

constexpr uint32_t CCB::SHARED_EX_INDEX = 0
static

Definition at line 57 of file conditional_contextual_bandit.cc.

◆ TOP_ACTION_INDEX

constexpr uint32_t CCB::TOP_ACTION_INDEX = 0
static

Definition at line 58 of file conditional_contextual_bandit.cc.

Referenced by output_example().