Skip to main content

prior-elicitation

Load when the user is choosing priors, running prior predictive checks, calling find_constrained_prior, using PreliZ, or otherwise eliciting domain knowledge into a Bayesian model. Covers weakly informative priors, constrained priors, sensitivity analysis, and elicitation workflows. Triggers include: prior selection, elicitation, find_constrained_prior, PreliZ, prior predictive, expert/informative priors, weakly informative priors, constrained priors.

跳到安装

来源信息

仓库
pymc-labs/python-analytics-skills
最近来源活动
2026年6月22日 14:35
检测到的 SKILL.md 语言
英语
星标
82
分支
10

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
4 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
prior-elicitation
description
Load when the user is choosing priors, running prior predictive checks, calling find_constrained_prior, using PreliZ, or otherwise eliciting domain knowledge into a Bayesian model. Covers weakly informative priors, constrained priors, sensitivity analysis, and elicitation workflows. Triggers include: prior selection, elicitation, find_constrained_prior, PreliZ, prior predictive, expert/informative priors, weakly informative priors, constrained priors.
# Prior Elicitation for PyMC Models ## Decision Flowchart: Choosing a Prior Strategy ``` Do you have domain expertise or expert access? ├── YES: Can the expert quantify beliefs precisely? │ ├── YES → Expert elicitation (SHELF protocol, PreliZ roulette/quartile) │ └── NO → Constrained priors (find_constrained_prior, PreliZ maxent) └── NO: Do you know the plausible scale of the parameter? ├── YES → Weakly informative priors (Normal, HalfNormal, Student-t) └── NO → Use prior predictive checks to calibrate └── Generate predictions → Do they cover plausible outcomes? ├── YES → Prior is acceptable └── NO → Tighten or widen prior, repeat ``` ### When to Use Each Strategy | Strategy | Use When | Example | |---|---|---| | Weakly informative | You know rough scale but not shape | `pm.Normal("beta", 0, 10)` for standardized predictors | | Constrained | "95% sure the value is between A and B" | `pm.find_constrained_prior(pm.Normal, ...)` | | MaxEnt | You have bounds and want least-informative prior | `preliz.maxent(preliz.Normal(), -1, 1, 0.94)` | | Expert-elicited | Domain expert provides quantiles or probabilities | SHELF protocol with PreliZ | | Hierarchical | Group-level parameters with partial pooling | `pm.Normal("mu_group", mu=mu_hyper, sigma=sigma_hyper)` | ## pm.find_constrained_prior Finds distribution parameters such that a specified mass falls within given bounds. ```python import pymc as pm # "I'm 95% sure the effect is between -2 and 2" params = pm.find_constrained_prior( pm.Normal, lower=-2, upper=2, mass=0.95, init_guess={"mu": 0, "sigma": 1}, ) # Returns: {"mu": 0.0, "sigma": 1.02} # Use directly in model with pm.Model() as model: beta = pm.Normal("beta", **params) ``` ### Common Patterns ```python # Positive parameter, 90% between 0.1 and 10 params = pm.find_constrained_prior( pm.LogNormal, lower=0.1, upper=10, mass=0.90, init_guess={"mu": 0, "sigma": 1}, ) # Rate parameter, 80% between 0.01 and 0.5 params = pm.find_constrained_prior( pm.Gamma, lower=0.01, upper=0.5, mass=0.80, init_guess={"alpha": 2, "mu": 0.1}, ) # Bounded parameter (probability), 95% between 0.2 and 0.8 params = pm.find_constrained_prior( pm.Beta, lower=0.2, upper=0.8, mass=0.95, init_guess={"alpha": 5, "beta": 5}, ) ``` See `references/find_constrained_prior.md` for full API details. ## PreliZ Integration PreliZ is a library for prior elicitation. It provides tools to translate domain knowledge into probability distributions. ### Maximum Entropy (maxent) Find the least-informative distribution consistent with constraints: ```python import preliz as pz # Least-informative Normal with 94% mass in [-1, 1] dist = pz.maxent(pz.Normal(), -1, 1, 0.94) # Least-informative HalfNormal with 94% mass below 5 dist = pz.maxent(pz.HalfNormal(), 0, 5, 0.94) # Use result in PyMC with pm.Model(): sigma = pm.HalfNormal("sigma", sigma=dist.sigma) ``` ### Roulette (chip-and-bin elicitation) Interactive method where an expert allocates "chips" to bins: ```python # Define bins and expert-allocated chip counts pz.roulette(x_min=0, x_max=100, nrows=10) # Opens interactive widget — expert distributes chips across bins # Returns fitted distribution ``` ### Predictive Finder (predictive_elicitation) Elicit priors by reasoning about observable predictions: ```python def my_model(x, beta0, beta1, sigma): mu = beta0 + beta1 * x return pz.Normal(mu=mu, sigma=sigma) # Expert specifies: "when x=5, y is typically between 10 and 30" pz.predictive_finder(my_model, target=pz.Normal()) ``` ### Quartile Method Specify distribution via expert-provided quartiles: ```python # Expert says: "median is 50, Q1 is 30, Q3 is 70" dist = pz.quartile(pz.Normal(), q1=30, q2=50, q3=70) ``` See `references/preliz.md` for comprehensive PreliZ reference. ## Prior Predictive Interpretation Checklist Always run prior predictive checks before sampling: ```python with model: prior_pred = pm.sample_prior_predictive(draws=500, random_seed=42) # prior_pred is a DataTree (ArviZ 1.1) prior_samples = prior_pred["prior"].ds prior_predictive = prior_pred["prior_predictive"].ds ``` ### What to Check 1. **Range of predictions**: Do simulated outcomes cover the plausible data range? - Plot: `az.plot_ppc_dist(prior_pred, group="prior_predictive", kind="ecdf")` 2. **Impossible values**: Are any simulated outcomes physically impossible? - Negative counts, probabilities outside [0,1], negative durations 3. **Scale**: Is the prior predictive spread reasonable relative to the data? - Too wide = vague, slow convergence. Too narrow = overly informative 4. **Shape**: Do simulated datasets look qualitatively like real data? - Bimodal when data is unimodal? Heavy tails when data is bounded? ### Red Flags - Prior predictive covers 10+ orders of magnitude — priors too vague - >10% of samples produce impossible values — wrong distribution family or scale - Prior predictive is concentrated on a narrow range far from data — prior is miscalibrated - All prior predictive samples look identical — prior is too tight (dogmatic) ## Expert Elicitation Workflow ### SHELF-like Protocol 1. **Define the parameter**: What does it represent? What are its units? 2. **Establish plausible range**: "What is the lowest/highest value you would expect?" 3. **Elicit quantiles**: "What value are you 25%/50%/75% sure the parameter is below?" 4. **Elicit tail behavior**: "Is there any chance of extreme values? How extreme?" 5. **Fit distribution**: Use `preliz.quartile()` or `pm.find_constrained_prior()` 6. **Validate**: Show the fitted distribution back to the expert for confirmation 7. **Prior predictive check**: Generate predictions and ask "do these look realistic?" For prior predictive checking workflows in PyMC, see the [pymc-modeling skill](../pymc-modeling/SKILL.md). ### Translating Domain Knowledge | Expert says | Translation | |---|---| | "Roughly between A and B" | `find_constrained_prior(..., lower=A, upper=B, mass=0.90)` | | "Usually around X, rarely above Y" | LogNormal or Gamma with median near X, 95th percentile near Y | | "Positive, with diminishing probability for large values" | HalfNormal, Exponential, or HalfCauchy | | "Could go either way, maybe 50-50" | `pm.Beta("p", alpha=1, beta=1)` or `pm.Normal("effect", 0, ...)` | | "No more than X in absolute value" | `pm.TruncatedNormal` or `pm.Uniform(-X, X)` | See `references/elicitation_workflows.md` for detailed protocols. ## Sensitivity Analysis ### Checking Prior Sensitivity Conclusions are robust if they hold under different reasonable priors. ```python # Fit model with original priors with pm.Model() as model_original: beta = pm.Normal("beta", 0, 1) ... idata_orig = pm.sample() # Fit with wider priors with pm.Model() as model_wide: beta = pm.Normal("beta", 0, 10) ... idata_wide = pm.sample() # Fit with different family with pm.Model() as model_robust: beta = pm.StudentT("beta", nu=3, mu=0, sigma=1) ... idata_robust = pm.sample() # Compare posteriors visually import arviz as az az.plot_forest( [idata_orig, idata_wide, idata_robust], model_names=["Original", "Wide", "Robust"], var_names=["beta"], ) ``` ### What to Report - If posteriors are similar across priors: conclusions are data-driven (robust) - If posteriors differ substantially: conclusions are prior-sensitive — report sensitivity - Always compare the posterior-to-prior contraction: strong contraction = data is informative ### Power-scaling Sensitivity For systematic sensitivity analysis, scale the prior log-density by a factor alpha: ```python # alpha > 1: stronger prior influence # alpha < 1: weaker prior influence # Compare posteriors across alpha in [0.5, 0.75, 1.0, 1.25, 1.5] ``` When posteriors are stable across alpha values, the inference is robust to prior choice.
在 GitHub 查看