0
# Bayesian Sampling
1
2
MCMC sampling methods for drawing from posterior distributions. PyStan provides multiple sampling algorithms including HMC-NUTS (Hamiltonian Monte Carlo with No-U-Turn Sampler) and fixed parameter sampling for models without parameters to estimate.
3
4
## Capabilities
5
6
### Default Sampling
7
8
The primary sampling method using HMC-NUTS with diagonal euclidean adaptation.
9
10
```python { .api }
11
def sample(self, *, num_chains: int = 4, **kwargs) -> Fit:
12
"""
13
Draw samples from the model.
14
15
Parameters in kwargs will be passed to the default sample function.
16
The default sample function is currently stan::services::sample::hmc_nuts_diag_e_adapt.
17
Parameter names are identical to those used in CmdStan.
18
19
Args:
20
num_chains: PyStan-specific keyword argument. Number of independent processes
21
to use when drawing samples. Default: 4
22
**kwargs: Additional parameters passed to Stan sampling function:
23
- num_samples (int): Number of post-warmup samples per chain. Default: 1000
24
- num_warmup (int): Number of warmup samples per chain. Default: 1000
25
- init (list): Initial parameter values for each chain
26
- adapt_delta (float): Target acceptance rate. Default: 0.8
27
- max_treedepth (int): Maximum tree depth. Default: 10
28
- stepsize (float): Initial step size. Default: 1.0
29
30
Returns:
31
Fit: Instance of Fit allowing access to draws
32
33
Examples:
34
User-defined initial values for parameters must be provided for each chain.
35
Typically they will be the same for each chain:
36
37
>>> program_code = "parameters {real y;} model {y ~ normal(0,1);}"
38
>>> posterior = stan.build(program_code)
39
>>> fit = posterior.sample(num_chains=2, init=[{"y": 3}, {"y": 3}])
40
"""
41
```
42
43
### HMC-NUTS Sampling
44
45
Explicit HMC-NUTS sampling with diagonal euclidean adaptation.
46
47
```python { .api }
48
def hmc_nuts_diag_e_adapt(self, *, num_chains: int = 4, **kwargs) -> Fit:
49
"""
50
Draw samples from the model using stan::services::sample::hmc_nuts_diag_e_adapt.
51
52
Parameters in kwargs will be passed to the (Python wrapper of)
53
stan::services::sample::hmc_nuts_diag_e_adapt. Parameter names are
54
identical to those used in CmdStan.
55
56
Args:
57
num_chains: PyStan-specific keyword argument. Number of independent processes
58
to use when drawing samples. Default: 4
59
**kwargs: Additional parameters passed to Stan sampling function
60
61
Returns:
62
Fit: Instance of Fit allowing access to draws
63
"""
64
```
65
66
### Fixed Parameter Sampling
67
68
Sampling for models with no parameters to estimate (e.g., for generated quantities only).
69
70
```python { .api }
71
def fixed_param(self, *, num_chains: int = 4, **kwargs) -> Fit:
72
"""
73
Draw samples from the model using stan::services::sample::fixed_param.
74
75
Used for models with no parameters, typically when only generated quantities
76
are needed or for forward simulation.
77
78
Parameters in kwargs will be passed to the (Python wrapper of)
79
stan::services::sample::fixed_param. Parameter names are
80
identical to those used in CmdStan.
81
82
Args:
83
num_chains: PyStan-specific keyword argument. Number of independent processes
84
to use when drawing samples. Default: 4
85
**kwargs: Additional parameters passed to Stan sampling function
86
87
Returns:
88
Fit: Instance of Fit allowing access to draws
89
"""
90
```
91
92
## Usage Examples
93
94
### Basic Sampling
95
96
```python
97
import stan
98
99
program_code = """
100
parameters {
101
real mu;
102
real<lower=0> sigma;
103
}
104
model {
105
mu ~ normal(0, 1);
106
sigma ~ exponential(1);
107
}
108
"""
109
110
model = stan.build(program_code)
111
112
# Sample with default settings
113
fit = model.sample()
114
115
# Sample with custom settings
116
fit = model.sample(
117
num_chains=4,
118
num_samples=2000,
119
num_warmup=1000,
120
adapt_delta=0.95,
121
max_treedepth=12
122
)
123
```
124
125
### Custom Initialization
126
127
```python
128
import stan
129
130
program_code = """
131
parameters {
132
real alpha;
133
real beta;
134
}
135
model {
136
alpha ~ normal(0, 10);
137
beta ~ normal(0, 10);
138
}
139
"""
140
141
model = stan.build(program_code)
142
143
# Provide initial values for each chain
144
init_values = [
145
{"alpha": 1.0, "beta": 0.5},
146
{"alpha": -1.0, "beta": 1.5},
147
{"alpha": 0.0, "beta": -0.5},
148
{"alpha": 2.0, "beta": 2.0}
149
]
150
151
fit = model.sample(num_chains=4, init=init_values)
152
```
153
154
### Fixed Parameter Model
155
156
```python
157
import stan
158
159
# Model with only generated quantities
160
program_code = """
161
generated quantities {
162
real y_pred = normal_rng(0, 1);
163
real z_pred = exponential_rng(1);
164
}
165
"""
166
167
model = stan.build(program_code)
168
169
# Use fixed_param for models without parameters
170
fit = model.fixed_param(num_chains=1, num_samples=1000)
171
172
print(fit['y_pred'])
173
print(fit['z_pred'])
174
```
175
176
### Advanced Sampling Control
177
178
```python
179
import stan
180
import numpy as np
181
182
# Hierarchical model
183
program_code = """
184
data {
185
int<lower=0> J;
186
real y[J];
187
real<lower=0> sigma[J];
188
}
189
parameters {
190
real mu;
191
real<lower=0> tau;
192
real theta[J];
193
}
194
model {
195
mu ~ normal(0, 5);
196
tau ~ cauchy(0, 5);
197
theta ~ normal(mu, tau);
198
y ~ normal(theta, sigma);
199
}
200
"""
201
202
# Eight schools data
203
data = {
204
'J': 8,
205
'y': [28, 8, -3, 7, -1, 1, 18, 12],
206
'sigma': [15, 10, 16, 11, 9, 11, 10, 18]
207
}
208
209
model = stan.build(program_code, data=data)
210
211
# Sample with tight adaptation for difficult geometry
212
fit = model.sample(
213
num_chains=4,
214
num_samples=2000,
215
num_warmup=2000,
216
adapt_delta=0.99,
217
max_treedepth=15,
218
stepsize=0.01
219
)
220
```