Closing the loop after PolicyLearner: batched Thompson sampling on the treatment-effect posterior (scoping, following #833)
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 20/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- numpy, python
- Ambito
- data, machine-learning
Direzione di ricerca
This is a design proposal that asks maintainers to decide whether a batched Thompson sampler belongs in causalml/optimize/bandit.py before any code is written. Read the PolicyLearner code in causalml/optimize and the "Choosing an Estimator" docs page to see how randomized, known-propensity data is handled. Done means a maintainer agrees on placement and scope, then a sampler and tests that use only numpy and scipy.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
When #833 was closed, you suggested agreeing first on where multi-armed bandits fit relative to causalml.optimize. Here is a narrow proposal, and the question of whether it fits.
Where it would sit. CausalML today takes one dataset, estimates the effect, validates it, and decides who to treat (PolicyLearner, value optimization). The proposal adds the step after that decision: run it as the next randomized batch, update the effect estimate, and decide again. It is one method, not a general bandit collection, and the loop is built around a treatment-effect estimate.
The core: an effect posterior carried from batch to batch.
- Each batch is a randomized experiment with known, fixed assignment shares.
- Within a batch, the method fits a logistic regression with the batch's own intercept and each arm's log odds ratio against a control arm. Only the effects are carried forward: their posterior becomes the prior for the next batch, and the intercept is refit every batch. Anything that moves all arms together within a batch, such as a promotion or a weekday, goes into the intercept instead of the effects.
- The next batch's shares come from Thompson sampling on the effect posterior.
- Because the shares depend only on the batch, the batch intercept stratifies on exactly what the assignment depended on. It is the comparison a propensity-stratified estimate makes, done through the design.
The logs are ordinary causalml input. Every unit was randomized with a known probability, its batch's share for the arm it received (p = shares[treatment]). The accumulated log (X, treatment, y, p, batch) can therefore be analysed afterwards by the existing learners with p passed in, as the "Choosing an Estimator" page describes for randomized data with a known assignment probability. The bandit handles allocation online; CATE estimation, validation and policy_risk stay with the existing tools.
Scale. Uplift in causalml is mostly a risk difference, while this method works on log odds. Within a segment both rank the arms the same way, so allocation is unaffected; reporting a risk difference needs the segment's base rate.
Suggested first PR, following your note on #833: causalml/optimize/bandit.py with
- the batched effect-posterior sampler for a binary outcome and discrete arms, without covariates;
- a Beta-Bernoulli Thompson sampler as the baseline;
- tests, formatted with
black, using only numpy and scipy.
I'd suggest marking it experimental so that it stays outside the v1.0 API freeze. Segments (each segment's effect shrunk toward the common effect by an amount estimated from the data), simulation utilities and a notebook would follow as separate PRs, and only if the first one fits.
A rough shape, with names open to change:
sampler = BatchedEffectThompsonSampler(n_arms=3, control_name=0, random_state=0)
shares = sampler.allocate() # assignment shares for the next batch
sampler.update(treatment=t, y=y) # outcomes observed in that batch
Background: the method is described in arXiv:2609.19709, and I maintain an MIT implementation (orts on PyPI). I would write the causalml version to the library's conventions rather than add a dependency. If this doesn't fit, or belongs somewhere other than optimize, I'd rather know before writing code.
- Lingua principale
- Python
- Stelle
- 6k
- Fork
- 892
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di uber/causalml
-
Add a pickle-size regression test for fitted learners (v1.0 M1)Forse già presa @techi101 l’ha presa 7 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 67/100
-
BaseRClassifier ignores cv_n_jobs during outcome cross-validationForse già presa @ayuxy027 l’ha presa 17 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 25/100
-
cate_scoring default learner is oversized for its own per-fold, per-arm call patternForse già presa @su-jin1425 l’ha presa 78 giorni fa. Apertaenhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
S-, T- and X-learner bootstrap confidence intervals are not reproducibleForse già presa @su-jin1425 l’ha presa 78 giorni fa. Apertabug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
-
sklearn metadata routing: let `treatment` reach a learner inside a PipelineForse di nuovo libera @su-jin1425 l’ha presa 90 giorni fa e non c’è nessuna pull request aperta. Apertaenhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
Tutte le issue di uber/causalml
Issue simili
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
splunk/security_content#4418 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug / Enhancement]: Improve teleop_robot CLI with configurable timeout, robust input validation, and clean ROS shutdownForse già presa @muskan-creates352 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 3 giorni
-
bug(pipelines): shortcode stripping deletes text between a {{< >}} shortcode and the next {{% %}}Forse già presa @Ashborne-lab l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
kubeflow/docs-agent#293 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
Imbad0202/academic-research-skills#1093 ·
I maintainer di solito rispondono entro 1 giorno
-
Input: placeholder drawn in the text colour when the empty Input is focused but not yet editedAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pierreaubert/gpui-toolkit#114 ·
I maintainer di solito rispondono entro 1 giorno