|
1 | | -# Методы офлайн-оценки политик в `Policyscope`: интуиция, формулы и ссылки на статьи |
| 1 | +# Методы офлайн-оценки политик в `Policyscope`: интуиция, формулы, доверительные интервалы |
2 | 2 |
|
3 | | -> Важно про отображение: в этом документе формулы даны в **plain-text формате** (без LaTeX-разметки `$$...$$`), чтобы текст одинаково читался на GitHub и в локальных Markdown-просмотрщиках без MathJax/KaTeX. |
| 3 | +> Важно про отображение: формулы в документе даны в **plain-text формате** (без обязательного LaTeX `$$...$$`), чтобы всё одинаково читалось на GitHub и в локальных Markdown-просмотрщиках. |
4 | 4 |
|
5 | | -Этот гайд покрывает все методы, реализованные в репозитории: |
| 5 | +## Что важно сразу |
6 | 6 |
|
7 | | -- On-policy baseline (`value_on_policy`) |
8 | | -- Replay (`replay_value`) |
9 | | -- IPS (`ips_value`) |
10 | | -- SNIPS (`snips_value`) |
11 | | -- DM / Direct Method (`dm_value`) |
12 | | -- DR / Doubly Robust (`dr_value`) |
13 | | -- SNDR / Self-Normalized DR (`sndr_value`) |
14 | | -- Switch-DR (`switch_dr_value`) |
15 | | -- Bootstrap CI для DR (`dr_with_bootstrap_ci`) |
| 7 | +- `IPS/SNIPS/DM/DR/SNDR/Switch-DR/Replay` — это **оценщики значения политики** (point estimators). |
| 8 | +- `Bootstrap CI` — это **не отдельный OPE-оценщик**, а процедура статистического вывода (inference), которая строит доверительный интервал вокруг выбранного оценщика. |
| 9 | + |
| 10 | +Иными словами, `dr_with_bootstrap_ci` — это обёртка «оценщик + интервал», а не «ещё один метод оценки политики» наравне с IPS/DR. |
16 | 11 |
|
17 | 12 | --- |
18 | 13 |
|
19 | 14 | ## 1) Единая постановка задачи |
20 | 15 |
|
21 | 16 | Есть логи политики A: `(x_i, a_i, r_i)`, где: |
22 | | - |
23 | 17 | - `x_i` — контекст, |
24 | 18 | - `a_i` — действие, выбранное логирующей политикой `pi_A`, |
25 | 19 | - `r_i` — наблюдаемая награда. |
26 | 20 |
|
27 | | -Нужно оценить ожидаемую ценность новой политики `pi_B`: |
| 21 | +Нужно оценить ценность новой политики `pi_B`: |
28 | 22 |
|
29 | 23 | ```text |
30 | 24 | V(pi_B) = E_x [ E_{a~pi_B(.|x)} [ r(x, a) ] ] |
31 | 25 | ``` |
32 | 26 |
|
33 | 27 | Ключевые обозначения: |
34 | | - |
35 | | -- `mu(x, a) = E[r | x, a]` — модель ожидаемой награды, |
| 28 | +- `mu(x,a) = E[r|x,a]` — модель ожидаемой награды, |
36 | 29 | - `p_A(a|x) = pi_A(a|x)` — propensity логирующей политики, |
37 | 30 | - `w_i = pi_B(a_i|x_i) / p_A(a_i|x_i)` — importance weight. |
38 | 31 |
|
39 | 32 | --- |
40 | 33 |
|
41 | | -## 2) On-policy baseline (`value_on_policy`) |
| 34 | +## 2) Point-estimators (что оценивает `V_hat`) |
42 | 35 |
|
43 | | -Средняя награда на логах A: |
| 36 | +### 2.1 On-policy baseline (`value_on_policy`) |
44 | 37 |
|
45 | 38 | ```text |
46 | 39 | V_A_hat = (1/n) * sum_i r_i |
47 | 40 | ``` |
48 | 41 |
|
49 | | -Это baseline для сравнения с `V_B`. |
50 | | - |
51 | | ---- |
52 | | - |
53 | | -## 3) Replay (`replay_value`) |
| 42 | +Это baseline текущей политики A. |
54 | 43 |
|
55 | | -Берём только строки, где действия A и B совпали: |
| 44 | +### 2.2 Replay (`replay_value`) |
56 | 45 |
|
57 | 46 | ```text |
58 | 47 | I = { i : a_i == a_i^B } |
59 | | -V_replay_hat = (1 / |I|) * sum_{i in I} r_i |
| 48 | +V_replay_hat = (1/|I|) * sum_{i in I} r_i |
60 | 49 | ``` |
61 | 50 |
|
62 | | -Интуиция: |
63 | | -- максимально «честно» (без моделирования контрфактов), |
64 | | -- но может иметь высокую дисперсию при малом числе совпадений. |
| 51 | +- Плюс: «честная» фильтрация без моделирования контрфактов. |
| 52 | +- Минус: может иметь большую дисперсию, если совпадений мало. |
65 | 53 |
|
66 | | -Литература: |
67 | | -- Li et al. (unbiased offline evaluation / replay): https://arxiv.org/abs/1003.5956 |
| 54 | +Источник: Li et al. (unbiased offline evaluation) — https://arxiv.org/abs/1003.5956 |
68 | 55 |
|
69 | | ---- |
70 | | - |
71 | | -## 4) IPS (`ips_value`) |
| 56 | +### 2.3 IPS (`ips_value`) |
72 | 57 |
|
73 | 58 | ```text |
74 | | -V_IPS_hat = (1/n) * sum_i (w_i * r_i) |
| 59 | +V_IPS_hat = (1/n) * sum_i [w_i * r_i] |
75 | 60 | where w_i = pi_B(a_i|x_i) / p_A(a_i|x_i) |
76 | 61 | ``` |
77 | 62 |
|
78 | | -Интуиция: |
79 | | -- корректно перевзвешивает логи A «под» политику B, |
80 | | -- несмещён при корректных propensity и overlap, |
81 | | -- чувствителен к большим весам. |
82 | | - |
83 | | -Литература: |
84 | | -- Dudík, Langford, Li: https://arxiv.org/abs/1103.4601 |
85 | | -- Практический контекст bandits: https://arxiv.org/abs/1003.5956 |
| 63 | +- Несмещён при корректных propensity и overlap. |
| 64 | +- Нестабилен при тяжёлом хвосте весов. |
86 | 65 |
|
87 | | ---- |
| 66 | +Источник: Dudík, Langford, Li — https://arxiv.org/abs/1103.4601 |
88 | 67 |
|
89 | | -## 5) SNIPS (`snips_value`) |
| 68 | +### 2.4 SNIPS (`snips_value`) |
90 | 69 |
|
91 | 70 | ```text |
92 | 71 | V_SNIPS_hat = sum_i (w_i * r_i) / sum_i w_i |
93 | 72 | ``` |
94 | 73 |
|
95 | | -Интуиция: |
96 | | -- нормировка стабилизирует оценки, |
97 | | -- обычно снижает дисперсию, |
98 | | -- может добавлять смещение. |
99 | | - |
100 | | -Литература: |
101 | | -- Swaminathan & Joachims: https://arxiv.org/abs/1502.02362 |
102 | | -- JMLR version: https://jmlr.org/papers/v16/swaminathan15a.html |
| 74 | +- Обычно более стабилен, чем IPS. |
| 75 | +- Может вносить смещение. |
103 | 76 |
|
104 | | ---- |
| 77 | +Источник: Swaminathan & Joachims — https://arxiv.org/abs/1502.02362 |
105 | 78 |
|
106 | | -## 6) DM / Direct Method (`dm_value`) |
107 | | - |
108 | | -Сначала строится модель `mu_hat(x,a)`, затем: |
| 79 | +### 2.5 DM (`dm_value`) |
109 | 80 |
|
110 | 81 | ```text |
111 | | -V_DM_hat = (1/n) * sum_i sum_a [ pi_B(a|x_i) * mu_hat(x_i, a) ] |
| 82 | +V_DM_hat = (1/n) * sum_i sum_a [ pi_B(a|x_i) * mu_hat(x_i,a) ] |
112 | 83 | ``` |
113 | 84 |
|
114 | | -Интуиция: |
115 | | -- низкая дисперсия, |
116 | | -- зависит от качества модели награды. |
117 | | - |
118 | | -Литература: |
119 | | -- Dudík et al. (DM/IPS/DR): https://arxiv.org/abs/1103.4601 |
| 85 | +- Низкая дисперсия. |
| 86 | +- Чувствителен к ошибкам модели `mu_hat`. |
120 | 87 |
|
121 | | ---- |
| 88 | +Источник: https://arxiv.org/abs/1103.4601 |
122 | 89 |
|
123 | | -## 7) DR / Doubly Robust (`dr_value`) |
| 90 | +### 2.6 DR (`dr_value`) |
124 | 91 |
|
125 | 92 | ```text |
126 | 93 | V_DR_hat = (1/n) * sum_i [ |
127 | | - sum_a pi_B(a|x_i) * mu_hat(x_i, a) |
128 | | - + (pi_B(a_i|x_i)/p_A(a_i|x_i)) * (r_i - mu_hat(x_i, a_i)) |
| 94 | + sum_a pi_B(a|x_i) * mu_hat(x_i,a) |
| 95 | + + (pi_B(a_i|x_i)/p_A(a_i|x_i)) * (r_i - mu_hat(x_i,a_i)) |
129 | 96 | ] |
130 | 97 | ``` |
131 | 98 |
|
132 | | -Интуиция: |
133 | | -- сочетает DM + IPS-коррекцию, |
134 | | -- консистентен, если корректна хотя бы одна часть: propensity или `mu_hat`. |
135 | | - |
136 | | -Литература: |
137 | | -- Классика DR: https://arxiv.org/abs/1103.4601 |
138 | | -- Доп. анализ DR: https://arxiv.org/abs/1503.02834 |
139 | | - |
140 | | ---- |
| 99 | +- Doubly robust: консистентность при корректности хотя бы одной части (`p_A` или `mu_hat`). |
141 | 100 |
|
142 | | -## 8) SNDR / Self-Normalized DR (`sndr_value`) |
| 101 | +Источники: |
| 102 | +- https://arxiv.org/abs/1103.4601 |
| 103 | +- https://arxiv.org/abs/1503.02834 |
143 | 104 |
|
144 | | -В реализации `Policyscope` нормируется коррекционный член DR: |
| 105 | +### 2.7 SNDR (`sndr_value`) |
145 | 106 |
|
146 | 107 | ```text |
147 | 108 | w_bar = (1/n) * sum_i w_i |
148 | 109 | V_SNDR_hat = (1/n) * sum_i [ |
149 | | - sum_a pi_B(a|x_i) * mu_hat(x_i, a) |
150 | | - + (w_i / w_bar) * (r_i - mu_hat(x_i, a_i)) |
| 110 | + sum_a pi_B(a|x_i) * mu_hat(x_i,a) |
| 111 | + + (w_i/w_bar) * (r_i - mu_hat(x_i,a_i)) |
151 | 112 | ] |
152 | 113 | ``` |
153 | 114 |
|
154 | | -Интуиция: |
155 | | -- меньше вариативность при «тяжёлых» весах, |
156 | | -- ценой некоторого смещения. |
| 115 | +- Стабилизирует DR при тяжёлых весах. |
| 116 | +- Может увеличить смещение. |
157 | 117 |
|
158 | | -Литература: |
159 | | -- Self-normalization: https://arxiv.org/abs/1502.02362 |
160 | | -- DR фундамент: https://arxiv.org/abs/1103.4601 |
| 118 | +Основано на идеях self-normalization + DR: |
| 119 | +- https://arxiv.org/abs/1502.02362 |
| 120 | +- https://arxiv.org/abs/1103.4601 |
161 | 121 |
|
162 | | ---- |
163 | | - |
164 | | -## 9) Switch-DR (`switch_dr_value`) |
165 | | - |
166 | | -Для весов выше порога `tau` IPS-поправка выключается: |
| 122 | +### 2.8 Switch-DR (`switch_dr_value`) |
167 | 123 |
|
168 | 124 | ```text |
169 | 125 | V_SwitchDR_hat = (1/n) * sum_i [ |
170 | | - sum_a pi_B(a|x_i) * mu_hat(x_i, a) |
171 | | - + 1[w_i <= tau] * w_i * (r_i - mu_hat(x_i, a_i)) |
| 126 | + sum_a pi_B(a|x_i) * mu_hat(x_i,a) |
| 127 | + + 1[w_i <= tau] * w_i * (r_i - mu_hat(x_i,a_i)) |
172 | 128 | ] |
173 | 129 | ``` |
174 | 130 |
|
175 | | -Интуиция: |
176 | | -- снижает дисперсию за счёт контролируемого bias-variance trade-off. |
| 131 | +- Контролирует variance через отключение опасно больших весов. |
177 | 132 |
|
178 | | -Литература: |
179 | | -- SWITCH estimator: https://proceedings.mlr.press/v70/wang17a.html |
180 | | -- arXiv: https://arxiv.org/abs/1612.01205 |
| 133 | +Источник: https://arxiv.org/abs/1612.01205 |
181 | 134 |
|
182 | 135 | --- |
183 | 136 |
|
184 | | -## 10) Bootstrap CI для DR (`dr_with_bootstrap_ci`) |
| 137 | +## 3) Почему `Bootstrap CI` — не отдельный OPE-оценщик |
185 | 138 |
|
186 | | -Интервалы строятся бутстрэпом (по строкам или по кластерам `user_id`). |
| 139 | +`Bootstrap CI` не задаёт новую формулу `V_hat`. |
| 140 | +Он берёт **любой выбранный `V_hat`** (например DR/IPS/SNIPS) и оценивает его неопределённость: |
187 | 141 |
|
188 | | -Интуиция: |
189 | | -- эмпирически оцениваем распределение оценки, |
190 | | -- учитываем зависимость внутри кластера при cluster bootstrap. |
| 142 | +```text |
| 143 | +Результат inference: [L, U] для неизвестного V(pi_B) |
| 144 | +``` |
191 | 145 |
|
192 | | -Литература: |
193 | | -- Efron & Tibshirani: https://www.routledge.com/An-Introductionto-the-Bootstrap/Efron-Tibshirani/p/book/9780412042317 |
194 | | -- Cluster bootstrap: https://direct.mit.edu/rest/article/90/3/414/57731/Bootstrap-Based-Improvements-for-Inference-with |
| 146 | +Поэтому корректно мыслить так: |
| 147 | +- «Estimator» отвечает на вопрос: *какая точечная оценка?* |
| 148 | +- «CI method» отвечает на вопрос: *насколько эта оценка статистически неопределённа?* |
195 | 149 |
|
196 | 150 | --- |
197 | 151 |
|
198 | | -## 11) Практический чек-лист |
| 152 | +## 4) Как считать CI для остальных OPE-оценщиков |
199 | 153 |
|
200 | | -1. Проверяйте overlap: нет ли зон, где `p_A(a|x)` очень мал, а `pi_B(a|x)` велик. |
201 | | -2. Контролируйте ESS: низкий ESS = мало эффективных наблюдений. |
202 | | -3. Сравнивайте IPS/SNIPS/DR/Switch-DR, а не одну точечную оценку. |
203 | | -4. Всегда смотрите доверительные интервалы. |
204 | | -5. Решение о выкладке делайте по `V_B` и `Delta = V_B - V_A`. |
| 154 | +Ниже — основные подходы, которые используются в литературе. |
205 | 155 |
|
206 | | ---- |
| 156 | +### 4.1 Nonparametric bootstrap (универсальный практический baseline) |
| 157 | + |
| 158 | +Подходит почти для любого point-estimator (Replay/IPS/SNIPS/DM/DR/SNDR/Switch-DR): |
| 159 | + |
| 160 | +1. `b=1..B`: ресемплируем строки (или кластеры `user_id`) с возвращением. |
| 161 | +2. Считаем `V_hat^(b)` тем же оценщиком. |
| 162 | +3. CI берём по квантилям `alpha/2` и `1-alpha/2`. |
| 163 | + |
| 164 | +Плюсы: |
| 165 | +- просто, |
| 166 | +- единая процедура для разных оценщиков. |
| 167 | + |
| 168 | +Минусы: |
| 169 | +- чувствителен к тяжёлым хвостам, |
| 170 | +- в адаптивных данных (bandit logs) может давать некорректное покрытие без доп. поправок. |
| 171 | + |
| 172 | +Классика bootstrap: Efron & Tibshirani (книга). |
| 173 | + |
| 174 | +### 4.2 Асимптотические Wald/IF-интервалы (для IPS/DR и их вариантов) |
| 175 | + |
| 176 | +Идея: представить оценщик как среднее influence-like термов `psi_i`, затем: |
| 177 | + |
| 178 | +```text |
| 179 | +SE_hat = sqrt( Var_hat(psi_i) / n ) |
| 180 | +CI = V_hat +/- z_(1-alpha/2) * SE_hat |
| 181 | +``` |
| 182 | + |
| 183 | +Плюсы: |
| 184 | +- дешево по вычислениям, |
| 185 | +- удобно для онлайн-отчётности. |
207 | 186 |
|
208 | | -## 12) Важные допущения |
| 187 | +Минусы: |
| 188 | +- требуют условий асимптотики, |
| 189 | +- плохи при малом `n` и тяжелых весах. |
209 | 190 |
|
210 | | -- Positivity (overlap): действия B должны иметь поддержку в логах A. |
211 | | -- Корректное логирование действий и propensity. |
212 | | -- Стабильность определения награды. |
| 191 | +Связанные источники: |
| 192 | +- DR/OPE базис: https://arxiv.org/abs/1103.4601 |
| 193 | +- Пост-bandit inference и корректность интервалов в адаптивных дизайнах: |
| 194 | + https://proceedings.neurips.cc/paper/2021/file/eff3058117fd4cf4d4c3af12e273a40f-Paper.pdf |
213 | 195 |
|
214 | | -Нарушение допущений обычно критичнее, чем выбор конкретного OPE-оценщика. |
| 196 | +### 4.3 High-confidence bounds (концентрационные, «гарантийные») |
| 197 | + |
| 198 | +Вместо симметричного CI строят нижнюю/верхнюю границу с гарантиями вероятности. |
| 199 | +Часто используют эмпирические Bernstein/концентрационные подходы и клиппинг. |
| 200 | + |
| 201 | +Подходит для risk-averse запуска, когда важнее «не переоценить» качество. |
| 202 | + |
| 203 | +Источник: High Confidence OPE (Thomas et al., AAAI 2015): |
| 204 | +- PDF: https://people.cs.umass.edu/~pthomas/papers/Thomas2015.pdf |
| 205 | + |
| 206 | +### 4.4 Cluster bootstrap (когда есть зависимость внутри пользователя) |
| 207 | + |
| 208 | +Если на одного `user_id` приходится много наблюдений, стандартный row-bootstrap занижает неопределённость. |
| 209 | +Нужно ресемплировать кластеры целиком. |
| 210 | + |
| 211 | +Источник: Cameron, Gelbach, Miller (cluster bootstrap): |
| 212 | +- https://direct.mit.edu/rest/article/90/3/414/57731/Bootstrap-Based-Improvements-for-Inference-with |
215 | 213 |
|
216 | 214 | --- |
217 | 215 |
|
218 | | -## 13) Что использовать первым |
| 216 | +## 5) Практическая рекомендация для `Policyscope` |
| 217 | + |
| 218 | +1. Для всех OPE-оценщиков начните с **cluster bootstrap CI** (если есть повторные наблюдения на пользователя). |
| 219 | +2. Для отчёта держите и point-estimate, и CI. |
| 220 | +3. Если веса тяжёлые (низкий ESS), добавляйте диагностику стабильности: |
| 221 | + - IPS vs SNIPS, |
| 222 | + - DR vs Switch-DR, |
| 223 | + - sensitivity по `weight_clip` / `tau`. |
| 224 | +4. Для критичных решений используйте high-confidence lower bound как дополнительный guardrail. |
| 225 | + |
| 226 | +--- |
| 227 | + |
| 228 | +## 6) Мини-ответ на ваш ключевой вопрос |
| 229 | + |
| 230 | +**Нет, `Bootstrap CI для DR` не является отдельным OPE-эстиматором наравне с IPS/DR.** |
| 231 | +Это слой статистического вывода поверх выбранного point-estimator. |
219 | 232 |
|
220 | | -- Нужен прозрачный baseline: **IPS**. |
221 | | -- Нужна устойчивая практика: **DR**. |
222 | | -- Тяжёлые веса/нестабильность: **SNDR** или **Switch-DR**. |
223 | | -- Обязательный слой для принятия решения: **bootstrap CI**. |
| 233 | +То, что в коде есть отдельная функция `dr_with_bootstrap_ci`, действительно может выглядеть как «ещё один метод», но математически это скорее «pipeline для инференса», а не новый `V_hat`. |
0 commit comments