0Pricing
R Academy · Leçon

Écrire des modèles Stan dans R

Définissez les blocs de données, les paramètres et le bloc de modèle dans la syntaxe Stan.

Écrire des modèles Stan dans R est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.

Qu'est-ce que Stan ?

Stan est un langage de programmation probabiliste destiné à la modélisation statistique bayésienne. RStan est l'interface R de Stan. Vous écrivez le modèle dans le langage de Stan (proche de C++), puis Stan le compile en code C++ efficace qui exécute un échantillonnage Monte-Carlo hamiltonien (HMC) afin d'approximer la loi a posteriori.

# Stan installation check
library(rstan)

# Check version
cat('RStan version:', as.character(packageVersion('rstan')), '\n')

# Enable parallel chains
options(mc.cores = parallel::detectCores())

# Reuse compiled models across sessions
rstan_options(auto_write = TRUE)

cat('Stan ready. Cores:', parallel::detectCores(), '\n')

Structure d'un modèle Stan

Un modèle Stan peut comporter jusqu'à six blocs nommés : data, transformed data, parameters, transformed parameters, model et generated quantities. Les trois blocs essentiels sont data, parameters et model.

library(rstan)

# Stan model as a character string in R
stan_code <- '
data {
  int<lower=0> N;       // number of observations
  vector[N] x;          // predictor
  vector[N] y;          // response
}
parameters {
  real alpha;           // intercept
  real beta;            // slope
  real<lower=0> sigma;  // noise (must be positive)
}
model {
  // Priors
  alpha ~ normal(0, 10);
  beta  ~ normal(0, 10);
  sigma ~ exponential(1);

  // Likelihood
  y ~ normal(alpha + beta * x, sigma);
}
'

cat('Stan model defined as a string in R\n')
cat('Blocks: data, parameters, model\n')

data{} : déclarer les données d'entrée

Le bloc data déclare toutes les données externes que le modèle reçoit de R. Les types comprennent int, real, vector[N], matrix[M,N] et array. Les contraintes telles que <lower=0> sont vérifiées lors de l'exécution.

library(rstan)

# Comprehensive data block examples
data_block_examples <- '
data {
  // Scalars
  int<lower=1> N;               // at least 1 observation
  int<lower=2> K;               // at least 2 groups

  // Constrained scalars
  real<lower=0, upper=1> rate;  // probability

  // Vectors
  vector[N] y;                  // continuous response
  array[N] int<lower=0, upper=1> z;  // binary outcomes

  // Matrix
  matrix[N, K] X;               // design matrix

  // Integer array
  array[N] int group;           // group membership 1..K
}
'

cat(data_block_examples)

paramètres{} : Types de paramètres

Le bloc parameters déclare les inconnues que Stan échantillonne. Les contraintes de ce bloc définissent l’espace des paramètres : <lower=0> pour les quantités positives, <lower=0, upper=1> pour les probabilités. Stan applique automatiquement les corrections jacobiennes de la log-probabilité pour les paramètres contraints.

library(rstan)

# Common parameter declarations
param_examples <- '
parameters {
  // Unconstrained
  real mu;                        // mean
  vector[K] beta;                 // regression coefficients

  // Positive (sigma, lambda, variance)
  real<lower=0> sigma;
  real<lower=0> lambda;

  // Probability
  real<lower=0, upper=1> theta;

  // Simplex (sums to 1, for mixture weights)
  simplex[K] pi;

  // Correlation matrix
  corr_matrix[K] Omega;

  // Cholesky factor of covariance
  cholesky_factor_cov[K] L_Sigma;
}
'
cat(param_examples)

modèle{} : Lois a priori et vraisemblance

Le bloc model cumule la log-probabilité a posteriori à l’aide de la syntaxe ~ (tilde). y ~ normal(mu, sigma) est une forme abrégée qui consiste à ajouter le logarithme de la PDF normale à target. Vous pouvez écrire des incréments explicites de log-probabilité avec target += normal_lpdf(y | mu, sigma).

library(rstan)

model_block_example <- '
model {
  // --- Priors ---
  mu    ~ normal(0, 10);          // weakly informative
  sigma ~ cauchy(0, 2.5);         // half-Cauchy for scale
  beta  ~ normal(0, 1);           // standardised coefficients

  // --- Likelihood ---
  // Tilde notation (most common)
  y ~ normal(mu + X * beta, sigma);

  // Equivalent explicit notation:
  // target += normal_lpdf(y | mu + X * beta, sigma);

  // For loop (less common but valid)
  // for (i in 1:N)
  //   target += normal_lpdf(y[i] | mu, sigma);
}
'
cat(model_block_example)

Ajuster un modèle normal simple

Voici un flux de travail Stan minimal complet : définir la chaîne de caractères du modèle, préparer la liste de données, appeler stan(), puis examiner les résultats avec print(). Stan compile le modèle la première fois et le met en cache pour les exécutions suivantes.

library(rstan)

# Stan model: estimate mean and SD of a normal distribution
normal_model <- '
data {
  int<lower=0> N;
  vector[N] y;
}
parameters {
  real mu;
  real<lower=0> sigma;
}
model {
  mu    ~ normal(0, 10);
  sigma ~ exponential(0.1);
  y     ~ normal(mu, sigma);
}
'

# Simulate data
set.seed(42)
y_data <- rnorm(50, mean = 5, sd = 2)

# Fit the model
fit <- stan(
  model_code = normal_model,
  data       = list(N = length(y_data), y = y_data),
  chains     = 2,
  iter       = 1000,
  warmup     = 500,
  refresh    = 0  # suppress iteration output
)

print(fit, pars = c('mu', 'sigma'))

Régression linéaire avec Stan

Stan rend la régression linéaire bayésienne simple à mettre en œuvre : spécifiez des lois a priori normales pour les coefficients et une loi a priori exponentielle ou demi-Cauchy pour sigma. La loi a posteriori fournit la distribution complète de l’incertitude pour chaque coefficient, et pas seulement des estimations ponctuelles.

library(rstan)

lin_reg_model <- '
data {
  int<lower=0> N;
  vector[N] x;
  vector[N] y;
}
parameters {
  real alpha;
  real beta;
  real<lower=0> sigma;
}
model {
  alpha ~ normal(0, 10);
  beta  ~ normal(0, 10);
  sigma ~ exponential(1);
  y ~ normal(alpha + beta * x, sigma);
}
generated quantities {
  vector[N] y_rep;  // posterior predictive
  for (i in 1:N)
    y_rep[i] = normal_rng(alpha + beta * x[i], sigma);
}
'

set.seed(7)
n <- 80
x <- rnorm(n); y <- 2 + 3 * x + rnorm(n, 0, 1)

fit <- stan(model_code = lin_reg_model,
            data = list(N = n, x = x, y = y),
            chains = 2, iter = 1000, refresh = 0)
print(fit, pars = c('alpha', 'beta', 'sigma'))

Bloc transformed parameters{}

Le bloc transformed parameters calcule des quantités dérivées à partir des paramètres échantillonnés. Ces quantités sont utiles pour paramétrer les modèles de manière numériquement stable (par exemple avec des décompositions de Cholesky ou des transformations logarithmiques), tout en conservant l’interprétabilité des paramètres principaux.

library(rstan)

# Model with transformed parameters
trans_param_example <- '
data {
  int<lower=0> N;
  array[N] int<lower=0> y;  // counts
}
parameters {
  real log_lambda;           // work in log space for stability
}
transformed parameters {
  real<lower=0> lambda;
  lambda = exp(log_lambda);  // transform back to original scale
}
model {
  log_lambda ~ normal(1, 2);  // prior on log scale
  y ~ poisson(lambda);
}
'

set.seed(42)
y_counts <- rpois(30, lambda = 5)

fit_poisson <- stan(
  model_code = trans_param_example,
  data       = list(N = length(y_counts), y = y_counts),
  chains     = 2, iter = 1000, refresh = 0
)
print(fit_poisson, pars = c('log_lambda', 'lambda'))

Bloc generated quantities{}

Le bloc generated quantities s’exécute après l’échantillonnage pour calculer des quantités supplémentaires : des échantillons prédictifs a posteriori (y_rep), la log-vraisemblance pour la validation croisée LOO, ou des paramètres transformés destinés aux résumés. Les valeurs produites ici sont échantillonnées à partir de la distribution prédictive a posteriori.

library(rstan)

# Use generated quantities for posterior predictive checks
model_with_gq <- '
data {
  int<lower=0> N;
  vector[N] y;
}
parameters {
  real mu;
  real<lower=0> sigma;
}
model {
  mu    ~ normal(0, 10);
  sigma ~ exponential(0.5);
  y     ~ normal(mu, sigma);
}
generated quantities {
  vector[N] y_rep;           // replicated datasets
  real mean_y_rep;           // mean of replicated data
  for (i in 1:N)
    y_rep[i] = normal_rng(mu, sigma);
  mean_y_rep = mean(y_rep);
}
'

set.seed(1)
y_obs <- rnorm(40, 3, 1.5)
fit <- stan(model_code = model_with_gq,
            data = list(N = length(y_obs), y = y_obs),
            chains = 2, iter = 1000, refresh = 0)
print(fit, pars = c('mu', 'sigma', 'mean_y_rep'))

Transmettre des données de R à Stan

L’argument data de stan() est une liste R nommée. Les noms doivent correspondre exactement aux noms des variables déclarées dans le bloc Stan data{}. Les vecteurs deviennent des vector[N] dans Stan ; les entiers deviennent des int ; les matrices R deviennent des matrix[M,N] dans Stan.

library(rstan)

# Data preparation: names must match Stan data block exactly
set.seed(42)
n <- 60
x1 <- rnorm(n)
x2 <- rnorm(n)
y  <- 1.5 + 2 * x1 - 0.8 * x2 + rnorm(n, 0, 0.5)

# Build the design matrix
X <- cbind(x1, x2)  # 60 x 2 matrix

# Named list passed to stan(data = ...)
stan_data <- list(
  N = n,          # int
  K = ncol(X),    # int
  X = X,          # matrix[N, K]
  y = y           # vector[N]
)

cat('Stan data list elements:\n')
for (nm in names(stan_data)) {
  cat(' ', nm, ': class =', class(stan_data[[nm]]),
      'dim =', paste(dim(stan_data[[nm]]), collapse = 'x'),
      '\n')
}

Afficher le modèle compilé

Après l’ajustement, utilisez print(fit) pour afficher les résumés a posteriori (moyenne, se_mean, sd, quantiles, Rhat, n_eff) de tous les paramètres. Utilisez stan_plot(fit) pour obtenir un graphique visuel des intervalles et traceplot(fit) pour évaluer le mélange des chaînes.

library(rstan)

# Reuse the simple normal model from scene 6
normal_model <- '
data { int<lower=0> N; vector[N] y; }
parameters { real mu; real<lower=0> sigma; }
model {
  mu ~ normal(0, 10);
  sigma ~ exponential(0.1);
  y ~ normal(mu, sigma);
}
'

set.seed(5)
fit <- stan(model_code = normal_model,
            data = list(N = 50, y = rnorm(50, 7, 3)),
            chains = 2, iter = 1000, refresh = 0)

# Detailed summary table
print(fit)

# Extract as data frame
posterior_df <- as.data.frame(fit)
cat('\nPosterior samples shape:', nrow(posterior_df),
    'rows x', ncol(posterior_df), 'cols\n')

Vérification rapide

Dans un modèle Stan, vous souhaitez contraindre un paramètre à être strictement positif (par exemple, un écart type). Quelle déclaration est correcte ?

Récapitulatif : écrire des modèles Stan

Points essentiels :

  • Un modèle Stan possède trois blocs essentiels : data{}, parameters{}, model{}
  • Contraintes : <lower=0>, <upper=1>, <lower=0, upper=1> pour les probabilités
  • Types : int, real, vector[N], matrix[M,N], simplex[K]
  • Bloc model : utilisez la syntaxe tilde y ~ normal(mu, sigma) pour les lois a priori et la vraisemblance
  • transformed parameters{} pour les quantités dérivées ; generated quantities{} pour les calculs après l’échantillonnage
  • Transmettez les données sous forme de liste R nommée, dont les noms correspondent exactement à ceux des blocs Stan
  • rstan_options(auto_write = TRUE) met en cache les modèles compilés
library(rstan)

# Stan model skeleton
model_skeleton <- '
data    { int N; vector[N] y; }
parameters { real mu; real<lower=0> sigma; }
model   { mu ~ normal(0,10); sigma ~ exponential(1); y ~ normal(mu, sigma); }
'
cat(model_skeleton)
cat('\nFit with: stan(model_code = model_skeleton, data = list(N=..., y=...), chains=4)\n')

Questions Fréquemment Posées

La leçon « Écrire des modèles Stan dans R » est-elle gratuite ?

Oui — le texte complet de « Écrire des modèles Stan dans R » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Écrire des modèles Stan dans R » ?

Définissez les blocs de données, les paramètres et le bloc de modèle dans la syntaxe Stan. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer R Academy ?

Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Écrire des modèles Stan dans R » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon R Academy ?

Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Introduction au raisonnement bayésien
  2. Écrire des modèles Stan dans R
  3. Échantillonnage MCMC et diagnostics
  4. Vérifications prédictives a posteriori
← Retour à R Academy