Skip to main content

pymc

Probabilistic programming for Bayesian statistical modeling and inference. PyMC provides declarative model specification with MCMC (NUTS) and variational inference samplers; NumPyro offers JAX-accelerated equivalent for large-scale problems. Use when: quantifying uncertainty in parameter estimates, building hierarchical or mixed-effects models, Bayesian A/B testing or experimentation, posterior predictive checks, model comparison with WAIC or LOO-CV, scientific measurement with error propagation, any analysis requiring credible intervals, probability statements like P(effect > 0), or situations where understanding the full posterior distribution matters more than a single p-value. Also use when priors encode domain knowledge, sample sizes are small, or data is naturally nested.

Informações da origem

Repositório
tondevrel/scientific-agent-skills
Última atividade na origem
1 de fevereiro de 2026 às 04:41
Idioma detectado do SKILL.md
inglês
Estrelas
22
Forks
2

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
pymc
description
Probabilistic programming for Bayesian statistical modeling and inference. PyMC provides declarative model specification with MCMC (NUTS) and variational inference samplers; NumPyro offers JAX-accelerated equivalent for large-scale problems. Use when: quantifying uncertainty in parameter estimates, building hierarchical or mixed-effects models, Bayesian A/B testing or experimentation, posterior predictive checks, model comparison with WAIC or LOO-CV, scientific measurement with error propagation, any analysis requiring credible intervals, probability statements like P(effect > 0), or situations where understanding the full posterior distribution matters more than a single p-value. Also use when priors encode domain knowledge, sample sizes are small, or data is naturally nested.
# PyMC & NumPyro — Probabilistic Programming PyMC is the leading Python library for Bayesian statistical modeling. You declare priors and a likelihood — the sampler computes the posterior automatically. NumPyro provides the identical paradigm on JAX for GPU-accelerated inference. Both integrate with ArviZ for diagnostics. **Core value:** Instead of "is this significant?" (p-value), Bayesian methods answer "what is the full probability distribution over possible values?" — a fundamentally richer answer for every scientific and business question. ## When to Use - Quantifying uncertainty: credible intervals, prediction intervals, error propagation through calculations. - Hierarchical models: data naturally nested (students in schools, patients in hospitals, stores in regions). - A/B testing where "P(B > A) = 0.95" is more actionable than "p = 0.03". - Scientific measurement where uncertainty must propagate through a pipeline. - Model comparison: which explanation fits better? (WAIC, LOO-CV) - Small samples: Bayesian priors regularize and prevent overfitting where MLE fails. - Any problem where you can articulate the generative story (how data was produced). **When NOT to use:** Simple hypothesis tests on huge datasets where a p-value suffices. Pure prediction without uncertainty (use sklearn). Real-time inference (MCMC is too slow). ## Reference Documentation **PyMC docs**: https://pymc.io/en/stable/ **NumPyro docs**: https://num.pyro.ai/en/stable/ **ArviZ docs**: https://arviz.org/en/stable/ **GitHub**: https://github.com/pymc-devs/pymc **Search patterns**: `pm.Model`, `pm.sample`, `pm.Normal`, `az.summary`, `az.plot_trace` ## Core Principles ### Bayes' Theorem **posterior ∝ prior × likelihood** Prior = belief before data. Likelihood = how probable is this data given the parameter? Posterior = updated belief after seeing data. PyMC specifies prior + likelihood; MCMC computes the posterior by sampling. ### MCMC — Markov Chain Monte Carlo The posterior is rarely analytically tractable. MCMC draws samples that, in the limit, are distributed exactly as the posterior. PyMC uses NUTS (No-U-Turn Sampler) — state of the art. Output: thousands of parameter values drawn from the posterior. ### Posterior Predictive Check (PPC) Generate synthetic data from the fitted model. Compare to real data. If they match visually, the model is reasonable. This catches systematic failures that summary statistics miss — the single most important validation step. ### Credible Intervals A 95% credible interval [a, b] means: "Given the data, there is a 95% probability the true parameter lies in [a, b]." This is the intuitive interpretation people actually want. (Frequentist confidence intervals do NOT mean this.) ## Quick Reference ### Installation ```bash pip install pymc arviz # PyMC + diagnostics pip install numpyro jax jaxlib # NumPyro (JAX backend, GPU-accelerated) ``` ### Standard Imports ```python import pymc as pm import arviz as az import numpy as np import pandas as pd ``` ### Basic Pattern — Coin Flip (Simplest Bayesian Model) ```python import pymc as pm import arviz as az # Observed: 15 heads out of 50 flips n_flips, n_heads = 50, 15 with pm.Model() as model: # Prior: belief about P(heads) before seeing data p = pm.Beta('p', alpha=2, beta=2) # Weakly informative, centered at 0.5 # Likelihood: how many heads given p heads = pm.Binomial('heads', n=n_flips, p=p, observed=n_heads) # Sample the posterior trace = pm.sample(4000, cores=2, return_inferencedata=True, random_seed=42) # Interpret posterior az.summary(trace, var_names=['p']) # → mean ≈ 0.31, HDI[94%] = [0.19, 0.43] # Translation: "P(heads) is 31%; 94% credible that it's between 19% and 43%" az.plot_posterior(trace, var_names=['p']) ``` ### Basic Pattern — NumPyro Equivalent ```python import numpyro import numpyro.distributions as dist from numpyro.infer import MCMC, NUTS from jax import random import jax.numpy as jnp n_flips, n_heads = 50, 15 def model(): p = numpyro.sample('p', dist.Beta(2, 2)) numpyro.sample('heads', dist.Binomial(n_flips, p), obs=n_heads) kernel = NUTS(model) mcmc = MCMC(kernel, num_warmup=1000, num_samples=4000, num_chains=2) mcmc.run(random.PRNGKey(0)) samples = mcmc.get_samples() print(f"P(heads): {samples['p'].mean():.3f} " f"HDI=[{jnp.percentile(samples['p'], 3):.3f}, {jnp.percentile(samples['p'], 97):.3f}]") ``` ## Critical Rules ### ✅ DO - **Check convergence ALWAYS** — `az.summary()` shows Rhat. Rhat > 1.01 means not converged. Never trust results without this. - **Use ≥ 2 chains, prefer 4** — Cannot assess convergence with 1 chain. - **Do posterior predictive checks** — `pm.sample_posterior_predictive()`. Non-negotiable validation. - **Use informative priors where possible** — Even weakly informative (`HalfNormal(1)` for σ) beats flat priors. Flat priors on unbounded scales cause convergence failures. - **Use `HalfNormal` or `Gamma` for scale parameters** — σ must be positive. `pm.HalfNormal('sigma', sigma=1)` is the default choice. - **Wrap derived quantities in `pm.Deterministic`** — Only way to track computed posteriors (odds ratios, differences, lifts). - **Set `random_seed`** — Reproducibility. - **Use `return_inferencedata=True`** — Returns ArviZ InferenceData. Legacy dict format is deprecated. ### ❌ DON'T - **Don't ignore divergences** — Divergence = sampler lost. Requires reparameterization or prior adjustment. - **Don't use `Uniform` on scale parameters** — `pm.Uniform('sigma', 0, 100)` causes sampler to struggle near 0. Use `HalfNormal`. - **Don't confuse `observed` and unobserved** — `observed=data` binds to data. Without it, the variable is sampled from the prior. - **Don't run only 1 chain** — Cannot diagnose convergence. - **Don't use PyMC for >100k rows without considering NumPyro** — CPU-bound PyMC becomes very slow. NumPyro + JAX + GPU is 10–100x faster. - **Don't mix up loss functions / label formats** — In Bayesian context: if labels are integers use `Categorical`; if binary use `Bernoulli`; if proportions use `Beta`. ## Anti-Patterns (NEVER) ```python import pymc as pm import numpy as np # ❌ BAD: Flat prior on scale → sampler struggles near zero with pm.Model(): sigma = pm.Uniform('sigma', lower=0, upper=100) # Divergences guaranteed # ✅ GOOD: HalfNormal is the standard for positive scales with pm.Model(): sigma = pm.HalfNormal('sigma', sigma=1.0) # ❌ BAD: Ignoring convergence — trusting undiagnosed results with pm.Model(): mu = pm.Normal('mu', mu=0, sigma=10) obs = pm.Normal('obs', mu=mu, sigma=1, observed=data) trace = pm.sample(100, cores=1) # Too few draws, 1 chain print(trace.posterior['mu'].mean().values) # Meaningless if not converged # ✅ GOOD: Proper setup + convergence gate with pm.Model(): mu = pm.Normal('mu', mu=0, sigma=10) obs = pm.Normal('obs', mu=mu, sigma=1, observed=data) trace = pm.sample(4000, cores=4, return_inferencedata=True, random_seed=42) import arviz as az summary = az.summary(trace) assert summary['r_hat'].max() < 1.01, f"Not converged: Rhat={summary['r_hat'].max():.3f}" # ❌ BAD: Derived quantity not tracked — lost after sampling with pm.Model(): p_a = pm.Beta('p_a', 1, 1) p_b = pm.Beta('p_b', 1, 1) # Difference p_b - p_a is never recorded in the trace # ✅ GOOD: Deterministic captures derived posteriors with pm.Model(): p_a = pm.Beta('p_a', 1, 1) p_b = pm.Beta('p_b', 1, 1) diff = pm.Deterministic('diff', p_b - p_a) # Now in trace.posterior['diff'] # ❌ BAD: No posterior predictive check — model could be completely wrong with pm.Model() as model: mu = pm.Normal('mu', mu=0, sigma=10) sigma = pm.HalfNormal('sigma', sigma=1) obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=data) trace = pm.sample(4000, return_inferencedata=True) # "Converged" ≠ "correct". Convergence just means the sampler found A distribution. # ✅ GOOD: PPC validates whether the model generates plausible data with pm.Model() as model: mu = pm.Normal('mu', mu=0, sigma=10) sigma = pm.HalfNormal('sigma', sigma=1) obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=data) trace = pm.sample(4000, return_inferencedata=True) ppc = pm.sample_posterior_predictive(trace, model=model) az.plot_ppc(ppc, var_names=['obs']) # Simulated vs real — must look similar ``` ## Prior Selection Guide ``` PARAMETER | RECOMMENDED PRIOR | NOTES ---------------------------|--------------------------------|-------------------------------------- Mean / intercept | Normal(domain_mean, wide_sd) | Weakly informative; scale to data Positive scale (σ, τ) | HalfNormal(1) | Default; adjust sigma to data scale Rate / proportion (0–1) | Beta(1, 1) | Uniform on [0,1]; Beta(2,5) if informed Count rate (λ) | Gamma(2, 1) or Exponential(1) | Positive, right-skewed Regression slope | Normal(0, 2–5) | Weakly regularizing toward zero Odds ratio | Lognormal(0, 1) | Positive, multiplicative scale Correlation | LKJCorrelation(1) | PyMC-specific; valid [-1, 1] RULES OF THUMB: → Know the rough scale? Use Normal(known_mean, 2–10 × known_std). → Know nothing? Wide but bounded priors, NOT Uniform(-∞, ∞). → Scale parameters (σ, τ) ALWAYS positive → HalfNormal, Gamma, or Exponential. → More data = prior matters less. With n > 100, even bad priors get washed out. ``` ## Model Specification — PyMC Patterns ### Basic Structure ```python import pymc as pm with pm.Model() as model: # 1. PRIORS — parameters to learn mu = pm.Normal('mu', mu=0, sigma=10) sigma = pm.HalfNormal('sigma', sigma=1) # 2. LIKELIHOOD — data generation mechanism obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=data) # 3. DERIVED QUANTITIES (optional) # pm.Deterministic('name', expression) # 4. SAMPLE trace = pm.sample(4000, cores=4, return_inferencedata=True, random_seed=42) ``` ### Linear Regression ```python import pymc as pm import numpy as np # X shape: (n,) single predictor or (n, p) multiple # y shape: (n,) with pm.Model(): intercept = pm.Normal('intercept', mu=0, sigma=5) slope = pm.Normal('slope', mu=0, sigma=5) # shape=(p,) for multivariate sigma = pm.HalfNormal('sigma', sigma=2) mu = pm.Deterministic('mu', intercept + slope * X) # Track mean in trace y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed=y) trace = pm.sample(4000, cores=4, return_inferencedata=True, random_seed=42) ``` ### Multivariate Regression ```python import pymc as pm import numpy as np X = np.array([...]) # Shape: (n, p) y = np.array([...]) n, p = X.shape with pm.Model(): intercept = pm.Normal('intercept', mu=0, sigma=5) slopes = pm.Normal('slopes', mu=0, sigma=5, shape=p) # One per feature sigma = pm.HalfNormal('sigma', sigma=2) mu = pm.Deterministic('mu', intercept + X @ slopes) # Matrix multiply y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed=y) trace = pm.sample(4000, cores=4, return_inferencedata=True) ``` ## Sampling and Diagnostics ### Sampling Parameters ```python import pymc as pm with pm.Model() as model: # ... model ... trace = pm.sample( draws=4000, # Posterior samples per chain (after warmup) tune=2000, # Warmup draws — discarded; sampler adapts here cores=4, # Parallel chains = CPU cores chains=4, # Independent chains for convergence check return_inferencedata=True, # ArviZ InferenceData format random_seed=42, # Reproducibility ) ``` ### Diagnostics Checklist ```python import pymc as pm import arviz as az # 1. SUMMARY — Rhat + ESS at a glance # Rhat ≈ 1.00 → converged | ESS > 100 → enough effective samples summary = az.summary(trace) print(summary[['mean', 'sd', 'hdi_3%', 'hdi_97%', 'r_hat', 'ess_bulk']]) # 2. TRACE PLOT — visual convergence # Chains should overlap, look like random noise. No trends or drift. az.plot_trace(trace, var_names=['mu', 'sigma']) # 3. POSTERIOR az.plot_posterior(trace, var_names=['mu', 'sigma']) # 4. ENERGY — divergence check az.plot_energy(trace) # Two distributions should overlap heavily # 5. PPC — model validation ppc = pm.sample_posterior_predictive(trace, model=model) az.plot_ppc(ppc, var_names=['y_obs']) # ─── Convergence decision tree ─── # Rhat > 1.05 → STOP. Increase tune, add chains, or reparameterize. # Rhat 1.01–1.05 → WARNING. Increase draws and tune. # Rhat < 1.01 → OK. Verify ESS > 100. # Many divergences → Reparameterize or tighten priors.
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub