In spatial data science and spatial statistics, observations recorded across geographic locations—such as crime incidents, disease outbreaks, real estate transactions, or environmental pollution measurements—are rarely distributed at random. According to Tobler’s First Law of Geography, "everything is related to everything else, but near things are more related than distant things." Spatial Cluster Analysis encompasses a set of statistical techniques designed to identify statistically significant spatial aggregations (hotspots, coldspots, or spatial outliers) that cannot be explained by chance alone.
By accounting for spatial dependence and spatial autocorrelation, these methods allow researchers and analysts to discover underlying geographic patterns, detect localized anomalies, and make informed decisions in urban planning, public health, and spatial econometrics.
1. Core Concepts: Global vs. Local Spatial Statistics
Spatial cluster analysis distinguishes between overall spatial structure and specific localized clusters:
- Global Spatial Autocorrelation (e.g., Global Moran's I, Geary's C): Measures whether the overall spatial distribution across the entire dataset exhibits clustering, dispersion, or randomness. It provides a single summary statistic for the whole region.
- Local Spatial Autocorrelation (e.g., LISA / Local Moran's I, Getis-Ord Gi*): Evaluates individual spatial units relative to their neighbors to locate specific Hotspots (high values surrounded by high values), Coldspots (low values surrounded by low values), and Spatial Outliers (high values surrounded by low, or vice versa).
- Spatial Weights Matrix (W): Defines spatial relationships and neighbor connectivity using strategies like k-nearest neighbors (KNN), distance thresholds, or contiguity (Queen/Rook).
2. Key Spatial Clustering Methods
| Method / Algorithm | Type | Primary Use Case & Characteristics |
|---|---|---|
| Local Moran's I (LISA) | Local Statistical Test | Detects localized spatial clusters (High-High, Low-Low) and spatial anomalies (High-Low, Low-High). |
| Getis-Ord Gi* | Local Statistical Test | Identifies statistically significant Hotspots and Coldspots based on Z-scores and p-values. |
| Spatial DBSCAN (ST-DBSCAN) | Density-Based ML | Clusters dense point features in physical space (or space-time) without requiring a predefined number of clusters. |
| SKATER / Max-P | Regionalization | Groups contiguous spatial polygons into larger, homogeneous regions based on attribute similarity while enforcing spatial contiguity constraints. |
3. Mathematical Formulation (Local Moran's I)
For a feature location i with attribute value xi, the Local Moran's I statistic Ii is formulated as:
Ii = [ (xi - x̄) / s² ] × ∑j wij (xj - x̄)
Where:
- x̄ is the global mean of the attribute across all spatial units.
- s² is the sample variance of the attribute.
- wij is the spatial weight between location i and location j in the spatial weights matrix W.
- A positive Ii value indicates a spatial cluster of similar values (High-High or Low-Low), whereas a negative Ii value indicates a spatial outlier (High-Low or Low-High).
4. Quick Implementation Example (Python with PySAL & esda)
Here is how to calculate Local Moran's I to detect spatial clusters using Python's pysal library suite:
import geopandas as gpd
from libpysal.weights import Queen
from esda.moran import Moran_Local
# Load a spatial GeoDataFrame containing polygon boundaries and an attribute of interest
# gdf = gpd.read_file("counties_data.geojson")
# 1. Create a spatial weights matrix using Queen contiguity
w = Queen.from_dataframe(gdf)
w.transform = 'R' # Row-standardize weights
# 2. Compute Local Moran's I for the target attribute 'incidents'
y = gdf['incidents'].values
lm = Moran_Local(y, w, seed=42)
# Extract local statistics, p-values, and cluster quadrant categories
# Quadrants: 1=High-High (Hotspot), 2=Low-High, 3=Low-Low (Coldspot), 4=High-Low
gdf['local_I'] = lm.Is
gdf['p_value'] = lm.p_sim
gdf['quadrant'] = lm.q
# Identify statistically significant Hotspots (High-High, quadrant 1, p < 0.05)
hotspots = gdf[(gdf['quadrant'] == 1) & (gdf['p_value'] < 0.05)]
print(f"Detected {len(hotspots)} statistically significant spatial hotspots.")
Key Takeaway: Spatial cluster analysis provides the necessary statistical framework to evaluate geographic patterns, allowing analysts to distinguish meaningful spatial hotspots and regional anomalies from random spatial variation by accounting for spatial autocorrelation and neighbor structures.