neighbayes.models.SARFlowSeparablePanel

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

Panel separable spatial-lag flow model with \(\rho_w = -\rho_d \rho_o\).

For each period \(t\),

\[y_t = \rho_d W_d y_t + \rho_o W_o y_t - \rho_d \rho_o W_w y_t + X_t \beta + \varepsilon_t, \qquad \varepsilon_t \sim \mathcal{N}(0, \sigma^2 I_N).\]

Under the separability restriction, \(A = I_N - \rho_d W_d - \rho_o W_o + \rho_d \rho_o W_w\) factorizes into Kronecker blocks, which enables the exact or approximated eigenvalue-based log-determinant used by this class.

Parameters:
y : array-like

Stacked panel response in shape (T, n, n), (T, n^2), or (n^2 * T,).

W : libpysal.graph.Graph or scipy.sparse / dense (n×n) matrix

Row-standardized graph on n units.

X

Stacked panel design matrix in time-first order.

T : int

Number of panel periods (must be a positive integer).

col_names : list of str, optional

Feature names for X. Inferred from a DataFrame if omitted.

k : int, optional

Number of destination/origin covariate pairs used by flow effects; inferred from columns prefixed dest_ if omitted.

model : int, default 0

Fixed-effects transform: 0 pooled, 1 pair FE, 2 time FE, 3 two-way FE.

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.

robust : bool, default False

If True, replace the Normal error with Student-t for robustness to heavy-tailed outliers. The degrees of freedom \(\nu\) are fixed at priors["nu"] (default 4, LeSage’s rval).

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.

  • rho_lower : float, default -0.999 — Lower bound of Uniform prior on rho_d and rho_o.

  • rho_upper : float, default 0.999 — Upper bound of Uniform prior on rho_d and rho_o.

  • nu : float, default 4.0 — Fixed Student-t degrees of freedom (only when robust=True).

Notes

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

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

Methods

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

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

Draw samples from the posterior via PyMC NUTS.

fitted_values()

Return fitted values at posterior mean parameters.

posterior_predictive([n_draws, random_seed])

Draw posterior-predictive samples y_rep for the full panel stack.

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, store_lambda=False, idata_kwargs=None, progressbar=True, **sample_kwargs)[source]

Draw samples from the posterior via PyMC NUTS.

Parameters:
draws : int, default 2000

Number of posterior samples per chain (after tuning).

tune : int, default 1000

Number of tuning (warm-up) steps per chain.

chains : int, default 4

Number of parallel chains.

random_seed : int, optional

Seed for reproducibility.

store_lambda : bool, default False

If True, include the high-dimensional fitted mean lambda in the stored posterior. Leaving this False reduces memory and conversion overhead for NB flow models.

idata_kwargs : dict, optional

Forwarded to pm.sample. {"log_likelihood": True} stores the pointwise log-likelihood that az.loo / az.waic / az.compare need; for SAR flow variants the captured Gaussian log-likelihood is post-processed to add the Jacobian contribution from log|I_N - rho_d W_d - rho_o W_o - rho_w W_w|. Off by default, as in PyMC: it holds one value per draw, chain, and flow.

progressbar : bool, default True

Show progress bar during sampling.

**sample_kwargs

Additional keyword arguments forwarded to pm.sample. Pass target_accept=0.95 to adjust the NUTS acceptance rate.

Return type:

arviz.InferenceData

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 the full panel stack.

Parameters:
n_draws : int, optional

Number of posterior draws to use. Defaults to all.

random_seed : int, optional

Seed for the posterior-predictive sampler.

Returns:

Array of shape (n_draws, N_flow * T) with posterior-predictive flows in time-first stacked order.

Return type:

np.ndarray

property pymc_model : pymc.model.core.Model | None[source]

Return the PyMC model object built for the most recent fit.

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.

See neighbayes.models.flow.FlowModel.spatial_effects() for the mode semantics (auto / combined / separate destination-origin sides per Thomas-Agnan & LeSage 2014, §83.5.2).

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