├── .Rbuildignore ├── .Rprofile ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── README.md ├── _site.yml ├── docs ├── index.html ├── lesson1-tasks.html ├── lesson1.html ├── lesson2-tasks.html ├── lesson2.html ├── lesson2_files │ └── figure-html │ │ ├── density-underdetermined-1.png │ │ └── density-underdetermined-2.png ├── lesson3-tasks.html ├── lesson3.html ├── lesson4-tasks.html ├── lesson4.html ├── lesson5.html ├── lesson6.html ├── site_libs │ ├── bootstrap-3.3.5 │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ ├── cerulean.min.css │ │ │ ├── cosmo.min.css │ │ │ ├── darkly.min.css │ │ │ ├── flatly.min.css │ │ │ ├── fonts │ │ │ │ ├── Lato.ttf │ │ │ │ ├── LatoBold.ttf │ │ │ │ ├── LatoItalic.ttf │ │ │ │ ├── NewsCycle.ttf │ │ │ │ ├── NewsCycleBold.ttf │ │ │ │ ├── OpenSans.ttf │ │ │ │ ├── OpenSansBold.ttf │ │ │ │ ├── OpenSansBoldItalic.ttf │ │ │ │ ├── OpenSansItalic.ttf │ │ │ │ ├── OpenSansLight.ttf │ │ │ │ ├── OpenSansLightItalic.ttf │ │ │ │ ├── Raleway.ttf │ │ │ │ ├── RalewayBold.ttf │ │ │ │ ├── Roboto.ttf │ │ │ │ ├── RobotoBold.ttf │ │ │ │ ├── RobotoLight.ttf │ │ │ │ ├── RobotoMedium.ttf │ │ │ │ ├── SourceSansPro.ttf │ │ │ │ ├── SourceSansProBold.ttf │ │ │ │ ├── SourceSansProItalic.ttf │ │ │ │ ├── SourceSansProLight.ttf │ │ │ │ └── Ubuntu.ttf │ │ │ ├── journal.min.css │ │ │ ├── lumen.min.css │ │ │ ├── paper.min.css │ │ │ ├── readable.min.css │ │ │ ├── sandstone.min.css │ │ │ ├── simplex.min.css │ │ │ ├── spacelab.min.css │ │ │ ├── united.min.css │ │ │ └── yeti.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── shim │ │ │ ├── html5shiv.min.js │ │ │ └── respond.min.js │ ├── header-attrs-2.25 │ │ └── header-attrs.js │ ├── highlightjs-9.12.0 │ │ ├── default.css │ │ ├── highlight.js │ │ └── textmate.css │ ├── jquery-3.6.0 │ │ ├── jquery-3.6.0.js │ │ ├── jquery-3.6.0.min.js │ │ └── jquery-3.6.0.min.map │ └── navigation-1.1 │ │ ├── codefolding-lua.css │ │ ├── codefolding.js │ │ ├── sourceembed.js │ │ └── tabsets.js └── stan │ ├── lesson1 │ ├── initial.stan │ └── with_sigma_prior.stan │ └── lesson2 │ └── neg_binom.stan ├── index.Rmd ├── lesson1-tasks.Rmd ├── lesson1.Rmd ├── lesson2-tasks.Rmd ├── lesson2.Rmd ├── lesson3-tasks.Rmd ├── lesson3.Rmd ├── lesson4-tasks.Rmd ├── lesson4.Rmd ├── lesson5.Rmd ├── lesson6.Rmd ├── modelling-in-stan-2024.Rproj ├── renv.lock ├── renv ├── .gitignore ├── activate.R └── settings.json ├── solutions ├── lesson1-solutions.Rmd └── lesson2-solutions.Rmd └── stan ├── lesson1 ├── initial.stan └── with_sigma_prior.stan └── lesson2 └── neg_binom.stan /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^renv$ 2 | ^renv\.lock$ 3 | ^sbc_extensions_paper\.Rproj$ 4 | ^\.Rproj\.user$ 5 | -------------------------------------------------------------------------------- /.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # User-specific files 9 | .Ruserdata 10 | 11 | # Example code in package build process 12 | *-Ex.R 13 | 14 | # Output files from R CMD build 15 | /*.tar.gz 16 | 17 | # Output files from R CMD check 18 | /*.Rcheck/ 19 | 20 | # RStudio files 21 | .Rproj.user/ 22 | 23 | # produced vignettes 24 | vignettes/*.html 25 | vignettes/*.pdf 26 | 27 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 28 | .httr-oauth 29 | 30 | # knitr and R markdown default cache directories 31 | *_cache/ 32 | /cache/ 33 | /_SBC_cache* 34 | 35 | # Temporary files created by R markdown 36 | *.utf8.md 37 | *.knit.md 38 | 39 | # R Environment Variables 40 | .Renviron 41 | .Rproj.user 42 | 43 | _figs/ 44 | /*_files/ 45 | /*.html/ 46 | 47 | *.nb.html 48 | *.exe 49 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: sbc_extensions_paper 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), 6 | comment = c(ORCID = "YOUR-ORCID-ID")) 7 | Description: What the package does (one paragraph). 8 | License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a 9 | license 10 | Encoding: UTF-8 11 | Roxygen: list(markdown = TRUE) 12 | RoxygenNote: 7.0.0 13 | Suggests: 14 | testthat (>= 3.0.0) 15 | Config/testthat/edition: 3 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SBC and various test quantities 2 | 3 | Simulations for the paper "Simulation-Based Calibration Checking for Bayesian Computation: The Choice of Test Quantities Shapes Sensitivity". Written in 4 | R markdown, using the [SBC](https://hyunjimoon.github.io/SBC/) R package. 5 | Code is written in R markdown (`.Rmd`), rendered HTML can be found at 6 | https://martinmodrak.github.io/sbc_test_quantities_paper. 7 | 8 | Contents: 9 | 10 | - `mvn.Rmd` - the multivariate normal examples for the main body of the paper (Section 4 - Numerical Experiments) 11 | - `ordered_simplex.Rmd` - the implementations of ordered simplex for the main body of the paper (Section 5 - Real-world case study) 12 | - `bernoulli.Rmd` - Examples in the Appendix B 13 | 14 | The code uses `renv` to recreate the same environment as we used to run the examples. 15 | Run `renv::restore()` after loading the project. 16 | 17 | The rendered site can be rebuilt with `rmarkdown::render_site()`. 18 | -------------------------------------------------------------------------------- /_site.yml: -------------------------------------------------------------------------------- 1 | name: "modelling-in-stan-2024" 2 | navbar: 3 | title: "Bayesian probabilistic programming in Stan - 2024 course" 4 | left: 5 | - text: "Home" 6 | href: index.html 7 | - text: "Lesson 1 - Tasks" 8 | href: lesson1-tasks.html 9 | - text: "Lesson 2 - Tasks" 10 | href: lesson2-tasks.html 11 | - text: "Lesson 3 - Tasks" 12 | href: lesson3-tasks.html 13 | output_dir: docs 14 | include: ["*.html", "*.png"] 15 | exclude: ["R", "*.R", "*.Rmd", "DESCRIPTION", "NAMESPACE", "renv.lock", "LICENSE", "tests", "solutions", "*.exe"] 16 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bayesian statistical modelling and workflow in Stan 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 273 | 274 | 275 |

Last updated: 2024-05-06 14:00:15.738025.

276 | 289 | 290 | 291 | 292 | 293 |
294 | 295 | 307 | 308 | 309 | 310 | 321 | 322 | 323 | 324 | 325 | 326 | 334 | 335 | 336 | 337 | -------------------------------------------------------------------------------- /docs/lesson1-tasks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 1 - Tasks 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Task 1: Installing Stan

276 |

Note: Windows users in both Stan and Python might need RTools 277 | installed. Martin has a flash drive with RTools installers so that you 278 | don’t have to wait for the large download.

279 |
280 |

R

281 |

We will use the cmdstanr package, follow https://mc-stan.org/cmdstanr/articles/cmdstanr.html

284 |
285 |
286 |

Python

287 |

We will use the CmdStanPy package, follow https://mc-stan.org/cmdstanpy/installation.html

290 |
291 |
292 |
293 |

Task 2: Hello World model

294 |

Create a file called initial.stan and paste the 295 | following simple model.

296 |
data {
297 |   int<lower=0> N;
298 |   vector[N] y;
299 | }
300 | 
301 | parameters {
302 |   real mu;
303 | }
304 | 
305 | model {
306 |   // likelihood
307 |   target += normal_lpdf(y | mu, 1);
308 |   // prior
309 |   target += normal_lpdf(mu | 0, 1);
310 | }
311 |

Note that we express all contributions to the target density 312 | explicitly with target +=.

313 |

The corresponding statistical model is

314 |

\[ 315 | y_i \sim N(\mu, 1) \\ 316 | \mu \sim N(0,1) 317 | \]

318 |

i.e. we are estimating the mean of a normal distribution with known 319 | standard deviation and a somewhat informative prior on the mean.

320 |

Note: You’ll notice many Stan models use statements like 321 | y ~ normal(mu, 1) instead of 322 | target += normal(y | mu, 1). We will discuss this 323 | alternative syntax and the differences in next lesson.

324 |

Simulate data for the model with 10 data points, using the same 325 | structure as the model assumes, i.e. draw \(\mu\) from its prior, then draw \(y\) (using rnorm in R, 328 | numpy.random.Generator.normal in Python)

329 |

Compile the model, prepare the data in a format for the model, fit 330 | the model and display a summary:

331 | 348 |

Inspect the summary - how big is the uncertainty? Are the “true” 349 | values we used in simulation recovered?

350 |
351 |
352 |

Task 3: Estimate sigma

353 |

Add a sigma parameter of type real to model 354 | the standard deviation, with a half-Normal prior i.e. the new 355 | mathematical model is:

356 |

\[ 357 | y_i \sim N(\mu, \sigma) \\ 358 | \mu \sim N(0,1) \\ 359 | \sigma \sim HalfN(0, 2) 360 | \]

361 |

Since standard deviation cannot be negative, add a 362 | <lower=0> constraint to sigma.

363 |

HMC needs the parameter space to be Euclidean (i.e. \(\mathbb{R}^K\) for some \(K\)), so when something is constrained, 366 | there is an implicit transformation, so Stan will use 367 | log(sigma) internally.

368 |

There is no builtin half-normal distribution in Stan. But it turns 369 | out, using a normal prior on a variable constrained to be positive is 370 | the same as using a half-normal distribution. We will go into the 371 | reasons for this and some nuances next time.

372 |

Generate data according to this model, i.e. first draw \(\mu\) and \(\sigma\) from their priors, then draw \(y\). You can draw from the half-normal 376 | distribution simply by taking the absolute value of a draw from the 377 | normal distribution.

378 |

Explore the summary, do you recover the true parameters?

379 |
380 |
381 |

Task 4: Our first convergence problems

382 |

Use the model from the previous task with dataset of size 1. What 383 | happens?

384 |

Is there a reason the model may not work well with just a single 385 | datapoint?

386 |

Does the model from Task 2 also have issues with a dataset of size 1? 387 | Why?

388 |

Bonus: Try this if you feel it won’t take you too 389 | much time. Assume that the single data point is \(y = 1\), make a contour and/or heatmap plot 391 | of the posterior density as a function \(\mu\) and \(\sigma\) (in R use 394 | dnorm( log = TRUE), in Python use 395 | scipy.stats.norm and the logpdf method).

396 |

Generally, to get a basic understanding of warnings about convergence 397 | from Stan, the guide at https://mc-stan.org/misc/warnings is IMHO quite good (I 399 | wrote most of it :-D).

400 |
401 |
402 |

Task 5: Prior as data

403 |

Add two new data elements of type real - 404 | mu_prior_mean and mu_prior_sd to define the 405 | location and scale of the normal prior for \(\mu\)

407 |

Should those data have some constraints attached? If yes, add them as 408 | well.

409 |

Test that the model now works with some of the datasets you generated 410 | previously.

411 |
412 |
413 |

Task 6: Prior influence

414 |

Generate a dataset of size 10 with the prior \(\mu \sim N(0,1), \sigma \sim HalfN(0, 2)\). 416 | Find the least extreme values of mu_prior_mean and 417 | mu_prior_sd that make the posterior generated by Stan 418 | exclude the true value of \(\mu\) from 419 | your simulation.

420 |

Try the same task with a dataset of size 3 and a dataset of size 421 | 100.

422 |
423 |
424 |

Task 7: Bayesian “t-test”

425 |

Expand the model so that you now have two sets of data (possibly of 426 | unequal size), each belonging to a different group and estimate the mean 427 | in the first group and the difference in means. More specifically, the 428 | model should look like this:

429 |

\[ 430 | y_A \sim N(\mu, \sigma_A) \\ 431 | y_B \sim N(\mu + \delta, \sigma_B) \\ 432 | \mu \sim N(0, 1)\\ 433 | \delta \sim N\left(0, \frac{1}{2}\right) \\ 434 | \sigma_A, \sigma_B \sim HalfN(0, 1) 435 | \]

436 |

(you can keep the location and scale of the prior as data, but you 437 | can also hardcode it)

438 |

Repeatedly simulate data according to the model and fit it. How big 439 | do the groups need to be, so that your posterior interval for \(\delta\) excludes 0 most of the time?

441 |
442 | 443 | 444 | 445 | 446 |
447 | 448 | 460 | 461 | 462 | 463 | 474 | 475 | 476 | 477 | 478 | 479 | 487 | 488 | 489 | 490 | -------------------------------------------------------------------------------- /docs/lesson1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 1 - The Basics 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Basics of Bayesian Inference

276 | 283 |

\[\begin{gather*} 284 | \pi_\text{joint}(y, \theta) = \pi_\text{obs}(y | \theta) 285 | \pi_\text{prior}(\theta)\\ 286 | \pi_\text{marg}\left(y \right) = \int_\Theta \mathrm{d} \theta \: 287 | \pi_{\text{obs}}(y | \theta) \pi_\text{prior}(\theta)\\ 288 | \pi_\text{post}(\theta | y) = \frac{\pi_\text{obs}(y | \theta) 289 | \pi_\text{prior}(\theta)}{\pi_\text{marg}\left(y \right)}. 290 | \end{gather*}\]

291 | 309 |

\[ 310 | y \sim N(\mu,\sigma) \\ 311 | \mu \sim N(0, 1) \\ 312 | \sigma \sim HalfN(0, 2) 313 | \]

314 | 350 |
351 |
352 |

Basics of Stan

353 | 400 |
401 |
402 |

The tasks

403 | 410 |
411 |
412 |

Summary after tasks

413 | 418 |
419 | 420 | 421 | 422 | 423 |
424 | 425 | 437 | 438 | 439 | 440 | 451 | 452 | 453 | 454 | 455 | 456 | 464 | 465 | 466 | 467 | -------------------------------------------------------------------------------- /docs/lesson2-tasks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 2 - Tasks 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Task 1: Prior predictive check

276 | 288 |
289 |
290 |

Task 2: Fitting a Poisson

291 | 298 |
299 |
302 |

Task 3: Detecting overdispersion with a posterior predictive 303 | check

304 | 312 |

R: - Use fit$draws(format = "draws_matrix") to get a 313 | matrix of draws, then use 314 | rpois`` to generate the predictions as the Stan model assumes - use eitherbayesplot::ppc_statwith a stat measuring the dispersion (e.g. variance, sd, ...) orbayesplot::ppc_dens_overlayPython: use eitherarviz.plot_bpv()withkind=“t_stat”and a stat measuring the dispersion (e.g. variance, sd, ...) orarviz.plot_ppc`

315 | 327 |
328 |
330 |

Task 4: A bit more open-ended exploration

331 |

Given the following data:

332 |
y :  2, 0, 11, 25, 9, 4, 17, 11, 8, 4, 5, 2, 6, 4, 8, 24, 0, 3, 6, 4, 12, 9, 5, 6, 2, 10, 4, 15, 0, 1, 87, 19, 2, 1, 38, 16, 5, 7, 18, 11, 1, 0, 7, 15, 5, 0, 6, 1, 0, 6, 34, 29, 7, 11, 5, 10, 8, 3, 12, 18, 7, 1, 18, 18, 6, 3, 37, 5, 1, 0, 22, 13, 1, 0, 26, 19, 6, 7, 21, 45 
333 | group :  "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B" 
334 | type :  "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y" 
335 |

Try to fit the neg. binomial model from task 3 with a shared mean and 336 | overdispersion parameter to the y column of the data.

337 |

The model does not represent the data well. Try to figure out what it 338 | is and fix it!

339 |

Hint: many PPCs can be performed per group, in R this is the 340 | ppc_xxx_grouped functions.

341 |
342 |
343 |

Task 5: Open-ended exploration 2

344 |

Given the following data:

345 |
y :  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 
346 | group :  "B", "C", "D", "B", "C", "B", "D", "C", "A", "D", "C", "C", "C", "D", "C", "C", "B", "B", "D", "C", "D", "C", "C", "A", "B", "D", "C", "D", "D", "D", "C", "D", "A", "A", "C", "D", "D", "C", "C", "B", "B", "C", "D", "D", "A", "D", "A", "B", "C", "A" 
347 |

Once again use the model from Task 3. Use posterior predictive check 348 | to determine what is wrong.

349 |

Can you fix it?

350 |
351 | 352 | 353 | 354 | 355 |
356 | 357 | 369 | 370 | 371 | 372 | 383 | 384 | 385 | 386 | 387 | 388 | 396 | 397 | 398 | 399 | -------------------------------------------------------------------------------- /docs/lesson2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 2 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
library(dplyr)
275 | library(magrittr)
276 | library(ggplot2)
277 | library(tidyr)
278 | theme_set(theme_minimal())
279 |
280 |

Some technical Stan stuff

281 | 298 |
plot_densities <- function(n_data_vals, mu_range = c(-3,3), log_sigma_range = c(-2,2)) {
299 |   set.seed(566522)
300 |   y = c(-0.6906332,  1.2873201, 2.0089285, 0.1347772, -0.8905993, -0.8171846, rnorm(max(1, max(n_data_vals))))
301 |   underdetermined_theory <- crossing(mu = seq(mu_range[1], mu_range[2], length.out = 200), log_sigma = seq(log_sigma_range[1], log_sigma_range[2], length.out = 200),
302 |            data.frame(y_id = 1:length(y), y = y), n_data = n_data_vals
303 |            ) %>%
304 |     filter(y_id <= n_data) %>%
305 |     mutate(log_density_point = dnorm(y, mu, exp(log_sigma), log = TRUE)) %>%
306 |     group_by(mu, log_sigma, n_data) %>%
307 |     summarise(log_density = sum(log_density_point), .groups = "drop") %>%
308 |     group_by(n_data) %>%
309 |     mutate(rel_density = exp(log_density - max(log_density))) %>%
310 |     ggplot(aes(x = mu, y = log_sigma, z = rel_density)) + geom_contour() + #geom_raster() + 
311 |     facet_wrap(~n_data, nrow = 1, labeller = label_bquote(cols = paste(N, " = ", .(n_data)) )) + scale_y_continuous("log(sigma)")
312 |   
313 |   underdetermined_theory
314 | }
315 | 
316 | plot_densities(c(1,2,8))
317 |

318 |
plot_densities(c(15, 30, 50), mu_range = c(-1,1), log_sigma_range = c(-0.5,1))
319 |

320 | 335 |
336 |
337 |

Using integers in Stan programs

338 | 362 |
363 |
364 |

Workflow

365 | 402 |
403 | 404 | 405 | 406 | 407 |
408 | 409 | 421 | 422 | 423 | 424 | 435 | 436 | 437 | 438 | 439 | 440 | 448 | 449 | 450 | 451 | -------------------------------------------------------------------------------- /docs/lesson2_files/figure-html/density-underdetermined-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/lesson2_files/figure-html/density-underdetermined-1.png -------------------------------------------------------------------------------- /docs/lesson2_files/figure-html/density-underdetermined-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/lesson2_files/figure-html/density-underdetermined-2.png -------------------------------------------------------------------------------- /docs/lesson3-tasks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 3 - Tasks 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Task 1: Bayesian “t-test”

276 |

This is a copy of Task 7 from Lesson 1

277 |

Expand the model from lesson 1 so that you now have two sets of data 278 | (possibly of unequal size), each belonging to a different group and 279 | estimate the mean in the first group and the difference in means. More 280 | specifically, the model should look like this:

281 |

\[ 282 | y_A \sim N(\mu, \sigma_A) \\ 283 | y_B \sim N(\mu + \delta, \sigma_B) \\ 284 | \mu \sim N(0, 1)\\ 285 | \delta \sim N\left(0, \frac{1}{2}\right) \\ 286 | \sigma_A, \sigma_B \sim HalfN(0, 1) 287 | \]

288 |

(you can keep the location and scale of the prior as data, but you 289 | can also hardcode it)

290 |

Repeatedly simulate data according to the model and fit it.

291 |

How big do the groups need to be, so that your posterior interval for 292 | \(\delta\) excludes 0 most of the time? 293 | No need for a very precise answer, just a ballpark estimate, so running 294 | at most 5 simulations per sample size setting should be enough to get a 295 | good grasp.

296 |
297 |
298 |

Task 2: Convert to “long format”

299 |

Adapt the model from the previous task so that a) the standard 300 | deviation (\(\sigma\)) is the same for 301 | all data and b) the observed \(y\) are 302 | all stored in a single vector of length \(N\) and another vector of length \(N\) encodes group membership. I.e. your 305 | data section should look something like:

306 |
data {
307 |    int<lower=0> N;
308 |    vector[N] y;
309 |    array[N] int<lower=0,upper=1> isB;
310 | }
311 |

Hint: after converting isB into a vector 312 | (with to_vector) you can obtain a vector of length 313 | N of means for all observations by addition and 314 | multiplication.

315 |

You can then directly pass the vector to normal_lpdf, 316 | i.e. have

317 |
target += normal_lpdf(y | __COMPUTATION_HERE__, sigma);
318 |

If stuck, see https://mc-stan.org/docs/stan-users-guide/regression.html

321 |

For extra credit, you may try to figure out how to keep the distinct 322 | standard deviations following a similar computation.

323 |
324 |
325 |

Task 3: Add a continuous predictor

326 |

Add a new continuous predictor (a vector of real numbers) for each 327 | data point and add an extra coefficient (a new variable in the 328 | parameters block) to model its influence.

329 |

Simulate data and check parameter recovery.

330 |
331 |
332 |

Task 4: Matrix multiplication

333 |

Make a copy of the model and convert it to matrix multiplication 334 | format. Make the number of columns in the design matrix variable. I.e. 335 | your data section should look something like:

336 |
data {
337 |   int<lower=0> N;   // number of data items
338 |   int<lower=0> K;   // number of predictors
339 |   matrix[N, K] x;   // predictor matrix
340 |   vector[N] y;      // outcome vector
341 | }
342 |

Test that with the same data, you get the same results as in the 343 | previous version (since Hamiltonian Monte Carlo is stochastic you won’t 344 | get exactly the same results, but they should be numerically very 345 | close)

346 |
347 |
348 |

Task 5: Compare to user’s guide

349 |

Compare what you’ve built with the example linear regression models 350 | in Stan’s User’s guide: https://mc-stan.org/docs/stan-users-guide/regression.html#linear-regression

353 |

Generally, don’t be afraid to use the User’s guide as a starting 354 | point for your models, it is a great resource!

355 |
356 |
357 |

Task 6: Dummy coding

358 |

Use dummy 360 | coding to extend the model to have 3 groups instead of 2 in the 361 | categorical predictor. Your Stan code should not need to change.

362 |

Simulate data, fit, check parameter recovery.

363 |
364 |
365 |

Task 7: Negative binomial regression

366 |

Starting with the previous model, create a negative binomial 367 | regression model with a log link.

368 |

Simulate data, fit, check parameter recovery (you can use a simpler 369 | set of predictors if you prefer).

370 |
371 | 372 | 373 | 374 | 375 |
376 | 377 | 389 | 390 | 391 | 392 | 403 | 404 | 405 | 406 | 407 | 408 | 416 | 417 | 418 | 419 | -------------------------------------------------------------------------------- /docs/lesson3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 3 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
library(dplyr)
275 | library(magrittr)
276 | library(ggplot2)
277 | library(tidyr)
278 | theme_set(theme_minimal())
279 |
280 |

First, let’s slow down a bit

281 |

Try to complete Task 283 | 3 and 4 from Lesson 2 (and possibly others from the previous 284 | lessons)

285 |

Pick projects!

286 |
287 |
288 |

Note on models

289 | 294 |
295 |
296 |

Linear regression

297 | 337 |

Now, let’s do some tasks. Note that they match workflow (simple stuff 338 | first, …)

339 |
340 | 341 | 342 | 343 | 344 |
345 | 346 | 358 | 359 | 360 | 361 | 372 | 373 | 374 | 375 | 376 | 377 | 385 | 386 | 387 | 388 | -------------------------------------------------------------------------------- /docs/lesson4-tasks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 4 - Tasks 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Task 1: Fixed to random effects

276 |

Start with the code for Lesson 278 | 3 - Task 6 (dummy coding) and/or the regression 280 | code from Stan User’s guide.

281 |

Convert the 3 categorical groups into a random intercept model, 282 | i.e.:

283 |
    284 |
  1. Remove the categorical variable from the model matrix
  2. 285 |
  3. Introduce new data elements for the model to represent 286 | the number of categories and the category each observation belongs 287 | to
  4. 288 |
289 | 294 |
    295 |
  1. Introduce new parameter elements:
  2. 296 |
297 | 302 |
    303 |
  1. Add the categorical predictor to the result of the matrix 304 | multiplication for the linear predictor.
  2. 305 |
306 | 310 |
    311 |
  1. Add a prior for the standard deviation and then put a 312 | normal(0, ...) prior on the category random intercepts
  2. 313 |
314 |

How does the fit change from the fixed effect

315 |
316 |
317 |

Task 2: Non-centered parametrization

318 |

Convert the above model to non-centered parametrization, i.e.:

319 |
    320 |
  1. Put a normal(0, 1) prior on the random intercept 321 | vector
  2. 322 |
  3. Multiply the raw parameters by the standard deviation in 323 | transformed parameters
  4. 324 |
325 |
326 | 327 | 328 | 329 | 330 |
331 | 332 | 344 | 345 | 346 | 347 | 358 | 359 | 360 | 361 | 362 | 363 | 371 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /docs/lesson4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 4 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 | 283 | 284 | 285 | 286 | 287 |
288 | 289 | 301 | 302 | 303 | 304 | 315 | 316 | 317 | 318 | 319 | 320 | 328 | 329 | 330 | 331 | -------------------------------------------------------------------------------- /docs/lesson6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Lesson 6 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 92 | 93 | 94 | 133 | 134 | 168 | 169 | 170 | 171 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 264 | 265 | 272 | 273 | 274 |
275 |

Ordinal models

276 | 293 |
294 | 295 | 296 | 297 | 298 |
299 | 300 | 312 | 313 | 314 | 315 | 326 | 327 | 328 | 329 | 330 | 331 | 339 | 340 | 341 | 342 | -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/Lato.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/Lato.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/LatoBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/LatoBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/LatoItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/LatoItalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/NewsCycle.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/NewsCycle.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/NewsCycleBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/NewsCycleBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSans.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansBoldItalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansItalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansLight.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/OpenSansLightItalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/Raleway.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/Raleway.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/RalewayBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/RalewayBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/Roboto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/Roboto.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoLight.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoMedium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/RobotoMedium.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansPro.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansPro.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProBold.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProItalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/SourceSansProLight.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/css/fonts/Ubuntu.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/css/fonts/Ubuntu.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinmodrak/modelling-in-stan-2024/76624a9750429b790d41990c126cfd9574b3e235/docs/site_libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/shim/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | // Only run this code in IE 8 5 | if (!!window.navigator.userAgent.match("MSIE 8")) { 6 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); 7 | }; 8 | -------------------------------------------------------------------------------- /docs/site_libs/bootstrap-3.3.5/shim/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl 2 | * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT 3 | * */ 4 | 5 | // Only run this code in IE 8 6 | if (!!window.navigator.userAgent.match("MSIE 8")) { 7 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/site_libs/highlightjs-9.12.0/default.css: -------------------------------------------------------------------------------- 1 | .hljs-literal { 2 | color: #990073; 3 | } 4 | 5 | .hljs-number { 6 | color: #099; 7 | } 8 | 9 | .hljs-comment { 10 | color: #998; 11 | font-style: italic; 12 | } 13 | 14 | .hljs-keyword { 15 | color: #900; 16 | font-weight: bold; 17 | } 18 | 19 | .hljs-string { 20 | color: #d14; 21 | } 22 | -------------------------------------------------------------------------------- /docs/site_libs/highlightjs-9.12.0/textmate.css: -------------------------------------------------------------------------------- 1 | .hljs-literal { 2 | color: rgb(88, 72, 246); 3 | } 4 | 5 | .hljs-number { 6 | color: rgb(0, 0, 205); 7 | } 8 | 9 | .hljs-comment { 10 | color: rgb(76, 136, 107); 11 | } 12 | 13 | .hljs-keyword { 14 | color: rgb(0, 0, 255); 15 | } 16 | 17 | .hljs-string { 18 | color: rgb(3, 106, 7); 19 | } 20 | -------------------------------------------------------------------------------- /docs/site_libs/navigation-1.1/codefolding-lua.css: -------------------------------------------------------------------------------- 1 | detaiks.chunk-details > summary.chunk-summary { 2 | text-align: right; 3 | } 4 | details.chunk-details[open] > summary.chunk-summary::after { 5 | content: "Hide"; 6 | } 7 | details.chunk-details[open] > summary.chunk-summary > span.chunk-summary-text { 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /docs/site_libs/navigation-1.1/codefolding.js: -------------------------------------------------------------------------------- 1 | 2 | window.initializeCodeFolding = function(show) { 3 | 4 | // handlers for show-all and hide all 5 | $("#rmd-show-all-code").click(function() { 6 | $('div.r-code-collapse').each(function() { 7 | $(this).collapse('show'); 8 | }); 9 | }); 10 | $("#rmd-hide-all-code").click(function() { 11 | $('div.r-code-collapse').each(function() { 12 | $(this).collapse('hide'); 13 | }); 14 | }); 15 | 16 | // index for unique code element ids 17 | var currentIndex = 1; 18 | 19 | // select all R code blocks 20 | var rCodeBlocks = $('pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan, pre.julia, pre.foldable'); 21 | rCodeBlocks.each(function() { 22 | // skip if the block has fold-none class 23 | if ($(this).hasClass('fold-none')) return; 24 | 25 | // create a collapsable div to wrap the code in 26 | var div = $('
'); 27 | var showThis = (show || $(this).hasClass('fold-show')) && !$(this).hasClass('fold-hide'); 28 | var id = 'rcode-643E0F36' + currentIndex++; 29 | div.attr('id', id); 30 | $(this).before(div); 31 | $(this).detach().appendTo(div); 32 | 33 | // add a show code button right above 34 | var showCodeText = $('' + (showThis ? 'Hide' : 'Show') + ''); 35 | var showCodeButton = $(''); 36 | showCodeButton.append(showCodeText); 37 | showCodeButton 38 | .attr('data-toggle', 'collapse') 39 | .attr('data-bs-toggle', 'collapse') // BS5 40 | .attr('data-target', '#' + id) 41 | .attr('data-bs-target', '#' + id) // BS5 42 | .attr('aria-expanded', showThis) 43 | .attr('aria-controls', id); 44 | 45 | var buttonRow = $('
'); 46 | var buttonCol = $('
'); 47 | 48 | buttonCol.append(showCodeButton); 49 | buttonRow.append(buttonCol); 50 | 51 | div.before(buttonRow); 52 | 53 | // show the div if necessary 54 | if (showThis) div.collapse('show'); 55 | 56 | // update state of button on show/hide 57 | // * Change text 58 | // * add a class for intermediate states styling 59 | div.on('hide.bs.collapse', function () { 60 | showCodeText.text('Show'); 61 | showCodeButton.addClass('btn-collapsing'); 62 | }); 63 | div.on('hidden.bs.collapse', function () { 64 | showCodeButton.removeClass('btn-collapsing'); 65 | }); 66 | div.on('show.bs.collapse', function () { 67 | showCodeText.text('Hide'); 68 | showCodeButton.addClass('btn-expanding'); 69 | }); 70 | div.on('shown.bs.collapse', function () { 71 | showCodeButton.removeClass('btn-expanding'); 72 | }); 73 | 74 | }); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /docs/site_libs/navigation-1.1/sourceembed.js: -------------------------------------------------------------------------------- 1 | 2 | window.initializeSourceEmbed = function(filename) { 3 | $("#rmd-download-source").click(function() { 4 | var src = $("#rmd-source-code").html(); 5 | var a = document.createElement('a'); 6 | a.href = "data:text/x-r-markdown;base64," + src; 7 | a.download = filename; 8 | document.body.appendChild(a); 9 | a.click(); 10 | document.body.removeChild(a); 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /docs/site_libs/navigation-1.1/tabsets.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * jQuery Plugin: Sticky Tabs 5 | * 6 | * @author Aidan Lister 7 | * adapted by Ruben Arslan to activate parent tabs too 8 | * http://www.aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/ 9 | */ 10 | (function($) { 11 | "use strict"; 12 | $.fn.rmarkdownStickyTabs = function() { 13 | var context = this; 14 | // Show the tab corresponding with the hash in the URL, or the first tab 15 | var showStuffFromHash = function() { 16 | var hash = window.location.hash; 17 | var selector = hash ? 'a[href="' + hash + '"]' : 'li.active > a'; 18 | var $selector = $(selector, context); 19 | if($selector.data('toggle') === "tab") { 20 | $selector.tab('show'); 21 | // walk up the ancestors of this element, show any hidden tabs 22 | $selector.parents('.section.tabset').each(function(i, elm) { 23 | var link = $('a[href="#' + $(elm).attr('id') + '"]'); 24 | if(link.data('toggle') === "tab") { 25 | link.tab("show"); 26 | } 27 | }); 28 | } 29 | }; 30 | 31 | 32 | // Set the correct tab when the page loads 33 | showStuffFromHash(context); 34 | 35 | // Set the correct tab when a user uses their back/forward button 36 | $(window).on('hashchange', function() { 37 | showStuffFromHash(context); 38 | }); 39 | 40 | // Change the URL when tabs are clicked 41 | $('a', context).on('click', function(e) { 42 | history.pushState(null, null, this.href); 43 | showStuffFromHash(context); 44 | }); 45 | 46 | return this; 47 | }; 48 | }(jQuery)); 49 | 50 | window.buildTabsets = function(tocID) { 51 | 52 | // build a tabset from a section div with the .tabset class 53 | function buildTabset(tabset) { 54 | 55 | // check for fade and pills options 56 | var fade = tabset.hasClass("tabset-fade"); 57 | var pills = tabset.hasClass("tabset-pills"); 58 | var navClass = pills ? "nav-pills" : "nav-tabs"; 59 | 60 | // determine the heading level of the tabset and tabs 61 | var match = tabset.attr('class').match(/level(\d) /); 62 | if (match === null) 63 | return; 64 | var tabsetLevel = Number(match[1]); 65 | var tabLevel = tabsetLevel + 1; 66 | 67 | // find all subheadings immediately below 68 | var tabs = tabset.find("div.section.level" + tabLevel); 69 | if (!tabs.length) 70 | return; 71 | 72 | // create tablist and tab-content elements 73 | var tabList = $(''); 74 | $(tabs[0]).before(tabList); 75 | var tabContent = $('
'); 76 | $(tabs[0]).before(tabContent); 77 | 78 | // build the tabset 79 | var activeTab = 0; 80 | tabs.each(function(i) { 81 | 82 | // get the tab div 83 | var tab = $(tabs[i]); 84 | 85 | // get the id then sanitize it for use with bootstrap tabs 86 | var id = tab.attr('id'); 87 | 88 | // see if this is marked as the active tab 89 | if (tab.hasClass('active')) 90 | activeTab = i; 91 | 92 | // remove any table of contents entries associated with 93 | // this ID (since we'll be removing the heading element) 94 | $("div#" + tocID + " li a[href='#" + id + "']").parent().remove(); 95 | 96 | // sanitize the id for use with bootstrap tabs 97 | id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_'); 98 | tab.attr('id', id); 99 | 100 | // get the heading element within it, grab it's text, then remove it 101 | var heading = tab.find('h' + tabLevel + ':first'); 102 | var headingText = heading.html(); 103 | heading.remove(); 104 | 105 | // build and append the tab list item 106 | var a = $('' + headingText + ''); 107 | a.attr('href', '#' + id); 108 | a.attr('aria-controls', id); 109 | var li = $('
  • '); 110 | li.append(a); 111 | tabList.append(li); 112 | 113 | // set it's attributes 114 | tab.attr('role', 'tabpanel'); 115 | tab.addClass('tab-pane'); 116 | tab.addClass('tabbed-pane'); 117 | if (fade) 118 | tab.addClass('fade'); 119 | 120 | // move it into the tab content div 121 | tab.detach().appendTo(tabContent); 122 | }); 123 | 124 | // set active tab 125 | $(tabList.children('li')[activeTab]).addClass('active'); 126 | var active = $(tabContent.children('div.section')[activeTab]); 127 | active.addClass('active'); 128 | if (fade) 129 | active.addClass('in'); 130 | 131 | if (tabset.hasClass("tabset-sticky")) 132 | tabset.rmarkdownStickyTabs(); 133 | } 134 | 135 | // convert section divs with the .tabset class to tabsets 136 | var tabsets = $("div.section.tabset"); 137 | tabsets.each(function(i) { 138 | buildTabset($(tabsets[i])); 139 | }); 140 | }; 141 | 142 | -------------------------------------------------------------------------------- /docs/stan/lesson1/initial.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | vector[N] y; 4 | } 5 | 6 | parameters { 7 | real mu; 8 | } 9 | 10 | model { 11 | // likelihood 12 | target += normal_lpdf(y | mu, 1); 13 | // prior 14 | target += normal_lpdf(mu | 0, 1); 15 | } 16 | -------------------------------------------------------------------------------- /docs/stan/lesson1/with_sigma_prior.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | vector[N] y; 4 | real sigma_prior_sd; 5 | real mu_prior_mean; 6 | real mu_prior_sd; 7 | } 8 | 9 | parameters { 10 | real mu; 11 | real sigma; 12 | } 13 | 14 | model { 15 | // likelihood 16 | target += normal_lpdf(y | mu, sigma); 17 | // prior 18 | target += normal_lpdf(mu | mu_prior_mean, mu_prior_sd); 19 | target += normal_lpdf(sigma | 0, sigma_prior_sd); 20 | } 21 | -------------------------------------------------------------------------------- /docs/stan/lesson2/neg_binom.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | array[N] int y; 4 | } 5 | 6 | parameters { 7 | real log_mu; 8 | real phi; 9 | } 10 | 11 | model { 12 | // likelihood 13 | target += neg_binomial_2_log_lpmf(y | log_mu, phi); 14 | // prior 15 | target += normal_lpdf(log_mu | 2, 1); 16 | target += exponential_lpdf(phi | 1); 17 | } 18 | -------------------------------------------------------------------------------- /index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Bayesian statistical modelling and workflow in Stan" 3 | output: html_document 4 | --- 5 | 6 | Last updated: `r Sys.time()`. 7 | 8 | - Lesson 1: [outline](lesson1.html), [tasks](lesson1-tasks.html) 9 | - Lesson 2: [outline](lesson2.html), [tasks](lesson2-tasks.html) 10 | - Lesson 3: [outline](lesson3.html), [tasks](lesson3-tasks.html) 11 | - Lesson 4: [outline](lesson4.html), [tasks](lesson4-tasks.html) 12 | - Lesson 5: [outline](lesson5.html), [tasks](lesson5-tasks.html) 13 | - Lesson 6: [outline](lesson6.html), (no tasks given) 14 | -------------------------------------------------------------------------------- /lesson1-tasks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 1 - Tasks" 3 | output: html_document 4 | --- 5 | 6 | 7 | ## Task 1: Installing Stan 8 | 9 | Note: Windows users in both Stan and Python might need RTools installed. 10 | Martin has a flash drive with RTools installers so that you don't 11 | have to wait for the large download. 12 | 13 | ### R 14 | 15 | We will use the `cmdstanr` package, follow https://mc-stan.org/cmdstanr/articles/cmdstanr.html 16 | 17 | 18 | ### Python 19 | 20 | We will use the `CmdStanPy` package, follow https://mc-stan.org/cmdstanpy/installation.html 21 | 22 | 23 | ## Task 2: Hello World model 24 | 25 | Create a file called `initial.stan` and paste the following simple model. 26 | 27 | ```{r, comment="", echo=FALSE} 28 | cat(readLines("stan/lesson1/initial.stan"), sep = "\n") 29 | ``` 30 | 31 | Note that we express all contributions to the target density explicitly with `target += `. 32 | 33 | The corresponding statistical model is 34 | 35 | $$ 36 | y_i \sim N(\mu, 1) \\ 37 | \mu \sim N(0,1) 38 | $$ 39 | 40 | i.e. we are estimating the mean of a normal distribution with known standard deviation and 41 | a somewhat informative prior on the mean. 42 | 43 | _Note: You'll notice many Stan models use statements like `y ~ normal(mu, 1)` instead of `target += normal(y | mu, 1)`. We will discuss this alternative syntax and the differences in next lesson. _ 44 | 45 | Simulate data for the model with 10 data points, using the same structure as the model assumes, i.e. draw $\mu$ from its prior, then draw $y$ (using `rnorm` in R, `numpy.random.Generator.normal` in Python) 46 | 47 | Compile the model, prepare the data in a format for the model, fit the model and display a summary: 48 | 49 | - In R: https://mc-stan.org/cmdstanr/articles/cmdstanr.html#compiling-a-model 50 | - You may want to use `options(mc.cores = 4)` to compute chains in parallel. 51 | - In Python: https://mc-stan.org/cmdstanpy/users-guide/hello_world.html, you can also use the Arviz package - convert the CmdStanPy object to `InferenceData` via 52 | [arviz.from_cmdstanpy](https://python.arviz.org/en/latest/api/generated/arviz.from_cmdstanpy.html) and then use [arviz.summary](https://python.arviz.org/en/latest/api/generated/arviz.summary.html) 53 | 54 | Inspect the summary - how big is the uncertainty? Are the "true" values we used in simulation recovered? 55 | 56 | ## Task 3: Estimate `sigma` 57 | 58 | Add a `sigma` parameter of type `real` to model the standard deviation, with a half-Normal prior i.e. the new mathematical model is: 59 | 60 | $$ 61 | y_i \sim N(\mu, \sigma) \\ 62 | \mu \sim N(0,1) \\ 63 | \sigma \sim HalfN(0, 2) 64 | $$ 65 | 66 | Since standard deviation cannot be negative, add a `` constraint to `sigma`. 67 | 68 | HMC needs the parameter space to be Euclidean (i.e. $\mathbb{R}^K$ for some $K$), so when something is constrained, there is an implicit transformation, so Stan will use `log(sigma)` internally. 69 | 70 | There is no builtin half-normal distribution in Stan. But it turns out, using a normal prior on a variable constrained to be positive is the same as using a half-normal distribution. We will go into the reasons for this and some nuances next time. 71 | 72 | 73 | Generate data according to this model, i.e. first draw $\mu$ and $\sigma$ from their priors, then draw $y$. You can draw from the half-normal distribution simply by taking the absolute value of a draw from the normal distribution. 74 | 75 | Explore the summary, do you recover the true parameters? 76 | 77 | 78 | ## Task 4: Our first convergence problems 79 | 80 | Use the model from the previous task with dataset of size 1. What happens? 81 | 82 | Is there a reason the model may not work well with just a single datapoint? 83 | 84 | Does the model from Task 2 also have issues with a dataset of size 1? Why? 85 | 86 | **Bonus:** Try this if you feel it won't take you too much time. Assume that the single data point is $y = 1$, make a contour and/or heatmap plot of the posterior density as a function $\mu$ and $\sigma$ (in R use `dnorm( log = TRUE)`, in Python use `scipy.stats.norm` and the `logpdf` method). 87 | 88 | Generally, to get a basic understanding of warnings about convergence from Stan, the guide at https://mc-stan.org/misc/warnings is IMHO quite good (I wrote most of it :-D). 89 | 90 | ## Task 5: Prior as data 91 | 92 | Add two new data elements of type `real` - `mu_prior_mean` and `mu_prior_sd` to define the location and scale of the normal prior for $\mu$ 93 | 94 | Should those data have some constraints attached? If yes, add them as well. 95 | 96 | Test that the model now works with some of the datasets you generated previously. 97 | 98 | ## Task 6: Prior influence 99 | 100 | Generate a dataset of size 10 with the prior $\mu \sim N(0,1), \sigma \sim HalfN(0, 2)$. 101 | Find the least extreme values of `mu_prior_mean` and `mu_prior_sd` that make the posterior 102 | generated by Stan exclude the true value of $\mu$ from your simulation. 103 | 104 | Try the same task with a dataset of size 3 and a dataset of size 100. 105 | 106 | ## Task 7: Bayesian "t-test" 107 | 108 | Expand the model so that you now have two sets of data (possibly of unequal size), each belonging to a different group and 109 | estimate the mean in the first group and the difference in means. More specifically, the model should look like this: 110 | 111 | $$ 112 | y_A \sim N(\mu, \sigma_A) \\ 113 | y_B \sim N(\mu + \delta, \sigma_B) \\ 114 | \mu \sim N(0, 1)\\ 115 | \delta \sim N\left(0, \frac{1}{2}\right) \\ 116 | \sigma_A, \sigma_B \sim HalfN(0, 1) 117 | $$ 118 | 119 | (you can keep the location and scale of the prior as data, but you can also hardcode it) 120 | 121 | Repeatedly simulate data according to the model and fit it. 122 | How big do the groups need to be, so that your posterior interval for $\delta$ excludes 0 most of the time? 123 | 124 | -------------------------------------------------------------------------------- /lesson1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 1 - The Basics" 3 | output: html_document 4 | --- 5 | 6 | ```{r include=FALSE} 7 | # In 2024, the first two sections (Intro to Bayesian stats, intro to computations) took ~45 mins each, the third section (Intro to Stan) took about 30 minutes 8 | ``` 9 | 10 | 11 | ## Basics of Bayesian Inference 12 | 13 | - Bayes theorem for events 14 | - Exercise - which terms should go into nominator/denumerator? 15 | - Bayes theorem for models 16 | 17 | \begin{gather*} 18 | \pi_\text{joint}(y, \theta) = \pi_\text{obs}(y | \theta) \pi_\text{prior}(\theta)\\ 19 | \pi_\text{marg}\left(y \right) = \int_\Theta \mathrm{d} \theta \: \pi_{\text{obs}}(y | \theta) \pi_\text{prior}(\theta)\\ 20 | \pi_\text{post}(\theta | y) = \frac{\pi_\text{obs}(y | \theta) \pi_\text{prior}(\theta)}{\pi_\text{marg}\left(y \right)}. 21 | \end{gather*} 22 | 23 | 24 | - Bayesian statistics $\neq$ Bayesian epistemology 25 | - Problems with catchall hypothesis 26 | - Problems in computation of Bayes factors 27 | - Problems with selective inference 28 | - Compare to modern falsificationist ideas, notably Mayo (e.g. [Mayo 2018, SIST](https://www.cambridge.org/core/books/statistical-inference-as-severe-testing/D9DF409EF568090F3F60407FF2B973B2) --- I can lend you a copy, or [Mayo & Spanos 2011](https://doi.org/10.1016/B978-0-444-51862-0.50005-8)) 29 | - Liftoff 30 | - Modelling notation, e.g. 31 | 32 | $$ 33 | y \sim N(\mu,\sigma) \\ 34 | \mu \sim N(0, 1) \\ 35 | \sigma \sim HalfN(0, 2) 36 | $$ 37 | 38 | - Modelled vs. unmodelled data 39 | - Great intro to the underlying philosophical ideas: Chapters 1 - 2 of McElreath's "Statistical Rethinking" - available freely online at https://xcelab.net/rmpubs/sr2/statisticalrethinking2_chapters1and2.pdf 40 | - McElreath also has great free course on Bayesian statistics at https://github.com/rmcelreath/stat_rethinking_2024 41 | 42 | - Extracting information from probability distributions via expectation values (see [Mike Betancourt's writing](https://betanalpha.github.io/assets/case_studies/probabilistic_computation.html) for a _very_ detailed coverage) 43 | 44 | - MCMC algorithms allow us to sample posterior 45 | - What is a _chain_ 46 | - Convergence, Rhat, ESS 47 | - HMC - show example, requires gradient 48 | - Conceptually two components --- random initial momentum for each trajectory 49 | makes the chain explore, preference for high density regions makes the chain spend more time there. 50 | - Wax poetic how HMC is great 51 | - HMC will work great, if gradient is useful 52 | - HMC has good diagnostic - the "divergence" 53 | 54 | 55 | - What is needed to be proficient at probabilistic programming? 56 | - Mathematical probability/statistics 57 | - Numerics 58 | - A little software engineering 59 | 60 | ## Basics of Stan 61 | 62 | - A decent tutorial covering similar ground as we did (and some more) is at https://betanalpha.github.io/assets/case_studies/stan_intro.html Note that the example R code there uses the `rstan` package, while we will use the newer `cmdstanr` package. 63 | - Stan documentation: 64 | - [language reference](https://mc-stan.org/docs/reference-manual/index.html) - how the language and algorithms work 65 | - [function reference](https://mc-stan.org/docs/functions-reference/index.html) - individual functions available in the language 66 | - [user's guide](https://mc-stan.org/docs/stan-users-guide/index.html) - worked out implementations of many model classes 67 | - Stan has very helpful community at https://discourse.mc-stan.org 68 | - Fundamentally a Stan program computes logarithm of the density (and its gradient, Hessian via autodiff) 69 | - Why logarithms? 70 | - Stan is statically typed (and generally quite restrictive). Discuss pros and cons. 71 | - Stan architecture: 72 | - Math library + autodiff 73 | - The language 74 | - The interfaces 75 | - compiler to C++, compile C++ 76 | - Go through the ["hello world" model](stan/lesson1/initial.stan) for the lesson. 77 | - Main program blocks 78 | - `data` (both modelled and non-modelled) 79 | - `parameters` 80 | - `model` 81 | - `target += ` statements 82 | - `_lpdf` 83 | 84 | ## The tasks 85 | 86 | - Start a project to contain your coursework 87 | - In general: we expect you to use online documentation etc. a lot, just like 88 | in "real life" 89 | - [Task description](lesson1-tasks.html) - separate page 90 | 91 | ## Summary after tasks 92 | 93 | - Constraints 94 | - Divergences as helpful diagnostics 95 | - Discuss project proposals 96 | -------------------------------------------------------------------------------- /lesson2-tasks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 2 - Tasks" 3 | output: html_document 4 | --- 5 | 6 | 7 | ## Task 1: Prior predictive check 8 | 9 | - Let us take a vague $N(0, 10)$ prior on the logarithm of the mean of a Poisson distribution. Run a prior predictive check, is there anything suspicious? 10 | - Find a prior on the mean of Poisson distribution (or its logarithm - you pick) that matches this rough prior 11 | knowledge: 12 | - Zeroes are quite unlikely 13 | - Most values should be between 2 and 15 14 | - Values above 18 are quite unlikely 15 | 16 | 17 | 18 | ## Task 2: Fitting a Poisson 19 | 20 | - Build a model that takes an array of integers 21 | - Accept arguments for prior for the logarithm of the mean as data 22 | - Simulate 20 values from a Poisson distribution with known mean. Do you recover the values? 23 | 24 | ## Task 3: Detecting overdispersion with a posterior predictive check 25 | 26 | - Simulate 30 values with neg. binomial with $\phi = \frac{1}{2}$ (`size` in R's `rnbinom`), fit with the model from Task 2. Do you recover the simulated mean of the neg. binomial? 27 | 28 | - Try to detect the model-data mismatch with a posterior predictive check. 29 | 30 | 31 | R: 32 | - Use `fit$draws(format = "draws_matrix")` to get a matrix of draws, then use `rpois`` to generate the predictions as the Stan model assumes 33 | - use either `bayesplot::ppc_stat` with a stat measuring the dispersion (e.g. variance, sd, ...) or `bayesplot::ppc_dens_overlay` 34 | Python: use either `arviz.plot_bpv()` with `kind="t_stat"` and a stat measuring the dispersion (e.g. variance, sd, ...) or `arviz.plot_ppc` 35 | 36 | - What is the smallest number of observations we need to reliably detect the problem? 37 | 38 | - Implement a negative binomial model and see how the check behaves now. 39 | - Use [`neg_binomial_2_lpmf`](https://mc-stan.org/docs/functions-reference/unbounded_discrete_distributions.html#nbalt)) 40 | - Put an `exponential(1)` prior on the overdispersion parameter. 41 | 42 | ## Task 4: A bit more open-ended exploration 43 | 44 | Given the following data: 45 | 46 | ``` 47 | y : 2, 0, 11, 25, 9, 4, 17, 11, 8, 4, 5, 2, 6, 4, 8, 24, 0, 3, 6, 4, 12, 9, 5, 6, 2, 10, 4, 15, 0, 1, 87, 19, 2, 1, 38, 16, 5, 7, 18, 11, 1, 0, 7, 15, 5, 0, 6, 1, 0, 6, 34, 29, 7, 11, 5, 10, 8, 3, 12, 18, 7, 1, 18, 18, 6, 3, 37, 5, 1, 0, 22, 13, 1, 0, 26, 19, 6, 7, 21, 45 48 | group : "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B" 49 | type : "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y", "X", "X", "Y", "Y" 50 | ``` 51 | 52 | Try to fit the neg. binomial model from task 3 with a shared mean and overdispersion parameter to the `y` column of the data. 53 | 54 | The model does not represent the data well. Try to figure out what it is and fix it! 55 | 56 | Hint: many PPCs can be performed per group, in R this is the `ppc_xxx_grouped` functions. 57 | 58 | 59 | ## Task 5: Open-ended exploration 2 60 | 61 | Given the following data: 62 | 63 | ``` 64 | y : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 65 | group : "B", "C", "D", "B", "C", "B", "D", "C", "A", "D", "C", "C", "C", "D", "C", "C", "B", "B", "D", "C", "D", "C", "C", "A", "B", "D", "C", "D", "D", "D", "C", "D", "A", "A", "C", "D", "D", "C", "C", "B", "B", "C", "D", "D", "A", "D", "A", "B", "C", "A" 66 | ``` 67 | 68 | Once again use the model from Task 3. Use posterior predictive check to determine what is wrong. 69 | 70 | Can you fix it? 71 | -------------------------------------------------------------------------------- /lesson2.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 2" 3 | output: html_document 4 | --- 5 | 6 | ```{r setup} 7 | library(dplyr) 8 | library(magrittr) 9 | library(ggplot2) 10 | library(tidyr) 11 | theme_set(theme_minimal()) 12 | ``` 13 | 14 | 15 | 16 | ## Some technical Stan stuff 17 | 18 | 19 | - Back to [Task 4](https://martinmodrak.github.io/modelling-in-stan-2024/lesson1-tasks.html#task-4-our-first-convergence-problems) from past lesson 20 | - Here is a plot of how likelihood of the simple normal model with unknown mean and standard deviation changes as we add data points. Note that for N=1 the plot is truncated as the density grows without bounds as $\log \sigma \to \infty$ and $\mu \to y_1$. 21 | - The plots don't include prior, just the likelihood. Prior improves things a bit, but not enough (as witnessed by the warnings from Stan) 22 | - Note that the likelihood is still visibly skewed (and thus non-normal) even for quite large datasets. 23 | 24 | ```{r density-underdetermined} 25 | plot_densities <- function(n_data_vals, mu_range = c(-3,3), log_sigma_range = c(-2,2)) { 26 | set.seed(566522) 27 | y = c(-0.6906332, 1.2873201, 2.0089285, 0.1347772, -0.8905993, -0.8171846, rnorm(max(1, max(n_data_vals)))) 28 | underdetermined_theory <- crossing(mu = seq(mu_range[1], mu_range[2], length.out = 200), log_sigma = seq(log_sigma_range[1], log_sigma_range[2], length.out = 200), 29 | data.frame(y_id = 1:length(y), y = y), n_data = n_data_vals 30 | ) %>% 31 | filter(y_id <= n_data) %>% 32 | mutate(log_density_point = dnorm(y, mu, exp(log_sigma), log = TRUE)) %>% 33 | group_by(mu, log_sigma, n_data) %>% 34 | summarise(log_density = sum(log_density_point), .groups = "drop") %>% 35 | group_by(n_data) %>% 36 | mutate(rel_density = exp(log_density - max(log_density))) %>% 37 | ggplot(aes(x = mu, y = log_sigma, z = rel_density)) + geom_contour() + #geom_raster() + 38 | facet_wrap(~n_data, nrow = 1, labeller = label_bquote(cols = paste(N, " = ", .(n_data)) )) + scale_y_continuous("log(sigma)") 39 | 40 | underdetermined_theory 41 | } 42 | 43 | plot_densities(c(1,2,8)) 44 | plot_densities(c(15, 30, 50), mu_range = c(-1,1), log_sigma_range = c(-0.5,1)) 45 | ``` 46 | 47 | - Explain divergences - we will mostly follow https://mc-stan.org/misc/warnings 48 | - Divergences are your friend! 49 | - Sampling statements vs. target increments (https://mc-stan.org/docs/reference-manual/statements.html#sampling-statements.section) 50 | - "Up to a constant" - recall the half-normal prior for sigma. 51 | - `xx_lupdf`, `xx_lupmf` 52 | 53 | ## Using integers in Stan programs 54 | 55 | - Ints can only ever be data 56 | - Arrays are declared as `array[size] base_type;` ([arrays in Stan manual](https://mc-stan.org/docs/reference-manual/types.html#array-data-types.section)) 57 | - i.e. array of `N` ints is `array[N] int;` 58 | - You can have arrays of anything (i.e. vectors, matrices, bounded integers, ...) 59 | - Poisson and negative binomial distibution 60 | - Modelling log mean 61 | - The mean - overdispersion parametrization of negative binomial 62 | - In R, you can use `rnbinom(mu = mean, size = overdispersion)` 63 | - In Python, it seems you need to convert manually, see https://stackoverflow.com/a/62460072/802009 for Python 64 | 65 | ## Workflow 66 | 67 | - We will follow the Bayesian workflow from https://arxiv.org/abs/2011.01808 - we'll start with the most useful and simple steps in this lesson. 68 | - Build slowly and test as many assumptions of the model as possible 69 | - The assumptions will usually be wrong. But are they importantly wrong? 70 | - The goal is to be able to confidently build complex models 71 | - Steps of modelling, that need to be checked: 72 | - Prior, fit to data (likelihood), computation 73 | - Checking parameter recovery from simulations is a simple computation check 74 | - Priors can (and should) be tested: _prior predictive check_ 75 | - Simulate data from the prior, check that the data match domain expertise 76 | - If they don't the prior is bad 77 | - It may however be unclear how to get a better prior... 78 | - Posterior predictive checks: 79 | - Compute something about a dataset (e.g. variance for each group of observations) 80 | - Copmute the same something about each posterior draw 81 | - If the values for the actual dataset lie in the extreme of the posterior distribution, something is wrong 82 | - Simple model first. Individual components first separately, then joined. 83 | -------------------------------------------------------------------------------- /lesson3-tasks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 3 - Tasks" 3 | output: html_document 4 | --- 5 | 6 | 7 | 8 | ## Task 1: Bayesian "t-test" 9 | 10 | __This is a copy of Task 7 from Lesson 1__ 11 | 12 | Expand the model from lesson 1 so that you now have two sets of data (possibly of unequal size), each belonging to a different group and 13 | estimate the mean in the first group and the difference in means. More specifically, the model should look like this: 14 | 15 | $$ 16 | y_A \sim N(\mu, \sigma_A) \\ 17 | y_B \sim N(\mu + \delta, \sigma_B) \\ 18 | \mu \sim N(0, 1)\\ 19 | \delta \sim N\left(0, \frac{1}{2}\right) \\ 20 | \sigma_A, \sigma_B \sim HalfN(0, 1) 21 | $$ 22 | 23 | (you can keep the location and scale of the prior as data, but you can also hardcode it) 24 | 25 | Repeatedly simulate data according to the model and fit it. 26 | 27 | How big do the groups need to be, so that your posterior interval for $\delta$ excludes 0 most of the time? No need for a very precise answer, just a ballpark estimate, so running at most 5 simulations per sample size setting should be enough to get a good grasp. 28 | 29 | 30 | ## Task 2: Convert to "long format" 31 | 32 | Adapt the model from the previous task so that a) the standard deviation ($\sigma$) is the same for all data and b) the observed $y$ are all stored in a single vector of length $N$ and another vector of length $N$ encodes group membership. I.e. your `data` section should look something like: 33 | 34 | ``` 35 | data { 36 | int N; 37 | vector[N] y; 38 | array[N] int isB; 39 | } 40 | ``` 41 | 42 | Hint: after converting `isB` into a `vector` (with `to_vector`) you can obtain 43 | a vector of length `N` of means for all observations by addition and multiplication. 44 | 45 | You can then directly pass the vector to `normal_lpdf`, i.e. have 46 | 47 | ``` 48 | target += normal_lpdf(y | __COMPUTATION_HERE__, sigma); 49 | ``` 50 | 51 | If stuck, see https://mc-stan.org/docs/stan-users-guide/regression.html 52 | 53 | For extra credit, you may try to figure out how to keep the distinct standard deviations following a similar computation. 54 | 55 | 56 | ## Task 3: Add a continuous predictor 57 | 58 | Add a new continuous predictor (a vector of real numbers) for each data point and add an extra coefficient (a new variable in the `parameters` block) to model its influence. 59 | 60 | Simulate data and check parameter recovery. 61 | 62 | ## Task 4: Matrix multiplication 63 | 64 | Make a copy of the model and convert it to matrix multiplication format. 65 | Make the number of columns in the design matrix variable. I.e. your `data` section should look something like: 66 | 67 | ``` 68 | data { 69 | int N; // number of data items 70 | int K; // number of predictors 71 | matrix[N, K] x; // predictor matrix 72 | vector[N] y; // outcome vector 73 | } 74 | ``` 75 | 76 | 77 | Test that with the same data, you get the same results as in the previous version (since Hamiltonian Monte Carlo is stochastic you won't get exactly the same results, but they should be numerically very close) 78 | 79 | ## Task 5: Compare to user's guide 80 | 81 | Compare what you've built with the example linear regression models in Stan's User's guide: 82 | https://mc-stan.org/docs/stan-users-guide/regression.html#linear-regression 83 | 84 | Generally, don't be afraid to use the User's guide as a starting point for your models, it is a great resource! 85 | 86 | ## Task 6: Dummy coding 87 | 88 | Use [dummy coding](https://stats.idre.ucla.edu/other/mult-pkg/faq/general/faqwhat-is-dummy-coding/) to extend the model to have 3 groups instead of 2 in the categorical predictor. 89 | Your Stan code should not need to change. 90 | 91 | Simulate data, fit, check parameter recovery. 92 | 93 | ## Task 7: Negative binomial regression 94 | 95 | Starting with the previous model, create a negative binomial regression model with a log link. 96 | 97 | Simulate data, fit, check parameter recovery (you can use a simpler set of predictors if you prefer). 98 | 99 | -------------------------------------------------------------------------------- /lesson3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 3" 3 | output: html_document 4 | --- 5 | 6 | ```{r setup} 7 | library(dplyr) 8 | library(magrittr) 9 | library(ggplot2) 10 | library(tidyr) 11 | theme_set(theme_minimal()) 12 | ``` 13 | 14 | 15 | 16 | ## First, let's slow down a bit 17 | 18 | Try to complete [Task 3 and 4](lesson3-tasks.html#task-3-detecting-overdispersion-with-a-posterior-predictive-check) from Lesson 2 (and possibly others from the previous lessons) 19 | 20 | Pick projects! 21 | 22 | ## Note on models 23 | 24 | - Reuse methodology slides: https://docs.google.com/presentation/d/1jkcKfTOupedZRoJZ9qSuGVDBjlzZFt6vOyEyN0pwduY/edit?usp=sharing 25 | 26 | ## Linear regression 27 | 28 | - The most ubiquitous type of model --- see e.g. https://lindeloev.github.io/tests-as-linear/ 29 | - Taylor series 30 | - Intercept, coefficients 31 | - [Dummy coding](https://stats.idre.ucla.edu/other/mult-pkg/faq/general/faqwhat-is-dummy-coding/) 32 | - There are other ways to code (e.g. [effect coding](https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faqwhat-is-effect-coding/)) 33 | - `model.matrix` in `R` does the coding for you 34 | - Linear predictors and matrix multiplication 35 | - Intercept in the matrix 36 | - [Least squares](https://en.wikipedia.org/wiki/Least_squares) and its relatio to normal distribution 37 | - Maximum likelihood estimator is equivalent to least-squares. 38 | - [Generalized linear models](https://en.wikipedia.org/wiki/Generalized_linear_model) (GLM) 39 | - Link function, inverse link function 40 | - Most common link functions: 41 | - log for positive outcomes (i.e. exponentiate the predictors), 42 | - logit (i.e. apply inverse logit to the predictor) for outcomes in [0, 1] - most notably for probabilities in logistic regression. 43 | - Posterior predictive checks as a method to determine which predictors to add 44 | 45 | Now, let's do some tasks. Note that they match workflow (simple stuff first, ...) 46 | -------------------------------------------------------------------------------- /lesson4-tasks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 4 - Tasks" 3 | output: html_document 4 | --- 5 | 6 | 7 | 8 | ## Task 1: Fixed to random effects 9 | 10 | Start with the code for [Lesson 3 - Task 6 (dummy coding)](https://martinmodrak.github.io/modelling-in-stan-2024/lesson3-tasks.html#task-6-dummy-coding) and/or the [regression code from Stan User's guide](https://mc-stan.org/docs/stan-users-guide/regression.html#linear-regression). 11 | 12 | Convert the 3 categorical groups into a random intercept model, i.e.: 13 | 14 | 1) Remove the categorical variable from the model matrix 15 | 2) Introduce new `data` elements for the model to represent the number of categories and the category each observation belongs to 16 | - Use `array[N] int ` as a type for the cateogry input 17 | - You may want to add `` bounds for the category input - what would that be? 18 | 3) Introduce new `parameter` elements: 19 | - A positive number for the random intercept standard deviation 20 | - A vector of the effects for each category (contrast with dummy coding, where you would have one fewer effects) 21 | 4) Add the categorical predictor to the result of the matrix multiplication for the linear predictor. 22 | - Note that in Stan, you can index a `vector` by an array to obtain a `vector` the same length as the array 23 | 5) Add a prior for the standard deviation and then put a `normal(0, ...)` prior on the category random intercepts 24 | 25 | How does the fit change from the fixed effect 26 | 27 | ## Task 2: Non-centered parametrization 28 | 29 | Convert the above model to non-centered parametrization, i.e.: 30 | 31 | 1) Put a `normal(0, 1)` prior on the random intercept vector 32 | 2) Multiply the raw parameters by the standard deviation in `transformed parameters` 33 | -------------------------------------------------------------------------------- /lesson4.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 4" 3 | output: html_document 4 | --- 5 | 6 | 7 | 8 | - Random effects 9 | - Population of effects 10 | - Shrinkage 11 | - Non-centered parametrization 12 | - `transformed parameters` block 13 | 14 | -------------------------------------------------------------------------------- /lesson5.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 5" 3 | output: html_document 4 | --- 5 | 6 | 7 | ## Brms internals 8 | 9 | Core brms abstraction: one row of data -> one target increment 10 | 11 | ```{r, include=FALSE} 12 | library(brms) 13 | df <- data.frame(y = rnorm(100), x = rnorm(100), g = sample(LETTERS[1:3], size = 100, replace = TRUE)) 14 | ``` 15 | 16 | ``` 17 | make_stancode(y ~ x, df) 18 | ``` 19 | 20 | ```{r, results = "asis", echo=FALSE} 21 | cat("```stan\n") 22 | cat(make_stancode(y ~ x, df)) 23 | cat("```") 24 | ``` 25 | 26 | ``` 27 | make_stancode(y ~ x + (1 | g), df) 28 | ``` 29 | 30 | ```{r, results = "asis", echo=FALSE} 31 | cat("```stan\n") 32 | cat(make_stancode(y ~ x + (1 | g), df)) 33 | cat("```") 34 | ``` 35 | 36 | ``` 37 | make_stancode(y ~ x + (1 | g), df) 38 | ``` 39 | 40 | ```{r, results = "asis", echo=FALSE} 41 | cat("```stan\n") 42 | cat(make_stancode(y ~ (1 + x | g), df)) 43 | cat("```") 44 | ``` 45 | 46 | 47 | Stanvars! 48 | 49 | ## Basics of numerical mathematics 50 | 51 | - [IEEE 754 Floating point](https://en.wikipedia.org/wiki/IEEE_754) 52 | - The worst possible way to represent reals (except all the others we tried) 53 | - Sign, exponent, Mantissa 54 | - Special values: +/-Inf, NaN 55 | - Signed zero 56 | $x = y \centernot\implies \frac{1}{x} = \frac{1}{y}$ 57 | - [Subnormal/Denormals](https://en.wikipedia.org/wiki/Subnormal_number) 58 | - The subnormal floats are a linearly spaced set of values, which span the gap between the negative and positive normal floats. 59 | - Small value + large value -> lost precision 60 | - Much more precision around 0 than around 1 61 | - Special functions 62 | - `log1p`, `log1p_exp`, `log_sum_exp`, `log_diff_exp` 63 | -------------------------------------------------------------------------------- /lesson6.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 6" 3 | output: html_document 4 | --- 5 | 6 | 7 | ## Ordinal models 8 | 9 | - Nice, thorough introduction: Bürkner & Vuorre 2019, https://doi.org/10.1177/2515245918823199 10 | - What are ordinal data 11 | - Cumulative model 12 | - In Stan: [`ordered_logistic`](https://mc-stan.org/docs/functions-reference/bounded_discrete_distributions.html#ordered-logistic-distribution) function, see also the [user's guide section](https://mc-stan.org/docs/stan-users-guide/regression.html#ordered-logistic.section) 13 | - Choice of link function 14 | - Continuation/stop models 15 | - Differences mainly theoretical 16 | 17 | 18 | -------------------------------------------------------------------------------- /modelling-in-stan-2024.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /renv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "R": { 3 | "Version": "4.3.2", 4 | "Repositories": [ 5 | { 6 | "Name": "Stan", 7 | "URL": "https://mc-stan.org/r-packages" 8 | }, 9 | { 10 | "Name": "CRAN", 11 | "URL": "https://cloud.r-project.org" 12 | } 13 | ] 14 | }, 15 | "Packages": { 16 | "KernSmooth": { 17 | "Package": "KernSmooth", 18 | "Version": "2.23-22", 19 | "Source": "Repository", 20 | "Repository": "CRAN", 21 | "Requirements": [ 22 | "R", 23 | "stats" 24 | ], 25 | "Hash": "2fecebc3047322fa5930f74fae5de70f" 26 | }, 27 | "MASS": { 28 | "Package": "MASS", 29 | "Version": "7.3-60", 30 | "Source": "Repository", 31 | "Repository": "CRAN", 32 | "Requirements": [ 33 | "R", 34 | "grDevices", 35 | "graphics", 36 | "methods", 37 | "stats", 38 | "utils" 39 | ], 40 | "Hash": "a56a6365b3fa73293ea8d084be0d9bb0" 41 | }, 42 | "Matrix": { 43 | "Package": "Matrix", 44 | "Version": "1.6-1.1", 45 | "Source": "Repository", 46 | "Repository": "CRAN", 47 | "Requirements": [ 48 | "R", 49 | "grDevices", 50 | "graphics", 51 | "grid", 52 | "lattice", 53 | "methods", 54 | "stats", 55 | "utils" 56 | ], 57 | "Hash": "1a00d4828f33a9d690806e98bd17150c" 58 | }, 59 | "R6": { 60 | "Package": "R6", 61 | "Version": "2.5.1", 62 | "Source": "Repository", 63 | "Repository": "CRAN", 64 | "Requirements": [ 65 | "R" 66 | ], 67 | "Hash": "470851b6d5d0ac559e9d01bb352b4021" 68 | }, 69 | "abind": { 70 | "Package": "abind", 71 | "Version": "1.4-5", 72 | "Source": "Repository", 73 | "Repository": "CRAN", 74 | "Requirements": [ 75 | "R", 76 | "methods", 77 | "utils" 78 | ], 79 | "Hash": "4f57884290cc75ab22f4af9e9d4ca862" 80 | }, 81 | "backports": { 82 | "Package": "backports", 83 | "Version": "1.4.1", 84 | "Source": "Repository", 85 | "Repository": "CRAN", 86 | "Requirements": [ 87 | "R" 88 | ], 89 | "Hash": "c39fbec8a30d23e721980b8afb31984c" 90 | }, 91 | "boot": { 92 | "Package": "boot", 93 | "Version": "1.3-28.1", 94 | "Source": "Repository", 95 | "Repository": "CRAN", 96 | "Requirements": [ 97 | "R", 98 | "graphics", 99 | "stats" 100 | ], 101 | "Hash": "9a052fbcbe97a98ceb18dbfd30ebd96e" 102 | }, 103 | "checkmate": { 104 | "Package": "checkmate", 105 | "Version": "2.3.1", 106 | "Source": "Repository", 107 | "Repository": "CRAN", 108 | "Requirements": [ 109 | "R", 110 | "backports", 111 | "utils" 112 | ], 113 | "Hash": "c01cab1cb0f9125211a6fc99d540e315" 114 | }, 115 | "class": { 116 | "Package": "class", 117 | "Version": "7.3-22", 118 | "Source": "Repository", 119 | "Repository": "CRAN", 120 | "Requirements": [ 121 | "MASS", 122 | "R", 123 | "stats", 124 | "utils" 125 | ], 126 | "Hash": "f91f6b29f38b8c280f2b9477787d4bb2" 127 | }, 128 | "cli": { 129 | "Package": "cli", 130 | "Version": "3.6.2", 131 | "Source": "Repository", 132 | "Repository": "CRAN", 133 | "Requirements": [ 134 | "R", 135 | "utils" 136 | ], 137 | "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" 138 | }, 139 | "cluster": { 140 | "Package": "cluster", 141 | "Version": "2.1.4", 142 | "Source": "Repository", 143 | "Repository": "CRAN", 144 | "Requirements": [ 145 | "R", 146 | "grDevices", 147 | "graphics", 148 | "stats", 149 | "utils" 150 | ], 151 | "Hash": "5edbbabab6ce0bf7900a74fd4358628e" 152 | }, 153 | "cmdstanr": { 154 | "Package": "cmdstanr", 155 | "Version": "0.7.1", 156 | "Source": "Repository", 157 | "Repository": "Stan", 158 | "Requirements": [ 159 | "R", 160 | "R6", 161 | "checkmate", 162 | "data.table", 163 | "jsonlite", 164 | "posterior", 165 | "processx", 166 | "rlang", 167 | "withr" 168 | ], 169 | "Hash": "7d975b08a9b0ff7bfb037c432a1ef0f8" 170 | }, 171 | "codetools": { 172 | "Package": "codetools", 173 | "Version": "0.2-19", 174 | "Source": "Repository", 175 | "Repository": "CRAN", 176 | "Requirements": [ 177 | "R" 178 | ], 179 | "Hash": "c089a619a7fae175d149d89164f8c7d8" 180 | }, 181 | "data.table": { 182 | "Package": "data.table", 183 | "Version": "1.15.0", 184 | "Source": "Repository", 185 | "Repository": "CRAN", 186 | "Requirements": [ 187 | "R", 188 | "methods" 189 | ], 190 | "Hash": "cfbbb4aed6e78cd45f17123a9ec9981a" 191 | }, 192 | "distributional": { 193 | "Package": "distributional", 194 | "Version": "0.4.0", 195 | "Source": "Repository", 196 | "Repository": "CRAN", 197 | "Requirements": [ 198 | "generics", 199 | "lifecycle", 200 | "numDeriv", 201 | "rlang", 202 | "stats", 203 | "utils", 204 | "vctrs" 205 | ], 206 | "Hash": "3bad76869f2257ea4fd00a3c08c2bcce" 207 | }, 208 | "fansi": { 209 | "Package": "fansi", 210 | "Version": "1.0.6", 211 | "Source": "Repository", 212 | "Repository": "CRAN", 213 | "Requirements": [ 214 | "R", 215 | "grDevices", 216 | "utils" 217 | ], 218 | "Hash": "962174cf2aeb5b9eea581522286a911f" 219 | }, 220 | "foreign": { 221 | "Package": "foreign", 222 | "Version": "0.8-85", 223 | "Source": "Repository", 224 | "Repository": "CRAN", 225 | "Requirements": [ 226 | "R", 227 | "methods", 228 | "stats", 229 | "utils" 230 | ], 231 | "Hash": "26a24dde1722321b78f10d3bf42538d6" 232 | }, 233 | "generics": { 234 | "Package": "generics", 235 | "Version": "0.1.3", 236 | "Source": "Repository", 237 | "Repository": "CRAN", 238 | "Requirements": [ 239 | "R", 240 | "methods" 241 | ], 242 | "Hash": "15e9634c0fcd294799e9b2e929ed1b86" 243 | }, 244 | "glue": { 245 | "Package": "glue", 246 | "Version": "1.7.0", 247 | "Source": "Repository", 248 | "Repository": "CRAN", 249 | "Requirements": [ 250 | "R", 251 | "methods" 252 | ], 253 | "Hash": "e0b3a53876554bd45879e596cdb10a52" 254 | }, 255 | "jsonlite": { 256 | "Package": "jsonlite", 257 | "Version": "1.8.8", 258 | "Source": "Repository", 259 | "Repository": "CRAN", 260 | "Requirements": [ 261 | "methods" 262 | ], 263 | "Hash": "e1b9c55281c5adc4dd113652d9e26768" 264 | }, 265 | "lattice": { 266 | "Package": "lattice", 267 | "Version": "0.21-9", 268 | "Source": "Repository", 269 | "Repository": "CRAN", 270 | "Requirements": [ 271 | "R", 272 | "grDevices", 273 | "graphics", 274 | "grid", 275 | "stats", 276 | "utils" 277 | ], 278 | "Hash": "5558c61e0136e247252f5f952cdaad6a" 279 | }, 280 | "lifecycle": { 281 | "Package": "lifecycle", 282 | "Version": "1.0.4", 283 | "Source": "Repository", 284 | "Repository": "CRAN", 285 | "Requirements": [ 286 | "R", 287 | "cli", 288 | "glue", 289 | "rlang" 290 | ], 291 | "Hash": "b8552d117e1b808b09a832f589b79035" 292 | }, 293 | "magrittr": { 294 | "Package": "magrittr", 295 | "Version": "2.0.3", 296 | "Source": "Repository", 297 | "Repository": "CRAN", 298 | "Requirements": [ 299 | "R" 300 | ], 301 | "Hash": "7ce2733a9826b3aeb1775d56fd305472" 302 | }, 303 | "matrixStats": { 304 | "Package": "matrixStats", 305 | "Version": "1.2.0", 306 | "Source": "Repository", 307 | "Repository": "CRAN", 308 | "Requirements": [ 309 | "R" 310 | ], 311 | "Hash": "33a3ca9e732b57244d14f5d732ffc9eb" 312 | }, 313 | "mgcv": { 314 | "Package": "mgcv", 315 | "Version": "1.9-0", 316 | "Source": "Repository", 317 | "Repository": "CRAN", 318 | "Requirements": [ 319 | "Matrix", 320 | "R", 321 | "graphics", 322 | "methods", 323 | "nlme", 324 | "splines", 325 | "stats", 326 | "utils" 327 | ], 328 | "Hash": "086028ca0460d0c368028d3bda58f31b" 329 | }, 330 | "nlme": { 331 | "Package": "nlme", 332 | "Version": "3.1-163", 333 | "Source": "Repository", 334 | "Repository": "CRAN", 335 | "Requirements": [ 336 | "R", 337 | "graphics", 338 | "lattice", 339 | "stats", 340 | "utils" 341 | ], 342 | "Hash": "8d1938040a05566f4f7a14af4feadd6b" 343 | }, 344 | "nnet": { 345 | "Package": "nnet", 346 | "Version": "7.3-19", 347 | "Source": "Repository", 348 | "Repository": "CRAN", 349 | "Requirements": [ 350 | "R", 351 | "stats", 352 | "utils" 353 | ], 354 | "Hash": "2c797b46eea7fb58ede195bc0b1f1138" 355 | }, 356 | "numDeriv": { 357 | "Package": "numDeriv", 358 | "Version": "2016.8-1.1", 359 | "Source": "Repository", 360 | "Repository": "CRAN", 361 | "Requirements": [ 362 | "R" 363 | ], 364 | "Hash": "df58958f293b166e4ab885ebcad90e02" 365 | }, 366 | "pillar": { 367 | "Package": "pillar", 368 | "Version": "1.9.0", 369 | "Source": "Repository", 370 | "Repository": "CRAN", 371 | "Requirements": [ 372 | "cli", 373 | "fansi", 374 | "glue", 375 | "lifecycle", 376 | "rlang", 377 | "utf8", 378 | "utils", 379 | "vctrs" 380 | ], 381 | "Hash": "15da5a8412f317beeee6175fbc76f4bb" 382 | }, 383 | "pkgconfig": { 384 | "Package": "pkgconfig", 385 | "Version": "2.0.3", 386 | "Source": "Repository", 387 | "Repository": "CRAN", 388 | "Requirements": [ 389 | "utils" 390 | ], 391 | "Hash": "01f28d4278f15c76cddbea05899c5d6f" 392 | }, 393 | "posterior": { 394 | "Package": "posterior", 395 | "Version": "1.5.0", 396 | "Source": "Repository", 397 | "Repository": "CRAN", 398 | "Requirements": [ 399 | "R", 400 | "abind", 401 | "checkmate", 402 | "distributional", 403 | "matrixStats", 404 | "methods", 405 | "parallel", 406 | "pillar", 407 | "rlang", 408 | "stats", 409 | "tensorA", 410 | "tibble", 411 | "vctrs" 412 | ], 413 | "Hash": "8dac526a34b9eb62305d16c04cb57837" 414 | }, 415 | "processx": { 416 | "Package": "processx", 417 | "Version": "3.8.3", 418 | "Source": "Repository", 419 | "Repository": "CRAN", 420 | "Requirements": [ 421 | "R", 422 | "R6", 423 | "ps", 424 | "utils" 425 | ], 426 | "Hash": "82d48b1aec56084d9438dbf98087a7e9" 427 | }, 428 | "ps": { 429 | "Package": "ps", 430 | "Version": "1.7.6", 431 | "Source": "Repository", 432 | "Repository": "CRAN", 433 | "Requirements": [ 434 | "R", 435 | "utils" 436 | ], 437 | "Hash": "dd2b9319ee0656c8acf45c7f40c59de7" 438 | }, 439 | "renv": { 440 | "Package": "renv", 441 | "Version": "1.0.3", 442 | "Source": "Repository", 443 | "Repository": "CRAN", 444 | "Requirements": [ 445 | "utils" 446 | ], 447 | "Hash": "41b847654f567341725473431dd0d5ab" 448 | }, 449 | "rlang": { 450 | "Package": "rlang", 451 | "Version": "1.1.3", 452 | "Source": "Repository", 453 | "Repository": "CRAN", 454 | "Requirements": [ 455 | "R", 456 | "utils" 457 | ], 458 | "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" 459 | }, 460 | "rpart": { 461 | "Package": "rpart", 462 | "Version": "4.1.21", 463 | "Source": "Repository", 464 | "Repository": "CRAN", 465 | "Requirements": [ 466 | "R", 467 | "grDevices", 468 | "graphics", 469 | "stats" 470 | ], 471 | "Hash": "d5bc1a16e01e50e08581f0c362d3955d" 472 | }, 473 | "spatial": { 474 | "Package": "spatial", 475 | "Version": "7.3-17", 476 | "Source": "Repository", 477 | "Repository": "CRAN", 478 | "Requirements": [ 479 | "R", 480 | "graphics", 481 | "stats", 482 | "utils" 483 | ], 484 | "Hash": "1229a01b4ec059e9f2396724f2ec9010" 485 | }, 486 | "survival": { 487 | "Package": "survival", 488 | "Version": "3.5-7", 489 | "Source": "Repository", 490 | "Repository": "CRAN", 491 | "Requirements": [ 492 | "Matrix", 493 | "R", 494 | "graphics", 495 | "methods", 496 | "splines", 497 | "stats", 498 | "utils" 499 | ], 500 | "Hash": "b8e943d262c3da0b0febd3e04517c197" 501 | }, 502 | "tensorA": { 503 | "Package": "tensorA", 504 | "Version": "0.36.2.1", 505 | "Source": "Repository", 506 | "Repository": "CRAN", 507 | "Requirements": [ 508 | "R", 509 | "stats" 510 | ], 511 | "Hash": "0d587599172f2ffda2c09cb6b854e0e5" 512 | }, 513 | "tibble": { 514 | "Package": "tibble", 515 | "Version": "3.2.1", 516 | "Source": "Repository", 517 | "Repository": "CRAN", 518 | "Requirements": [ 519 | "R", 520 | "fansi", 521 | "lifecycle", 522 | "magrittr", 523 | "methods", 524 | "pillar", 525 | "pkgconfig", 526 | "rlang", 527 | "utils", 528 | "vctrs" 529 | ], 530 | "Hash": "a84e2cc86d07289b3b6f5069df7a004c" 531 | }, 532 | "utf8": { 533 | "Package": "utf8", 534 | "Version": "1.2.4", 535 | "Source": "Repository", 536 | "Repository": "CRAN", 537 | "Requirements": [ 538 | "R" 539 | ], 540 | "Hash": "62b65c52671e6665f803ff02954446e9" 541 | }, 542 | "vctrs": { 543 | "Package": "vctrs", 544 | "Version": "0.6.5", 545 | "Source": "Repository", 546 | "Repository": "CRAN", 547 | "Requirements": [ 548 | "R", 549 | "cli", 550 | "glue", 551 | "lifecycle", 552 | "rlang" 553 | ], 554 | "Hash": "c03fa420630029418f7e6da3667aac4a" 555 | }, 556 | "withr": { 557 | "Package": "withr", 558 | "Version": "3.0.0", 559 | "Source": "Repository", 560 | "Repository": "CRAN", 561 | "Requirements": [ 562 | "R", 563 | "grDevices", 564 | "graphics" 565 | ], 566 | "Hash": "d31b6c62c10dcf11ec530ca6b0dd5d35" 567 | } 568 | } 569 | } 570 | -------------------------------------------------------------------------------- /renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "all", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /solutions/lesson1-solutions.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 1 - solutions" 3 | output: html_notebook 4 | --- 5 | 6 | ```{r} 7 | library(cmdstanr) 8 | options(mc.cores = 4) 9 | ``` 10 | 11 | 12 | ## Task 1 13 | 14 | ```{r} 15 | m_initial <- cmdstan_model("../stan/lesson1/initial.stan") 16 | ``` 17 | 18 | 19 | ```{r} 20 | N <- 5 21 | mu <- rnorm(1, mean = 0, sd = 1) 22 | y <- rnorm(N, mean = mu, sd = 1) 23 | 24 | res <- m_initial$sample(list(N = N, y = y)) 25 | res$summary() 26 | ``` 27 | 28 | ```{r} 29 | m_with_sigma_prior <- cmdstan_model("../stan/lesson1/with_sigma_prior.stan") 30 | ``` 31 | 32 | ```{r} 33 | 34 | N <- 1 35 | sigma <- abs(rnorm(1, mean =0, sd = 2)) 36 | mu <- rnorm(1, mean = 0, sd = 1) 37 | y <- rnorm(N, mean = mu, sd = 1) 38 | 39 | 40 | res <- m_with_sigma_prior$sample(list(N = N, y = y, mu_prior_mean = 0, sigma_prior_sd = 2, mu_prior_sd = 1)) 41 | res$summary() 42 | ``` 43 | 44 | ```{r} 45 | library(posterior) 46 | 47 | bayesplot::mcmc_pairs(res$draws(), transformations = list("sigma" = log)) 48 | 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /solutions/lesson2-solutions.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lesson 1 - solutions" 3 | output: html_notebook 4 | --- 5 | 6 | ```{r} 7 | library(cmdstanr) 8 | library(bayesplot) 9 | options(mc.cores = 4) 10 | ``` 11 | 12 | 13 | ## Task 1 14 | 15 | ```{r} 16 | hist(rpois(1000, rlnorm(1000, 0, 10))) 17 | ``` 18 | 19 | 20 | ```{r} 21 | N <- 1e5 22 | sim_data <- rpois(N, rlnorm(N, log(9), log(1.1))) 23 | hist(sim_data, breaks = 0:30) 24 | mean(sim_data >= 2 & sim_data <= 15) 25 | mean(sim_data == 0) 26 | mean(sim_data > 18) 27 | ``` 28 | 29 | # Task 4 30 | 31 | ```{r} 32 | m_negbin <- cmdstan_model("../stan/lesson2/neg_binom.stan") 33 | ``` 34 | 35 | ```{r} 36 | set.seed(456825) 37 | N <- 80 38 | group <- rep(c("A", "B"), length.out = N) 39 | type <- rep(c("X", "X", "Y", "Y"), length.out = N) 40 | y <- rnbinom(N, mu = if_else(type == "X", 5, 20) , size = 2) 41 | fit <- m_negbin$sample(data = list(N = length(y), y = y)) 42 | 43 | ``` 44 | 45 | ```{r} 46 | cat("y : ", paste0(y, collapse = ", "), "\n") 47 | cat("group : ", paste0('"', group,'"', collapse = ", "), "\n") 48 | cat("type : ", paste0('"', type,'"', collapse = ", "), "\n") 49 | ``` 50 | 51 | 52 | ```{r} 53 | dd <- fit$draws(format = "draws_matrix") 54 | ypred <- matrix(nrow = nrow(dd), ncol = N) 55 | for(i in 1:N) { 56 | ypred[,i] <- rnbinom(nrow(dd), mu = exp(dd[,"log_mu"]), size = dd[,"phi"]) 57 | } 58 | 59 | ppc_stat(y, ypred, group = type, stat = "sd") 60 | ppc_stat_grouped(y, ypred, group = type, stat = "mean") 61 | 62 | ``` 63 | 64 | 65 | 66 | # Task 5 67 | 68 | ```{r} 69 | N <- 50 70 | prob <- 0.9 71 | y <- rbinom(N, size = 1, prob = prob) 72 | 73 | fit_bern <- m_negbin$sample(data = list(N = N, y = y)) 74 | ``` 75 | 76 | ```{r} 77 | dd <- fit_bern$draws(format = "draws_matrix") 78 | ypred <- matrix(nrow = nrow(dd), ncol = N) 79 | for(i in 1:N) { 80 | ypred[,i] <- rnbinom(nrow(dd), mu = exp(dd[,"log_mu"]), size = dd[,"phi"]) 81 | } 82 | 83 | 84 | ppc_dens_overlay(y, ypred[1:50,]) 85 | ``` 86 | 87 | ```{r} 88 | cat("y : ", paste0(y, collapse = ", "), "\n") 89 | cat("group : ", paste0('"', sample(LETTERS[1:4], size = N, replace = TRUE),'"', collapse = ", "), "\n") 90 | ``` 91 | 92 | -------------------------------------------------------------------------------- /stan/lesson1/initial.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | vector[N] y; 4 | } 5 | 6 | parameters { 7 | real mu; 8 | } 9 | 10 | model { 11 | // likelihood 12 | target += normal_lpdf(y | mu, 1); 13 | // prior 14 | target += normal_lpdf(mu | 0, 1); 15 | } 16 | -------------------------------------------------------------------------------- /stan/lesson1/with_sigma_prior.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | vector[N] y; 4 | real sigma_prior_sd; 5 | real mu_prior_mean; 6 | real mu_prior_sd; 7 | } 8 | 9 | parameters { 10 | real mu; 11 | real sigma; 12 | } 13 | 14 | model { 15 | // likelihood 16 | target += normal_lpdf(y | mu, sigma); 17 | // prior 18 | target += normal_lpdf(mu | mu_prior_mean, mu_prior_sd); 19 | target += normal_lpdf(sigma | 0, sigma_prior_sd); 20 | } 21 | -------------------------------------------------------------------------------- /stan/lesson2/neg_binom.stan: -------------------------------------------------------------------------------- 1 | data { 2 | int N; 3 | array[N] int y; 4 | } 5 | 6 | parameters { 7 | real log_mu; 8 | real phi; 9 | } 10 | 11 | model { 12 | // likelihood 13 | target += neg_binomial_2_log_lpmf(y | log_mu, phi); 14 | // prior 15 | target += normal_lpdf(log_mu | 2, 1); 16 | target += exponential_lpdf(phi | 1); 17 | } 18 | --------------------------------------------------------------------------------