Vowpal Wabbit
gen_cs_example.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) by respective owners including Yahoo!, Microsoft, and
3  individual contributors. All rights reserved. Released under a BSD (revised)
4  license as described in the file LICENSE.
5 */
6 #include <float.h>
7 
8 #include "vw.h"
9 #include "reductions.h"
10 #include "vw_exception.h"
11 #include "gen_cs_example.h"
12 
13 namespace GEN_CS
14 {
15 using namespace LEARNER;
16 using namespace CB_ALGS;
17 using namespace CB;
18 
19 constexpr inline bool observed_cost(cb_class* cl)
20 {
21  // cost observed for this action if it has non zero probability and cost != FLT_MAX
22  return (cl != nullptr && cl->cost != FLT_MAX && cl->probability > .0);
23 }
24 
26 {
27  for (auto& cl : ld.costs)
28  if (observed_cost(&cl))
29  return &cl;
30  return nullptr;
31 }
32 
33 float safe_probability(float prob)
34 {
35  if (prob <= 0.)
36  {
37  std::cout << "Probability " << prob << " is not possible, replacing with 1e-3. Fix your dataset. " << std::endl;
38  return 1e-3f;
39  }
40  else
41  return prob;
42 }
43 
44 // Multiline version
45 void gen_cs_example_ips(multi_ex& examples, COST_SENSITIVE::label& cs_labels, float clip_p)
46 {
47  cs_labels.costs.clear();
48  for (uint32_t i = 0; i < examples.size(); i++)
49  {
50  CB::label ld = examples[i]->l.cb;
51 
52  COST_SENSITIVE::wclass wc = {0., i, 0., 0.};
53  if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
54  wc.x = ld.costs[0].cost / safe_probability(std::max(ld.costs[0].probability, clip_p));
55  cs_labels.costs.push_back(wc);
56  }
57 }
58 
59 // Multiline version
61 {
62  cs_labels.costs.clear();
63  for (uint32_t i = 0; i < examples.size(); i++)
64  {
65  CB::label ld = examples[i]->l.cb;
66 
67  COST_SENSITIVE::wclass wc = {0., i, 0., 0.};
68  if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
69  wc.x = ld.costs[0].cost;
70  cs_labels.costs.push_back(wc);
71  }
72 }
73 
74 // Multiline version
76 {
77  cs_labels.costs.clear();
78  for (uint32_t i = 0; i < examples.size(); i++)
79  {
80  COST_SENSITIVE::wclass wc = {FLT_MAX, i, 0., 0.};
81  cs_labels.costs.push_back(wc);
82  }
83 }
84 
85 // single line version
86 void gen_cs_example_ips(cb_to_cs& c, CB::label& ld, COST_SENSITIVE::label& cs_ld, float clip_p)
87 {
88  // this implements the inverse propensity score method, where cost are importance weighted by the probability of the
89  // chosen action generate cost-sensitive example
90  cs_ld.costs.clear();
91  if (ld.costs.size() == 0 || (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX))
92  // this is a typical example where we can perform all actions
93  {
94  // in this case generate cost-sensitive example with all actions
95  for (uint32_t i = 1; i <= c.num_actions; i++)
96  {
97  COST_SENSITIVE::wclass wc = {0., i, 0., 0.};
98  if (c.known_cost != nullptr && i == c.known_cost->action)
99  {
100  // use importance weighted cost for observed action, 0 otherwise
101  wc.x = c.known_cost->cost / safe_probability(std::max(c.known_cost->probability, clip_p));
102 
103  // ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
104  // update the loss of this regressor
105  c.nb_ex_regressors++;
107  (1.0f / c.nb_ex_regressors) * ((c.known_cost->cost) * (c.known_cost->cost) - c.avg_loss_regressors);
108  c.last_pred_reg = 0;
110  }
111 
112  cs_ld.costs.push_back(wc);
113  }
114  }
115  else // this is an example where we can only perform a subset of the actions
116  {
117  // in this case generate cost-sensitive example with only allowed actions
118  for (auto& cl : ld.costs)
119  {
120  COST_SENSITIVE::wclass wc = {0., cl.action, 0., 0.};
121  if (c.known_cost != nullptr && cl.action == c.known_cost->action)
122  {
123  // use importance weighted cost for observed action, 0 otherwise
124  wc.x = c.known_cost->cost / safe_probability(std::max(c.known_cost->probability, clip_p));
125 
126  // ips can be thought as the doubly robust method with a fixed regressor that predicts 0 costs for everything
127  // update the loss of this regressor
128  c.nb_ex_regressors++;
130  (1.0f / c.nb_ex_regressors) * ((c.known_cost->cost) * (c.known_cost->cost) - c.avg_loss_regressors);
131  c.last_pred_reg = 0;
133  }
134 
135  cs_ld.costs.push_back(wc);
136  }
137  }
138 }
139 
141 {
142  c.action_sum += ec_seq.size();
143  c.event_sum++;
144 
145  c.mtr_ec_seq.clear();
146  cs_labels.costs.clear();
147  for (size_t i = 0; i < ec_seq.size(); i++)
148  {
149  CB::label ld = ec_seq[i]->l.cb;
150 
151  COST_SENSITIVE::wclass wc = {0, 0, 0, 0};
152 
153  if (ld.costs.size() == 1 && ld.costs[0].cost != FLT_MAX)
154  {
155  wc.x = ld.costs[0].cost;
156  c.mtr_example = (uint32_t)i;
157  c.mtr_ec_seq.push_back(ec_seq[i]);
158  cs_labels.costs.push_back(wc);
159  }
160  }
161 }
162 
163 void gen_cs_example_sm(multi_ex&, uint32_t chosen_action, float sign_offset, ACTION_SCORE::action_scores action_vals,
164  COST_SENSITIVE::label& cs_labels)
165 {
166  cs_labels.costs.clear();
167  for (uint32_t i = 0; i < action_vals.size(); i++)
168  {
169  uint32_t current_action = action_vals[i].action;
170  COST_SENSITIVE::wclass wc = {0., current_action, 0., 0.};
171 
172  if (current_action == chosen_action)
173  wc.x = action_vals[i].score + sign_offset;
174  else
175  wc.x = action_vals[i].score - sign_offset;
176 
177  // TODO: This clipping is conceptually unnecessary because the example weight for this instance should be close to
178  // 0.
179  if (wc.x > 100.)
180  wc.x = 100.0;
181  if (wc.x < -100.)
182  wc.x = -100.0;
183 
184  cs_labels.costs.push_back(wc);
185  }
186 }
187 } // namespace GEN_CS
void gen_cs_example_sm(multi_ex &, uint32_t chosen_action, float sign_offset, ACTION_SCORE::action_scores action_vals, COST_SENSITIVE::label &cs_labels)
cb_class * get_observed_cost(CB::label &ld)
v_array< cb_class > costs
Definition: cb.h:27
void gen_cs_example_dm(multi_ex &examples, COST_SENSITIVE::label &cs_labels)
size_t size() const
Definition: v_array.h:68
CB::cb_class * known_cost
Definition: cb.cc:15
uint32_t action
Definition: cb.h:18
float probability
Definition: cb.h:19
uint32_t num_actions
constexpr bool observed_cost(cb_class *cl)
void gen_cs_example_ips(multi_ex &examples, COST_SENSITIVE::label &cs_labels, float clip_p)
std::vector< example * > multi_ex
Definition: example.h:122
float safe_probability(float prob)
Definition: cb.h:25
float cost
Definition: cb.h:17
void gen_cs_example_mtr(cb_to_cs_adf &c, multi_ex &ec_seq, COST_SENSITIVE::label &cs_labels)
v_array< wclass > costs
constexpr uint64_t c
Definition: rand48.cc:12
void gen_cs_test_example(multi_ex &examples, COST_SENSITIVE::label &cs_labels)
float f
Definition: cache.cc:40