Skip to content

Commit

Permalink
make release
Browse files Browse the repository at this point in the history
  • Loading branch information
DominiqueMakowski committed Jul 8, 2024
1 parent 0e99da0 commit 027fccd
Show file tree
Hide file tree
Showing 37 changed files with 1,221 additions and 422 deletions.
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Cognitive Models <img src='content/media/cover.png' align="right" height="300" />
# Cognitive Models <a href="https://dominiquemakowski.github.io/CognitiveModels/"><img src='content/media/cover.png' align="right" height="300" /></a>

*Computational Modeling of Cognitive Processes with Bayesian Mixed Models in Julia*

[![](https://img.shields.io/badge/status-looking_for_collaborators-orange)](https://github.com/DominiqueMakowski/CognitiveModels/issues)
[![](https://img.shields.io/badge/access-open-green)](https://dominiquemakowski.github.io/CognitiveModels/)
[![](https://img.shields.io/badge/access-open-brightgreen)](https://dominiquemakowski.github.io/CognitiveModels/)

The project is to write an open-access book on **cognitive models**, i.e., statistical models that best fit **psychological data** (e.g., reaction times, scales from surveys, ...).
This framework aims at moving away from a mere description of the data, to make inferences about the underlying cognitive processes that led to its generation.
Expand All @@ -18,20 +18,10 @@ Importantly, it is currently the only language in which we can fit all the cogni
Unfortunately, cognitive models often involve distributions for which Frequentist estimations are not yet implemented, and usually contain a lot of parameters (due to the presence of **random effects**), which makes traditional algorithms fail to converge.
Simply put, the Bayesian approach is the only one currently robust enough to fit these complex models.

## The Plan

As this is a fast-evolving field (both from the theoretical - with new models being proposed - and the technical side - with improvements to the packages and the algorithms), the book needs to be future-resilient and updatable to keep up with the latest best practices.

- [ ] Decide on the framework to build the book in a reproducible and collaborative manner (Quarto?)
- [ ] Set up the infrastructure to automatically build it using GitHub actions and host it on GitHub pages
- [ ] Write the content of the book
- [ ] Referencing
- Add Zenodo DOI and reference (but how to deal with evolving author? Through versioning?)
- Publish a paper to present the book project ([JOSE](https://jose.theoj.org/))?


## Looking for Coauthors

As this is a fast-evolving field (both from the theoretical - with new models being proposed - and the technical side - with improvements to the packages and the algorithms), the book needs to be future-resilient and updatable by contributors to keep up with the latest best practices.

This project can only be achieved by a team, and I suspect no single person has currently all the skills and knowledge to cover all the content. We need many people who have strengths in various aspects, such as Julia/Turing, theory, writing, making plots etc.
Most importantly, this project can serve as a way for us to learn more about this approach to psychological science.

Expand All @@ -40,3 +30,11 @@ Most importantly, this project can serve as a way for us to learn more about thi
## Content

See current WIP [**table of content**](https://dominiquemakowski.github.io/CognitiveModels/).

- Fundamentals of Bayesian Modeling in Julia
- On Predictors
- Choices and Scales
- Reaction Times
- [**Descriptive Models**](https://dominiquemakowski.github.io/CognitiveModels/4a_rt_descriptive.html)
- [**Generative Models**](https://dominiquemakowski.github.io/CognitiveModels/4b_rt_generative_.html)
- Individual Differences

Large diffs are not rendered by default.

Binary file modified content/.jupyter_cache/global.db
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"hash": "f1b09c48ebcc0d8b9c817ca76b3d37bf",
"hash": "13a6386ee9710a33c192a1e02a587307",
"result": {
"engine": "jupyter",
"markdown": "# Fundamentals of Bayesian Modeling in Julia\n\n![](https://img.shields.io/badge/status-not_started-red)\n\n\n## Very quick intro to Julia and Turing\n\nGoal is to teach just enough so that the reader understands the code.\n\n::: {.callout-important}\n\n### Notable Differences with Python and R\n\nThese are the most common sources of confusion and errors for newcomers to Julia:\n\n- **1-indexing**: Similarly to R, Julia uses 1-based indexing, which means that the first element of a vector is `x[1]` (not `x[0]` as in Python).\n- **Positional; Keyword arguments**: Julia functions makes a clear distinction between positional and keyword arguments, and both are often separated by `;`. Positional arguments are typically passed without a name, while keyword arguments must be named (e.g., `scatter(0, 0; color=:red)`). Some functions might look like `somefunction(; arg1=val1, arg2=val2)`.\n- **Symbols**: Some arguments are prefixed with `:` (e.g., `:red` in `scatter(0, 0; color=:red)`). These **symbols** are like character strings that are not manipulable (there are more efficient).\n- **Explicit vectorization**: Julia does not vectorize operations by default. You need to use a dot `.` in front of functions and operators to have it apply element by element. For example, `sin.([0, 1, 2])` will apply the `sin()` function to each element of its vector.\n- **In-place operations**: Julia has a strong emphasis on performance, and in-place operations are often used to avoid unnecessary memory allocations. When functions modify their input \"in-place\" (without returns), a band `!` is used. For example, assuming `x = [0]` (1-element vector containing 0), `push!(x, 2)` will modify `x` in place (it is equivalent to `x = push(x, 2)`).\n:::\n\n\n### Generate Data from Normal Distribution\n\n::: {#0c15ea13 .cell execution_count=1}\n``` {.julia .cell-code}\nusing Turing, Distributions, Random\nusing Makie\n\n# Random sample from a Normal(μ=100, σ=15)\niq = rand(Normal(100, 15), 500)\n```\n:::\n\n\n::: {#6de958d5 .cell execution_count=2}\n``` {.julia .cell-code}\nfig = Figure()\nax = Axis(fig[1, 1], title=\"Distribution\")\ndensity!(ax, iq)\nfig\n```\n\n::: {.cell-output .cell-output-stderr}\n```\n┌ Warning: Found `resolution` in the theme when creating a `Scene`. The `resolution` keyword for `Scene`s and `Figure`s has been deprecated. Use `Figure(; size = ...` or `Scene(; size = ...)` instead, which better reflects that this is a unitless size and not a pixel resolution. The key could also come from `set_theme!` calls or related theming functions.\n└ @ Makie C:\\Users\\domma\\.julia\\packages\\Makie\\VRavR\\src\\scenes.jl:220\n```\n:::\n\n::: {.cell-output .cell-output-display execution_count=3}\n![](1_introduction_files/figure-html/cell-3-output-2.svg){}\n:::\n:::\n\n\n### Recover Distribution Parameters with Turing\n\n::: {#76fbbced .cell execution_count=3}\n``` {.julia .cell-code}\n@model function model_gaussian(x)\n # Priors\n μ ~ Uniform(0, 200)\n σ ~ Uniform(0, 30)\n\n # Check against each datapoint\n for i in 1:length(x)\n x[i] ~ Normal(μ, σ)\n end\nend\n\nmodel = model_gaussian(iq)\nsampling_results = sample(model, NUTS(), 400)\n\n# Summary (95% CI)\nsummarystats(sampling_results)\n```\n\n::: {.cell-output .cell-output-stderr}\n```\n┌ Info: Found initial step size\n└ ϵ = 0.05\n\rSampling: 0%|█ | ETA: 0:00:32\rSampling: 100%|█████████████████████████████████████████| Time: 0:00:01\n```\n:::\n\n::: {.cell-output .cell-output-display execution_count=4}\n\n::: {.ansi-escaped-output}\n```{=html}\n<pre>Summary Statistics\n <span class=\"ansi-bold\"> parameters </span> <span class=\"ansi-bold\"> mean </span> <span class=\"ansi-bold\"> std </span> <span class=\"ansi-bold\"> mcse </span> <span class=\"ansi-bold\"> ess_bulk </span> <span class=\"ansi-bold\"> ess_tail </span> <span class=\"ansi-bold\"> rhat </span> <span class=\"ansi-bold\"> </span> ⋯\n <span class=\"ansi-bright-black-fg\"> Symbol </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> </span> ⋯\n μ 101.0966 0.6163 0.0285 464.5397 331.0063 1.0010 ⋯\n σ 14.5905 0.4758 0.0221 504.1965 231.1654 1.0362 ⋯\n<span class=\"ansi-cyan-fg\"> 1 column omitted</span>\n</pre>\n```\n:::\n\n:::\n:::\n\n\n## Linear Models\n\nUnderstand what the parameters mean (intercept, slopes, sigma).\n\n## Boostrapping\n\nIntroduce concepts related to pseudo-posterior distribution description\n\n## Hierarchical Models\n\nSimpson's paradox, random effects, how to leverage them to model interindividual differences\n\n## Bayesian estimation\n\nintroduce Bayesian estimation and priors over parameters\n\n## Bayesian mixed linear regression\n\nput everything together\n\n",
"markdown": "# Fundamentals of Bayesian Modeling in Julia\n\n![](https://img.shields.io/badge/status-not_started-red)\n\n\n## Brief Intro to Julia and Turing\n\nGoal is to teach just enough so that the reader understands the code. \nWe won't be discussing things like plotting (as it highly depends on the package used).\n\n### Installing Julia and Packages\n\nTODO.\n\n\n### Julia Basics\n\n::: {.callout-important}\n\n### Notable Differences with Python and R\n\nThese are the most common sources of confusion and errors for newcomers to Julia:\n\n- **1-indexing**: Similarly to R, Julia uses 1-based indexing, which means that the first element of a vector is `x[1]` (not `x[0]` as in Python).\n- **Positional; Keyword arguments**: Julia functions makes a clear distinction between positional and keyword arguments, and both are often separated by `;`. Positional arguments are typically passed without a name, while keyword arguments must be named (e.g., `scatter(0, 0; color=:red)`). Some functions might look like `somefunction(; arg1=val1, arg2=val2)`.\n- **Symbols**: Some arguments are prefixed with `:` (e.g., `:red` in `scatter(0, 0; color=:red)`). These *symbols* are like character strings that are not manipulable (there are more efficient).\n- **Explicit vectorization**: Julia does not vectorize operations by default. You need to use a dot `.` in front of functions and operators to have it apply element by element. For example, `sin.([0, 1, 2])` will apply the `sin()` function to each element of its vector.\n- **In-place operations**: Julia has a strong emphasis on performance, and in-place operations are often used to avoid unnecessary memory allocations. When functions modify their input \"in-place\" (without returns), a band `!` is used. For example, assuming `x = [0]` (1-element vector containing 0), `push!(x, 2)` will modify `x` in place (it is equivalent to `x = push(x, 2)`).\n- **Macros**: Some functions start with `@`. These are called macros and are used to manipulate the code before it is run. For example, `@time` will measure the time it takes to run the code that follows.\n- **Unicode**: Julia is a modern language to supports unicode characters, which are used a lot for mathematical operations. You can get the *mu* `μ` character by typing `\\mu` and pressing `TAB`.\n:::\n\n\n### Generate Data from Normal Distribution\n\n::: {#1f15e3d4 .cell execution_count=1}\n``` {.julia .cell-code code-fold=\"false\"}\nusing Turing, Distributions, Random\nusing Makie\n\n# Random sample from a Normal(μ=100, σ=15)\niq = rand(Normal(100, 15), 500)\n```\n:::\n\n\n::: {#e3dbae1f .cell execution_count=2}\n``` {.julia .cell-code}\nfig = Figure()\nax = Axis(fig[1, 1], title=\"Distribution\")\ndensity!(ax, iq)\nfig\n```\n\n::: {.cell-output .cell-output-stderr}\n```\n┌ Warning: Found `resolution` in the theme when creating a `Scene`. The `resolution` keyword for `Scene`s and `Figure`s has been deprecated. Use `Figure(; size = ...` or `Scene(; size = ...)` instead, which better reflects that this is a unitless size and not a pixel resolution. The key could also come from `set_theme!` calls or related theming functions.\n└ @ Makie C:\\Users\\domma\\.julia\\packages\\Makie\\VRavR\\src\\scenes.jl:220\n```\n:::\n\n::: {.cell-output .cell-output-display execution_count=3}\n![](1_introduction_files/figure-html/cell-3-output-2.svg){}\n:::\n:::\n\n\n### Recover Distribution Parameters with Turing\n\n::: {#e37369d6 .cell execution_count=3}\n``` {.julia .cell-code code-fold=\"false\"}\n@model function model_gaussian(x)\n # Priors\n μ ~ Uniform(0, 200)\n σ ~ Uniform(0, 30)\n\n # Check against each datapoint\n for i in 1:length(x)\n x[i] ~ Normal(μ, σ)\n end\nend\n\nfit_gaussian = model_gaussian(iq)\nchain_gaussian = sample(fit_gaussian, NUTS(), 400)\n```\n:::\n\n\nInspecting the chain variable will show various posterior statistics (including the mean, standard deviation, and diagnostic indices).\n\n::: {#31ba55af .cell execution_count=4}\n``` {.julia .cell-code code-fold=\"false\"}\nchain_gaussian\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n\n::: {.ansi-escaped-output}\n```{=html}\n<pre>Chains MCMC chain (400×14×1 Array{Float64, 3}):\nIterations = 201:1:600\nNumber of chains = 1\nSamples per chain = 400\nWall duration = 8.8 seconds\nCompute duration = 8.8 seconds\nparameters = μ, σ\ninternals = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size\nSummary Statistics\n <span class=\"ansi-bold\"> parameters </span> <span class=\"ansi-bold\"> mean </span> <span class=\"ansi-bold\"> std </span> <span class=\"ansi-bold\"> mcse </span> <span class=\"ansi-bold\"> ess_bulk </span> <span class=\"ansi-bold\"> ess_tail </span> <span class=\"ansi-bold\"> rhat </span> <span class=\"ansi-bold\"> e</span> ⋯\n <span class=\"ansi-bright-black-fg\"> Symbol </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> </span> ⋯\n μ 99.2403 0.6727 0.0333 414.3604 324.9996 0.9993 ⋯\n σ 14.4973 0.4440 0.0187 561.5709 284.5407 0.9976 ⋯\n<span class=\"ansi-cyan-fg\"> 1 column omitted</span>\nQuantiles\n <span class=\"ansi-bold\"> parameters </span> <span class=\"ansi-bold\"> 2.5% </span> <span class=\"ansi-bold\"> 25.0% </span> <span class=\"ansi-bold\"> 50.0% </span> <span class=\"ansi-bold\"> 75.0% </span> <span class=\"ansi-bold\"> 97.5% </span>\n <span class=\"ansi-bright-black-fg\"> Symbol </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span>\n μ 97.9096 98.7663 99.2552 99.7769 100.4228\n σ 13.6853 14.1811 14.5066 14.7917 15.3761\n</pre>\n```\n:::\n\n:::\n:::\n\n\nFor the purpose of this book, we will mostly focus on the 95% Credible Interval (CI), and we will assume that a parameter is ***\"significant\"*** if its CI does not include 0.\n\n::: {#45fb1631 .cell execution_count=5}\n``` {.julia .cell-code code-fold=\"false\"}\n# Summary (95% CI)\nhpd(chain_gaussian)\n```\n\n::: {.cell-output .cell-output-display execution_count=6}\n\n::: {.ansi-escaped-output}\n```{=html}\n<pre>HPD\n <span class=\"ansi-bold\"> parameters </span> <span class=\"ansi-bold\"> lower </span> <span class=\"ansi-bold\"> upper </span>\n <span class=\"ansi-bright-black-fg\"> Symbol </span> <span class=\"ansi-bright-black-fg\"> Float64 </span> <span class=\"ansi-bright-black-fg\"> Float64 </span>\n μ 97.8594 100.3178\n σ 13.5687 15.2885\n</pre>\n```\n:::\n\n:::\n:::\n\n\n## Linear Models\n\nUnderstand what the parameters mean (intercept, slopes, sigma).\n\n## Boostrapping\n\nIntroduce concepts related to pseudo-posterior distribution description\n\n## Hierarchical Models\n\nSimpson's paradox, random effects, how to leverage them to model interindividual differences\n\n## Bayesian estimation\n\nintroduce Bayesian estimation and priors over parameters\n\n## Bayesian mixed linear regression\n\nput everything together\n\n",
"supporting": [
"1_introduction_files\\figure-html"
],
Expand Down
Loading

0 comments on commit 027fccd

Please sign in to comment.