neighbayes.models.SEMFlowSeparable

class neighbayes.models.SEMFlowSeparable(y, X, W, **kwargs)[source]

Bayesian separable spatial-error flow model with \(\lambda_w = -\lambda_d \lambda_o\).

Spatial-error analogue of SARFlowSeparable. The separability constraint reduces \(\log|B|\) to the eigenvalue / Chebyshev factored form

\[\log|B| = n \log|I_n - \lambda_d W| + n \log|I_n - \lambda_o W|\]

enabling \(O(n)\) log-determinant evaluation per draw. All other properties (no \(X\)-mediated spillovers, closed-form effects, etc.) are identical to SEMFlow.

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.

k : int, optional

Number of regional attribute columns. Inferred from dest_*/orig_* column names when the standard LeSage layout is used.

logdet_method : {"eigenvalue", "chebyshev", "cheb_cholesky", "aaa", "cheb_stochastic"} or None, default None

None auto-selects (aaa for directed W, cheb_cholesky for symmetric, eigenvalue for small n). Method for the Kronecker-factored log-determinant.

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 for beta.

  • beta_sigma : float, default 1e6 — Normal prior std for beta.

  • sigma_sigma : float, default 10.0 — HalfNormal prior std for sigma.

  • lam_lower : float, default -0.999 — Lower bound of Uniform prior on lam_d and lam_o.

  • lam_upper : float, default 0.999 — Upper bound of Uniform prior on lam_d and lam_o.

Notes

The restrict_positive argument inherited from FlowModel has no effect on this class — separable variants always use Uniform priors on the individual \(\\lambda\) components.

__init__(y, X, W, **kwargs)[source]

Methods

__init__(y, X, W, **kwargs)

fit([draws, tune, chains, random_seed, ...])

Sample the SEM-flow posterior.

fitted_values()

Return fitted values at posterior mean parameters.

posterior_predictive([n_draws, random_seed])

Draw posterior-predictive samples y_rep.

residuals()

Return residuals y - fitted_values.

spatial_diagnostics()

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

inference_data

Return the ArviZ InferenceData from the most recent fit.

pymc_model

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 separable logdet_method) routes to the PyMC/NUTS path instead.

Parameters:
idata_kwargs : dict, optional

{"log_likelihood": True} stores the pointwise log-likelihood (one value per draw, chain, and flow) for az.loo / az.waic. Off by default, as in PyMC.

fitted_values()[source]

Return fitted values at posterior mean parameters.

Returns:

Posterior-mean fitted values (on the model’s native scale; fixed-effects-transformed for panel models).

Return type:

np.ndarray

property inference_data : arviz.data.inference_data.InferenceData | None[source]

Return the ArviZ InferenceData from the most recent fit.

Returns:

The inference data object, or None if the model has not been fit yet.

Return type:

arviz.InferenceData or None

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_rep from the implied data-generating process by solving the sparse system A(rho) y_rep = X β + ε (Gaussian) or y_rep ~ NegBin(exp(A^{-1} X β), α) (NB variants).

Parameters:
n_draws : int, optional

Number of posterior draws to use. Defaults to all available.

random_seed : int, optional

Seed for the posterior-predictive sampler.

Returns:

Array of shape (n_draws, N) with posterior-predictive flows.

Return type:

np.ndarray

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 logp and the prior under the same model definition used by the NUTS path.

Returns:

The model object used by fit(), or None if the instance has not been fit yet.

Return type:

pymc.Model or None

residuals()[source]

Return residuals y - fitted_values.

Returns:

Residual vector y - fitted_values on the same scale as fitted_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 matrix W to 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) and attrs["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 W was supplied.

See also

spatial_diagnostics_decision

Model-selection decision based on the test results.

spatial_effects

Posterior 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 a graphviz.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) where side is one of "combined", "dest", "orig".

Return type:

pandas.DataFrame, or (DataFrame, dict)

summary(var_names=None, **kwargs)[source]

Return posterior summary table.

Parameters:
var_names : list, optional

Variable names to include in the summary.

**kwargs

Additional arguments passed to arviz.summary().

Returns:

Posterior summary statistics.

Return type:

pandas.DataFrame