Sampling oracles
banditry.sampling_oracles.sampler.Sampler
Bases: ABC
Posterior-sampling contract used by TSAgent for Thompson sampling.
A Sampler takes a template ValueFunction together with the data observed so far
and returns a copy of the model whose weights are a single draw from the (approximate)
posterior over weights; TSAgent then optimises the sampled model's predictions to
pick the next action. Instances are constructed from TSConfig.sampler_config keyword
arguments (see :class:~banditry.sampling_oracles.langevin_sampler.LangevinSampler and
:class:~banditry.sampling_oracles.nuts_sampler.NUTSSampler for the accepted keys).
Attributes:
| Name | Type | Description |
|---|---|---|
generator |
Generator | None
|
Optional |
sample(model, Xc, Xe, y, nll=None)
abstractmethod
Draw one posterior sample of the model weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
ValueFunction
|
Template |
required |
Xc
|
FloatTensor | None
|
Continuous features of shape |
required |
Xe
|
LongTensor | None
|
Categorical (enum) features of shape |
required |
y
|
FloatTensor
|
Observed targets of shape |
required |
nll
|
Callable[..., FloatTensor] | None
|
Optional negative-log-likelihood callable
|
None
|
Returns:
| Type | Description |
|---|---|
ValueFunction
|
A new |
ValueFunction
|
mode and with its y-scaler fitted to |
Source code in src/banditry/sampling_oracles/sampler.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | |
__call__(model, Xc, Xe, y, nll=None)
Alias for :meth:sample.
Source code in src/banditry/sampling_oracles/sampler.py
221 222 223 224 225 226 227 228 229 230 | |
total_variation(**kwargs)
Diagnostic hook for sampler-quality metrics; the base implementation returns 0.
Source code in src/banditry/sampling_oracles/sampler.py
307 308 309 | |
banditry.sampling_oracles.langevin_sampler
LangevinSampler(step_size=welling_teh_schedule(a=0.001), prior_precision=0.0001, temperature=1.0, precondition=False, precond_alpha=0.99, precond_eps=1e-05, batch_size=64, min_batches=10, num_epochs=10, burn_in=10, init_obs_noise=1.0, min_obs_noise=1e-06, max_obs_noise=1.0, generator=None)
Bases: Sampler
Sample TS model weights from an approximate posterior using SGLD.
Runs stochastic gradient Langevin dynamics (Welling & Teh, 2011) on a deep copy of the
model: minibatch gradient steps on the negative log posterior with Gaussian noise
injected by the :class:~banditry.optimisation_oracles.sgld.SGLD optimizer. The
observation-noise standard deviation is learned jointly as a per-output parameter
(excluded from the weight prior). The total number of updates is the maximum of
num_epochs epochs, min_batches updates, and burn_in + 1 epochs, so at least
one post-burn-in epoch always runs; one post-burn-in state is kept via streaming
uniform (reservoir) selection and returned as the posterior draw.
The constructor keyword arguments below are exactly the valid keys of
TSConfig.sampler_config when sampler="langevin".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step_size
|
float | Callable[[int], float]
|
Learning-rate schedule: either a constant |
welling_teh_schedule(a=0.001)
|
prior_precision
|
float
|
Precision of the isotropic zero-mean Gaussian prior over model weights, applied as weight decay on the gradients. |
0.0001
|
temperature
|
float
|
Scales the variance of the injected Langevin noise; |
1.0
|
precondition
|
bool
|
If |
False
|
precond_alpha
|
float
|
EMA decay rate of the squared-gradient accumulator used by the preconditioner. |
0.99
|
precond_eps
|
float
|
Numerical-stability constant added to the preconditioner denominator. |
1e-05
|
batch_size
|
int
|
Minibatch size (capped at the dataset size). |
64
|
min_batches
|
int
|
Minimum total number of gradient updates to perform. |
10
|
num_epochs
|
int
|
Target number of passes over the data. |
10
|
burn_in
|
int
|
Number of initial epochs discarded before model states become eligible for selection as the returned sample. |
10
|
init_obs_noise
|
float
|
Initial observation-noise standard deviation (in standardised-y units). |
1.0
|
min_obs_noise
|
float
|
Lower clamp for the learned observation noise. |
1e-06
|
max_obs_noise
|
float
|
Upper clamp for the learned observation noise. |
1.0
|
generator
|
Generator | None
|
Optional |
None
|
Source code in src/banditry/sampling_oracles/langevin_sampler.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |
sample(model, Xc, Xe, y, nll=None)
Draw one posterior weight sample via SGLD.
Standardises y (and fits the model's x-scaler), then runs SGLD on a deep copy
of model for the configured number of updates, keeping one post-burn-in state
chosen uniformly at random as the posterior draw.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
ValueFunction
|
Template |
required |
Xc
|
FloatTensor | None
|
Continuous features of shape |
required |
Xe
|
LongTensor | None
|
Categorical features of shape |
required |
y
|
FloatTensor
|
Observed targets of shape |
required |
nll
|
Callable[..., FloatTensor] | None
|
Optional NLL callable |
None
|
Returns:
| Type | Description |
|---|---|
ValueFunction
|
A new |
ValueFunction
|
fitted y-scaler. |
Source code in src/banditry/sampling_oracles/langevin_sampler.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | |
welling_teh_schedule(a, b=1.0, gamma=0.55, lr_floor=1e-05)
Build the polynomial step-size schedule of Welling & Teh (2011).
Implements the decaying schedule from Welling & Teh (2011), "Bayesian Learning via
Stochastic Gradient Langevin Dynamics": eps_t = a * (b + t) ** (-gamma) during
burn-in. After burn-in the rate is frozen at its final burn-in value and clamped from
below by lr_floor, i.e. max(a * (b + n_burn_in) ** (-gamma), lr_floor).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
float
|
Initial scale of the schedule; must be positive. |
required |
b
|
float
|
Offset delaying the start of the decay; must be non-negative. |
1.0
|
gamma
|
float
|
Decay exponent; must lie in |
0.55
|
lr_floor
|
float
|
Lower bound applied to the post-burn-in learning rate. |
1e-05
|
Returns:
| Type | Description |
|---|---|
Callable[[int], float]
|
A callable |
Callable[[int], float]
|
number of burn-in updates |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/banditry/sampling_oracles/langevin_sampler.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
banditry.sampling_oracles.nuts_sampler.NUTSSampler(num_samples=64, warmup_steps=256, target_accept_prob=0.8, max_tree_depth=10, adapt_step_size=True, adapt_mass_matrix=True, use_multinomial_sampling=True, prior_std=1.0, obs_noise_prior_loc=0.0, obs_noise_prior_scale=1.0, init_obs_noise=1.0, min_obs_noise=1e-06, max_obs_noise=1000.0, jit_compile=False, ignore_jit_warnings=True, disable_progbar=True, generator=None)
Bases: Sampler
Sample TS model weights from a posterior using Pyro NUTS.
Runs the No-U-Turn Sampler (Hoffman & Gelman, 2014) via Pyro's MCMC over all
trainable model parameters plus a per-output observation-noise parameter, then returns
the model with one randomly chosen posterior draw loaded. Weights receive an isotropic
zero-mean Gaussian prior with standard deviation prior_std; the observation noise
is parameterised through a sigmoid squashed into (min_obs_noise, max_obs_noise)
with a Gaussian prior on the unconstrained value.
Requires the banditry[nuts] extra (installs pyro-ppl).
The constructor keyword arguments below are exactly the valid keys of
TSConfig.sampler_config when sampler="nuts".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_samples
|
int
|
Number of posterior draws collected after warmup; one is picked uniformly at random as the returned sample. |
64
|
warmup_steps
|
int
|
Number of warmup (adaptation) iterations discarded before sampling. |
256
|
target_accept_prob
|
float
|
Target acceptance probability for step-size adaptation. |
0.8
|
max_tree_depth
|
int
|
Maximum doubling depth of the NUTS trajectory tree. |
10
|
adapt_step_size
|
bool
|
Whether to adapt the leapfrog step size during warmup. |
True
|
adapt_mass_matrix
|
bool
|
Whether to adapt the mass matrix during warmup. |
True
|
use_multinomial_sampling
|
bool
|
Whether to draw states multinomially from the trajectory instead of using slice sampling. |
True
|
prior_std
|
float
|
Standard deviation of the zero-mean Gaussian prior over model weights. |
1.0
|
obs_noise_prior_loc
|
float
|
Prior mean of the log observation noise; clamped into
|
0.0
|
obs_noise_prior_scale
|
float
|
Prior standard deviation of the unconstrained observation-noise parameter. |
1.0
|
init_obs_noise
|
float
|
Initial observation-noise standard deviation (in standardised-y units), clamped into the allowed range. |
1.0
|
min_obs_noise
|
float
|
Lower bound of the observation-noise range. |
1e-06
|
max_obs_noise
|
float
|
Upper bound of the observation-noise range. |
1000.0
|
jit_compile
|
bool
|
Whether Pyro should JIT-compile the potential function. |
False
|
ignore_jit_warnings
|
bool
|
Whether to silence JIT tracer warnings. |
True
|
disable_progbar
|
bool
|
Whether to hide the MCMC progress bar. |
True
|
generator
|
Generator | None
|
Optional |
None
|
Source code in src/banditry/sampling_oracles/nuts_sampler.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | |
sample(model, Xc, Xe, y, nll=None)
Draw one posterior weight sample via NUTS MCMC.
Standardises y (and fits the model's x-scaler), builds a Pyro model whose
log-density combines the weight and noise priors with -nll as the likelihood
factor, runs NUTS for warmup_steps plus num_samples iterations, and loads
one uniformly chosen posterior draw into a deep copy of model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
ValueFunction
|
Template |
required |
Xc
|
FloatTensor | None
|
Continuous features of shape |
required |
Xe
|
LongTensor | None
|
Categorical features of shape |
required |
y
|
FloatTensor
|
Observed targets of shape |
required |
nll
|
Callable[..., FloatTensor] | None
|
Optional NLL callable |
None
|
Returns:
| Type | Description |
|---|---|
ValueFunction
|
A new |
ValueFunction
|
fitted y-scaler. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the model has no trainable parameters. |
RuntimeError
|
If MCMC returns no posterior draws. |
Source code in src/banditry/sampling_oracles/nuts_sampler.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
banditry.sampling_oracles.sampler.FeelGoodNLL(fg_lambda=1.0, fg_bound=10.0)
Bases: NLL
Feel-Good Thompson sampling loss factory (Zhang, 2021).
Implements the exploration reweighting of Zhang (2021), "Feel-Good Thompson Sampling
for Contextual Bandits and Reinforcement Learning". The returned loss augments the
Gaussian NLL with an optimism ("feel-good") bonus: for every distinct context observed
so far, a short evolutionary search over the free (non-context) variables finds the
current weight sample's maximum predicted value; that value is capped at fg_bound,
weighted by the number of observations sharing the context, and fg_lambda times the
total is subtracted from the NLL. Posterior draws are thereby tilted towards weights
that believe a high value is attainable, adding optimism to Thompson sampling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fg_lambda
|
float
|
Weight of the feel-good term. |
1.0
|
fg_bound
|
float
|
Upper cap applied to each context's best predicted value before weighting, preventing the bonus from dominating the likelihood. Must be non-negative. |
10.0
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/banditry/sampling_oracles/sampler.py
100 101 102 103 104 | |
__call__(fix_input, space, X)
Bind the observed contexts and return the feel-good loss callable.
Groups X by the context columns named in fix_input to enumerate the distinct
contexts and their observation counts. The returned callable computes a scalar total
loss: the Gaussian NLL summed over the dataset (rescaled to num_data) minus the
feel-good bonus. It expects the sampler to pass model (and, for functional
evaluation, model_params) as keyword arguments; without a model, or when
fg_lambda == 0, it falls back to the per-element Gaussian NLL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fix_input
|
dict
|
Context-variable mapping; only its keys are used, to group |
required |
space
|
|
required | |
X
|
DataFrame
|
Raw observations collected so far; grouped by the context columns. |
required |
Returns:
| Type | Description |
|---|---|
Callable[..., FloatTensor]
|
A callable |
Callable[..., FloatTensor]
|
the feel-good-adjusted negative log-likelihood. |
Source code in src/banditry/sampling_oracles/sampler.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |