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에서 보기