neighbayes.models.SEMFlow¶
- class neighbayes.models.SEMFlow(y, X, W, **kwargs)[source]¶
Bayesian spatial-error flow model with three free spatial parameters.
\[y = X\beta + u, \qquad B u = \varepsilon, \qquad B = I_N - \lambda_d W_d - \lambda_o W_o - \lambda_w W_w, \quad \varepsilon \sim \mathcal{N}(0, \sigma^2 I_N)\]where \(W_d = I_n \otimes W\), \(W_o = W \otimes I_n\), \(W_w = W \otimes W\). The Kronecker spatial structure is identical to
SARFlow, but the spatial filter acts on the disturbance rather than the dependent variable. Equivalently the model implies a Gaussian likelihood with covariance \(\sigma^2 (B^\top B)^{-1}\).Marginal mean is \(\mathbb{E}[y] = X\beta\), so there are no \(X\)-mediated spatial spillovers — the LeSage / Thomas-Agnan decomposition reduces to the closed-form expressions used by
OLSFlow(direct effect equals \(\beta\), network effect equals zero). UseSARFlowif spillovers from observed covariates are of interest.- Parameters:¶
- y : array-like, shape (n, n) or (N,)¶
Observed origin-destination flow matrix or its vec-form.
- W : libpysal.graph.Graph or scipy.sparse / dense (n×n) matrix¶
Row-standardized regional weights on n units (Graph or matrix).
- X : np.ndarray or pandas.DataFrame, shape (N, p)¶
Full origin-destination design matrix with \(N = n^2\) rows. DataFrame columns are preserved as feature names.
- col_names : list of str, optional
Column labels for
X. Inferred from a DataFrame if omitted; otherwise defaults to["x0", "x1", ...].- k : int, optional
Number of regional attribute columns (destination/origin variable pairs). Inferred from
dest_*/orig_*column names when the standard LeSage layout is used.- logdet_method : str, default "resolvent"
Log-determinant method. The default
"resolvent"samples via the resolvent-gradient sampler (recommended).- restrict_positive : bool, default True
If True, use
pm.Dirichlet("lam_simplex", a=ones(4))to enforce \(\\lambda_d, \\lambda_o, \\lambda_w \\geq 0\) and \(\\lambda_d + \\lambda_o + \\lambda_w \\leq 1\). If False, three independentpm.Uniform(lam_lower, lam_upper)priors are used with a differentiable quadratic-wall stability potential.- symmetric_xo_xd : bool, optional
If
None(default), origin and destination design blocks are compared and symmetry is auto-detected.- priors : dict, optional
Override default priors. Supported keys:
beta_mu: float, default 0.0 — Normal prior mean forbeta.beta_sigma: float, default 1e6 — Normal prior std forbeta.sigma_sigma: float, default 10.0 — HalfNormal prior std forsigma.lam_lower: float, default -1.0 — Lower bound of Uniform prior on each λ (only whenrestrict_positive=False).lam_upper: float, default 1.0 — Upper bound of Uniform prior on each λ (only whenrestrict_positive=False).
Notes
Implementation: PyMC body uses precomputed lags of both
yandX(self._Wd,self._Wo,self._Wwapplied toself._X) so that the residual \(B u = B y - B X \\beta\) is expressible as a linear combination of fixed quantities — no symbolic sparse mat-vec is required. The Jacobian \(\\log|B|\) reuses the same trace-based polynomial asSARFlow.Methods
__init__(y, X, W, **kwargs)fit([draws, tune, chains, random_seed, ...])Sample the SEM-flow posterior.
Return fitted values at posterior mean parameters.
posterior_predictive([n_draws, random_seed])Draw posterior-predictive samples
y_rep.Return residuals
y - fitted_values.Run Bayesian LM specification tests and return a summary table.
spatial_diagnostics_decision([alpha, format])Return a model-selection decision from Bayesian LM test results.
spatial_effects([draws, ...])Summarize posterior origin/destination/intra/network/total effects.
summary([var_names])Return posterior summary table.
Attributes
Return the ArviZ InferenceData from the most recent fit.
Return the PyMC model object built for the most recent fit.
-
fit(draws=
2000, tune=1000, chains=4, random_seed=None, *, step_size=0.0005, n_probes=48, logdet_method='jax', n_quad=8, progressbar=True, n_jobs=-1, idata_kwargs=None, **sample_kwargs)[source]¶ Sample the SEM-flow posterior.
Uses the resolvent-Kronecker gradient sampler (MALA-on-λ within GLS Gibbs for
β, σ²) by default; the separable subclass (which sets a separablelogdet_method) routes to the PyMC/NUTS path instead.
- property inference_data : arviz.data.inference_data.InferenceData | None[source]¶
Return the ArviZ InferenceData from the most recent fit.
-
posterior_predictive(n_draws=
None, random_seed=None)[source]¶ Draw posterior-predictive samples
y_rep.For each (subsampled) posterior draw, simulates a new flow vector
y_repfrom the implied data-generating process by solving the sparse systemA(rho) y_rep = X β + ε(Gaussian) ory_rep ~ NegBin(exp(A^{-1} X β), α)(NB variants).
- property pymc_model : pymc.model.core.Model | None[source]¶
Return the PyMC model object built for the most recent fit.
For Gibbs-fitted models the PyMC model is not constructed during sampling; it is built lazily on first access so that downstream consumers (e.g. bridge sampling for marginal likelihoods) can evaluate
logpand the prior under the same model definition used by the NUTS path.
- residuals()[source]¶
Return residuals
y - fitted_values.- Returns:¶
Residual vector
y - fitted_valueson the same scale asfitted_values().- Return type:¶
np.ndarray
- spatial_diagnostics()[source]¶
Run Bayesian LM specification tests and return a summary table.
Looks up the diagnostic suite registered for this model class and calls each test function on this fitted model, collecting the results into a tidy DataFrame. The set of tests depends on the model type — for example, an OLS model runs LM-Lag, LM-Error, LM-SDM-Joint, and LM-SLX-Error-Joint, while an SAR model runs LM-Error, LM-WX, and Robust-LM-WX. Panel models run the
Panel--prefixed analogues (e.g. Panel-LM-Lag).Requires the model to have been fit (
.fit()called) and a spatial weights matrixWto have been supplied at construction time.- Returns:¶
DataFrame indexed by test name with columns:
Column
Description
statistic
Posterior mean of the LM statistic
median
Posterior median of the LM statistic
df
Degrees of freedom for the \(\chi^2\) reference
p_value
Bayesian p-value:
1 - chi2.cdf(mean, df)ci_lower
Lower bound of 95% credible interval (2.5%)
ci_upper
Upper bound of 95% credible interval (97.5%)
The DataFrame has
attrs["model_type"](class name) andattrs["n_draws"](total posterior draws) metadata.- Return type:¶
pandas.DataFrame
- Raises:¶
RuntimeError – If the model has not been fit yet.
ValueError – If no spatial weights matrix
Wwas supplied.
See also
spatial_diagnostics_decisionModel-selection decision based on the test results.
spatial_effectsPosterior inference for direct/indirect/total impacts.
Examples
>>> ols = OLS(formula="price ~ income + crime", data=df, W=w) >>> ols.fit() >>> ols.spatial_diagnostics() statistic median df p_value ci_lower ci_upper LM-Lag 3.21 2.98 1 0.073 0.12 8.54 LM-Error 5.67 5.34 1 0.017 0.34 12.10 LM-SDM-Joint 7.89 7.12 4 0.096 1.23 18.32 LM-SLX-Error-Joint 6.45 5.98 4 0.168 0.89 15.67
-
spatial_diagnostics_decision(alpha=
0.05, format='graphviz')[source]¶ Return a model-selection decision from Bayesian LM test results.
Walks the flow decision tree using Bayesian p-values from
spatial_diagnostics()and recommends either the OLS flow baseline (no spatial dependence detected) or the SAR flow model (at least one direction is significant).- Parameters:¶
- alpha : float, default 0.05¶
Significance level for the Bayesian p-values.
- format : {"graphviz", "ascii", "model"}, default "graphviz"¶
Output format.
"model"returns the recommended model name string."ascii"returns an indented box-drawing tree."graphviz"returns agraphviz.Digraph(with ASCII fallback if graphviz is not installed).
- Return type:¶
str or graphviz.Digraph
-
spatial_effects(draws=
None, return_posterior_samples=False, ci=0.95, mode='auto')[source]¶ Summarize posterior origin/destination/intra/network/total effects.
Wraps
_compute_spatial_effects_posterior()to produce a tidy DataFrame indexed by predictor with posterior means, credible-interval bounds, and Bayesian p-values for each effect type (origin, destination, intra, network, total). Following Thomas-Agnan & LeSage (2014, §83.5.2), when destination and origin design blocks differ the decomposition is reported separately for shocks applied to each side.- Parameters:¶
- draws : int, optional¶
Maximum number of posterior draws to use. Defaults to all.
- return_posterior_samples : bool, default False¶
If True, also return the underlying posterior-draw arrays.
- ci : float, default 0.95¶
Credible-interval coverage.
- mode : {"auto", "combined", "separate"}, default "auto"¶
Controls whether destination- and origin-side effects are summed or reported separately.
"auto"collapses to combined when the destination and origin design blocks are identical (self._symmetric_xo_xd) and reports both sides otherwise."combined"always sums;"separate"always reports both.
- Returns:¶
Long-format summary indexed by
(predictor, side, effect)wheresideis one of"combined","dest","orig".- Return type:¶
pandas.DataFrame, or (DataFrame, dict)