Summary
Scoping an instrumental-variable workflow for pathmc, motivated by price-elasticity estimation under endogeneity (e.g. The ML trap in price elasticity estimation): price is set in response to a latent demand shock, so a naive demand~price regression is biased (elasticity can flip sign). An exogenous cost shock that moves price but not demand directly is a valid instrument.
Key finding: this splits across two layers, and only one is actually missing
Estimation — already supported. The ~~ correlated-residual operator already compiles a set of equations into a joint MvNormal with an LKJCholeskyCov over the residuals (see residuals.py, LKJResidual.emit; block detection in compile.py / graph.py). The docs describe the ~~ bidirected edge as being the unmeasured confounder. That joint correlated-errors structure is exactly Bayesian limited-information IV. So the continuous-outcome IV model can be written and fit today, with zero API change:
spec = """
log_price ~ g*cost_shock + controls # instrument enters the treatment equation
log_demand ~ b_price*log_price + controls # exclusion: cost_shock omitted here
log_price ~~ log_demand # unobserved demand-shock endogeneity
"""
m = pathmc.model(spec, data=df); m.fit()
b_price recovers the causal elasticity; the residual correlation soaks up the confounding; do()/ate() propagate through the block generatively.
Identification — genuinely missing. identify.py (is_identifiable, adjustment_sets) only reasons about the backdoor criterion. With an unobserved confounder + a valid instrument it returns "not identifiable" — a false negative, because it never inspects instruments. The docs (docs/user_guide/02-comparison.qmd) state "No instrumental variables", which is true of identification but overstated for estimation.
Design decision: detect + advise, do NOT auto-insert ~~
Whether a graph is an "IV situation" is query-dependent (defined relative to a treatment/outcome/instrument triple, not the graph alone). And a ~~ edge is an untestable structural assumption the user must own — the tool cannot infer hidden confounding from a DAG that does not state it. So pathmc should recognize IV identification when the user has declared the confounding and an instrument exists, and advise (warn + document) otherwise — never silently add ~~.
Sub-issues
Dependency shape: #345→#344; #348→#344 (+#346); #346 & #347 pair up; estimation for the continuous case already works today.
Summary
Scoping an instrumental-variable workflow for pathmc, motivated by price-elasticity estimation under endogeneity (e.g. The ML trap in price elasticity estimation): price is set in response to a latent demand shock, so a naive demand~price regression is biased (elasticity can flip sign). An exogenous cost shock that moves price but not demand directly is a valid instrument.
Key finding: this splits across two layers, and only one is actually missing
Estimation — already supported. The
~~correlated-residual operator already compiles a set of equations into a jointMvNormalwith anLKJCholeskyCovover the residuals (seeresiduals.py,LKJResidual.emit; block detection incompile.py/graph.py). The docs describe the~~bidirected edge as being the unmeasured confounder. That joint correlated-errors structure is exactly Bayesian limited-information IV. So the continuous-outcome IV model can be written and fit today, with zero API change:b_pricerecovers the causal elasticity; the residual correlation soaks up the confounding;do()/ate()propagate through the block generatively.Identification — genuinely missing.
identify.py(is_identifiable,adjustment_sets) only reasons about the backdoor criterion. With an unobserved confounder + a valid instrument it returns "not identifiable" — a false negative, because it never inspects instruments. The docs (docs/user_guide/02-comparison.qmd) state "No instrumental variables", which is true of identification but overstated for estimation.Design decision: detect + advise, do NOT auto-insert
~~Whether a graph is an "IV situation" is query-dependent (defined relative to a treatment/outcome/instrument triple, not the graph alone). And a
~~edge is an untestable structural assumption the user must own — the tool cannot infer hidden confounding from a DAG that does not state it. So pathmc should recognize IV identification when the user has declared the confounding and an instrument exists, and advise (warn + document) otherwise — never silently add~~.Sub-issues
~~idiomDependency shape: #345→#344; #348→#344 (+#346); #346 & #347 pair up; estimation for the continuous case already works today.