or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-variational.mddata-io-utilities.mdgenerated-quantities.mdindex.mdinstallation-setup.mdmcmc-results.mdmodel-compilation.mdmodel-interface.mdoptimization-results.mdvariational-results.md

advanced-variational.mddocs/

0

# Advanced Variational Methods

1

2

Containers for advanced variational approximation methods including Pathfinder algorithm and Laplace approximation. These methods provide fast approximate inference alternatives to full MCMC.

3

4

## Capabilities

5

6

### CmdStanPathfinder

7

8

Container for Pathfinder algorithm results, which provides fast variational approximation using multiple optimization paths.

9

10

```python { .api }

11

class CmdStanPathfinder:

12

def draws(self):

13

"""

14

Get approximate posterior draws from Pathfinder.

15

16

Returns:

17

np.ndarray: Posterior draws (draws, parameters)

18

"""

19

20

def stan_variable(self, var):

21

"""

22

Get draws for specific Stan variable.

23

24

Parameters:

25

- var (str): Variable name

26

27

Returns:

28

np.ndarray: Draws for the variable

29

"""

30

31

def stan_variables(self):

32

"""

33

Get all Stan variables as dictionary.

34

35

Returns:

36

dict: Mapping from variable names to draw arrays

37

"""

38

39

def method_variables(self):

40

"""

41

Get Pathfinder diagnostic variables.

42

43

Returns:

44

dict: Diagnostic information from Pathfinder runs

45

"""

46

47

def create_inits(self, seed=None, chains=4):

48

"""

49

Create initial values by sampling from Pathfinder approximation.

50

51

Parameters:

52

- seed (int, optional): Random seed

53

- chains (int): Number of initial value sets to create

54

55

Returns:

56

list or dict: Initial value dictionaries for MCMC chains

57

"""

58

59

def save_csvfiles(self, dir=None):

60

"""

61

Save CSV output files to directory.

62

63

Parameters:

64

- dir (str or PathLike, optional): Target directory

65

66

Returns:

67

None

68

"""

69

```

70

71

**Pathfinder Properties:**

72

73

```python { .api }

74

pathfinder.metadata # InferenceMetadata: Run configuration and timing

75

pathfinder.column_names # Tuple[str, ...]: Parameter names

76

pathfinder.is_resampled # bool: Whether PSIS resampling was used

77

```

78

79

**Pathfinder Usage Examples:**

80

81

```python

82

# Run Pathfinder with multiple paths

83

pf = model.pathfinder(data=data, num_paths=8, draws=2000)

84

85

# Use for approximate inference

86

theta_approx = pf.stan_variable("theta")

87

print(f"Approximate posterior mean: {theta_approx.mean()}")

88

89

# Create initial values for MCMC

90

inits = pf.create_inits(seed=12345, chains=4)

91

mcmc_fit = model.sample(data=data, inits=inits, chains=4)

92

93

# Check diagnostics

94

diagnostics = pf.method_variables()

95

print("Pathfinder diagnostics:", diagnostics.keys())

96

```

97

98

### CmdStanLaplace

99

100

Container for Laplace approximation results, providing multivariate normal approximation around a posterior mode.

101

102

```python { .api }

103

class CmdStanLaplace:

104

def draws(self):

105

"""

106

Get approximate posterior draws from Laplace approximation.

107

108

Returns:

109

np.ndarray: Posterior draws (draws, parameters)

110

"""

111

112

def draws_pd(self, vars=None):

113

"""

114

Get draws as pandas DataFrame.

115

116

Parameters:

117

- vars (list of str, optional): Specific variables to include

118

119

Returns:

120

pd.DataFrame: Draws with parameter names

121

"""

122

123

def draws_xr(self, vars=None):

124

"""

125

Get draws as xarray Dataset.

126

127

Parameters:

128

- vars (list of str, optional): Specific variables to include

129

130

Returns:

131

xr.Dataset: Draws with coordinate labels

132

"""

133

134

def stan_variable(self, var):

135

"""

136

Get draws for specific Stan variable.

137

138

Parameters:

139

- var (str): Variable name

140

141

Returns:

142

np.ndarray: Draws for the variable

143

"""

144

145

def stan_variables(self):

146

"""

147

Get all Stan variables as dictionary.

148

149

Returns:

150

dict: Mapping from variable names to draw arrays

151

"""

152

153

def method_variables(self):

154

"""

155

Get diagnostic variables.

156

157

Returns:

158

dict: Diagnostic information including Jacobian

159

"""

160

161

def save_csvfiles(self, dir=None):

162

"""

163

Save CSV output files to directory.

164

165

Parameters:

166

- dir (str or PathLike, optional): Target directory

167

168

Returns:

169

None

170

"""

171

```

172

173

**Laplace Properties:**

174

175

```python { .api }

176

laplace.metadata # InferenceMetadata: Run configuration and timing

177

laplace.column_names # Tuple[str, ...]: Parameter names

178

laplace.mode # CmdStanMLE: Mode around which approximation is centered

179

```

180

181

**Laplace Usage Examples:**

182

183

```python

184

# First find the mode

185

mle = model.optimize(data=data)

186

187

# Run Laplace approximation around the mode

188

laplace = model.laplace_sample(data=data, mode=mle, draws=1000)

189

190

# Access approximation

191

theta_laplace = laplace.stan_variable("theta")

192

print(f"Laplace approximation mean: {theta_laplace.mean()}")

193

194

# Get mode information

195

mode_params = laplace.mode.optimized_params_dict()

196

print(f"Mode at: {mode_params}")

197

198

# Compare with xarray format

199

draws_xr = laplace.draws_xr()

200

print("Laplace draws structure:", draws_xr)

201

```

202

203

## Advanced Usage Patterns

204

205

### Pathfinder for MCMC Initialization

206

207

```python

208

# Use Pathfinder to generate good initial values

209

pf = model.pathfinder(data=data, num_paths=8)

210

211

# Create multiple initialization strategies

212

inits_list = []

213

for i in range(4): # 4 chains

214

inits_list.append(pf.create_inits(seed=i, chains=1))

215

216

# Run MCMC with Pathfinder initialization

217

mcmc = model.sample(

218

data=data,

219

inits=inits_list,

220

chains=4,

221

iter_warmup=500, # May need less warmup with good inits

222

iter_sampling=1000

223

)

224

```

225

226

### Approximation Quality Assessment

227

228

```python

229

# Compare Pathfinder, Laplace, and MCMC

230

pf = model.pathfinder(data=data, num_paths=4, draws=2000)

231

mle = model.optimize(data=data)

232

laplace = model.laplace_sample(data=data, mode=mle, draws=2000)

233

mcmc = model.sample(data=data, chains=4, iter_sampling=500)

234

235

# Compare posterior means

236

theta_pf = pf.stan_variable("theta").mean()

237

theta_laplace = laplace.stan_variable("theta").mean()

238

theta_mcmc = mcmc.stan_variable("theta").mean(axis=(0,1))

239

240

print(f"Pathfinder mean: {theta_pf}")

241

print(f"Laplace mean: {theta_laplace}")

242

print(f"MCMC mean: {theta_mcmc}")

243

244

# Compare uncertainties

245

print(f"Pathfinder std: {pf.stan_variable('theta').std()}")

246

print(f"Laplace std: {laplace.stan_variable('theta').std()}")

247

print(f"MCMC std: {mcmc.stan_variable('theta').std()}")

248

```

249

250

### Hierarchical Workflow

251

252

```python

253

# Stage 1: Fast approximation with Pathfinder

254

pf = model.pathfinder(data=data, num_paths=8)

255

256

# Stage 2: Refine with Laplace if unimodal

257

mle = model.optimize(data=data, inits=pf.create_inits(chains=1))

258

laplace = model.laplace_sample(data=data, mode=mle, draws=1000)

259

260

# Stage 3: Full MCMC for final inference (if needed)

261

mcmc = model.sample(

262

data=data,

263

inits=laplace.stan_variables(), # Use Laplace mean as init

264

chains=4

265

)

266

267

# Compare computational costs and accuracy

268

print("Pathfinder time:", pf.metadata.time_total)

269

print("Laplace time:", laplace.metadata.time_total)

270

print("MCMC time:", mcmc.metadata.time_total)

271

```

272

273

### Model Selection with Approximations

274

275

```python

276

models = {

277

"simple": CmdStanModel(stan_file="simple.stan"),

278

"complex": CmdStanModel(stan_file="complex.stan")

279

}

280

281

# Fast model comparison using Pathfinder

282

results = {}

283

for name, model in models.items():

284

pf = model.pathfinder(data=data, num_paths=4)

285

286

# Estimate log marginal likelihood (approximate)

287

log_lik = pf.method_variables().get("lp__", np.array([]))

288

if len(log_lik) > 0:

289

results[name] = {

290

"pathfinder": pf,

291

"approx_log_ml": np.mean(log_lik)

292

}

293

294

# Select best model for full analysis

295

best_model = max(results.keys(), key=lambda k: results[k]["approx_log_ml"])

296

print(f"Best model (approximate): {best_model}")

297

298

# Run full MCMC on selected model

299

final_fit = models[best_model].sample(data=data)

300

```