analyze_spatial_diagnostics

analyze_spatial_diagnostics(
    df,
    outcome=None,
    covariates=None,
    *,
    gdf,
    w=None,
    period=None,
    entity=None,
    time=None,
    fixed_effects=None,
    alpha=0.05,
)

Run the LM specification tests on OLS residuals and recommend a spatial model.

Estimates the non-spatial OLS benchmark, computes Moran’s I on its residuals and the five Lagrange-multiplier tests (LM lag / LM error, their robust forms, and LM SARMA), then applies the Anselin-Florax decision rule: no LM rejection keeps OLS; otherwise the significant robust test picks the lag or error model, and when both robust tests reject the larger statistic wins (with a pointer to the spatial Durbin model, which nests both channels).

Parameters

Name Type Description Default
df pd.DataFrame Long panel (or cross-section) holding the outcome and covariates per entity. required
outcome str | None Dependent variable and regressors; default to the roles declared via :func:geometrics.set_roles. None
covariates str | None Dependent variable and regressors; default to the roles declared via :func:geometrics.set_roles. None
gdf gpd.GeoDataFrame Entity geometry carrying the same entity ids as df. required
w W | None libpysal weights aligned to the gdf ids; None builds the default weights with a :class:~geometrics.GeometricsWarning. None
period Any Period to test; None uses the latest period and records a note. None
entity str | None Panel identifiers; default to the ids declared via :func:geometrics.set_panel. None
time str | None Panel identifiers; default to the ids declared via :func:geometrics.set_panel. None
fixed_effects str | None Categorical column expanded to drop_first dummies in the OLS design. None
alpha float Significance level for the decision rule. 0.05

Returns

Name Type Description
SpatialDiagnosticsResult Frozen result with one row per test (test, statistic, df, p), the rendered table, the residual Moran’s I, the recommendation and its reasoning, the fitted OLS benchmark and w_spec.

Raises

Name Type Description
KeyError If a requested column is not in df.
TypeError If the outcome or a covariate is not numeric.
ValueError If alpha is not in (0, 1), the period is unknown, or the aligned cross-section is too small or degenerate.

Examples

Diagnostics on a small constructed lattice:

import geopandas as gpd
import numpy as np
import pandas as pd
from shapely.geometry import box

from geometrics.spatial_models import analyze_spatial_diagnostics
from geometrics.weights import make_weights

cells = [box(i % 4, i // 4, i % 4 + 1, i // 4 + 1) for i in range(16)]
gdf = gpd.GeoDataFrame(
    {"id": [f"r{i}" for i in range(16)]}, geometry=cells, crs="EPSG:4326"
)
rng = np.random.default_rng(0)
df = pd.DataFrame({"id": gdf["id"], "x": rng.normal(size=16)})
df["y"] = 2.0 * df["x"] + rng.normal(scale=0.1, size=16)
res = analyze_spatial_diagnostics(df, "y", ["x"], gdf=gdf, w=make_weights(gdf), entity="id")
print(res.recommendation)