Skip to main content
Codex ships two reference notebooks that demonstrate real analytical workflows using the free research-tier datasets on Hugging Face. Both notebooks are licensed CC-BY-4.0, pin to the 2026-04 snapshot, and require no paid tier.

Upzoning classifier

Fine-tune DistilBERT on council meeting language to predict zoning outcomes, then benchmark against Codex’s pre-computed scores.

Civic risk map

Build an H3 choropleth of litigation risk and test whether elevated risk predicts slower permit issuance.

Prerequisites

Both notebooks require Python 3.10+ and the following core dependencies:
datasets
transformers
pandas
numpy
matplotlib
h3
plotly
scipy
The upzoning classifier additionally requires torch, accelerate, evaluate, and scikit-learn. The civic risk map additionally requires geopandas and shapely.
You do not need a paid Codex tier. Both notebooks load the 100K-record research sample directly from Hugging Face.

Upzoning classifier

Goal: Fine-tune a DistilBERT model (~66M parameters, ~10 minutes on a single GPU) on the language_signals and summary fields from Civic Intelligence to predict upzoning outcomes (approved, denied, or continued), then compare against Codex’s pre-computed upzoning_probability. Datasets used: Civic Intelligence (research tier)

Workflow

1

Load the research-tier sample

Load the Civic Intelligence dataset from Hugging Face, pinned to the 2026-04 snapshot:
from datasets import load_dataset

ds = load_dataset(
    "axiom-ai/civic-intelligence",
    revision="snapshot/2026-04",
    split="train"
)
2

Filter to zoning records

Keep only zoning_vote and rezoning_hearing records with non-null outcomes for training:
zoning = ds.filter(
    lambda r: r["document_type"] in ("zoning_vote", "rezoning_hearing")
    and r["upzoning_probability"] is not None
)
3

Build input features

Concatenate the top 30 language_signals phrases with the summary field to create a text input for the classifier:
def build_text(row):
    signals = " | ".join((row["language_signals"] or [])[:30])
    return f"signals: {signals}\nsummary: {row['summary'] or ''}"
4

Split by jurisdiction

Use a jurisdiction-based train/test split to test generalization — train on Philadelphia, Chicago, and Dallas; evaluate on San Francisco and New York:
train_jurisdictions = {"philadelphia-pa", "chicago-il", "dallas-tx"}
test_jurisdictions = {"san-francisco-ca", "new-york-ny"}
5

Fine-tune DistilBERT

Train for 3 epochs with batch size 16, learning rate 5e-5, and macro-F1 as the evaluation metric.
6

Compare against Codex scores

Evaluate your trained classifier against Codex’s pre-computed upzoning_probability using ROC-AUC on the held-out jurisdictions.

What you learn

  • How to load and filter Codex datasets from Hugging Face
  • How language_signals and summary power zoning outcome prediction
  • How Codex’s pre-computed scores compare to a custom fine-tuned model
  • How jurisdiction-based splits reveal geographic generalization gaps

Civic risk map

Goal: Build an H3-cell choropleth of civic litigation risk and test whether elevated risk predicts depressed permit-issuance velocity in the following 6 months. Datasets used: Civic Intelligence, Urban Signal Grid, Permit Signals (all research tier)

Workflow

1

Load three datasets

Load the research-tier samples for Civic Intelligence, Urban Signal Grid, and Permit Signals from Hugging Face:
from datasets import load_dataset

civic = load_dataset("axiom-ai/civic-intelligence", revision="snapshot/2026-04", split="train")
usg = load_dataset("axiom-ai/urban-signal-grid", revision="snapshot/2026-04", split="train")
permits = load_dataset("axiom-ai/permit-signals", revision="snapshot/2026-04", split="train")
2

Filter to a focus metro

Filter all three datasets to a single metro (e.g., chicago-il) for tractable analysis.
3

Aggregate risk to H3 cells

Compute a confidence-weighted mean of litigation_risk_score per h3_index from the Civic Intelligence dataset:
import pandas as pd

civic_df = civic.to_pandas()
risk_by_cell = (
    civic_df
    .groupby("h3_index")
    .apply(lambda g: (g["litigation_risk_score"] * g["confidence_score"]).sum() / g["confidence_score"].sum())
    .rename("weighted_risk")
)
4

Join to Urban Signal Grid

Join the aggregated risk scores to the Urban Signal Grid on h3_index:
usg_df = usg.to_pandas()
joined = usg_df.merge(risk_by_cell, on="h3_index", how="left")
5

Render an interactive choropleth

Materialize H3 hexagon polygons and render a Plotly choropleth colored by litigation risk score.
6

Test the risk-to-permits hypothesis

Compute permit velocity (permits issued per cell in the following 6 months) and run a Spearman correlation test against litigation risk:
from scipy.stats import spearmanr

rho, p = spearmanr(merged["weighted_risk"], merged["permit_velocity"])

What you learn

  • How all three datasets join on h3_index alone — no spatial library required
  • How to aggregate record-level scores to the H3 cell grid
  • How civic proceedings signal downstream development activity
  • How to validate Codex scores against observable permit outcomes

Key takeaway

Both notebooks demonstrate the core Codex value proposition: datasets that join by construction, carry pre-computed AI labels, and enable cross-domain analysis without custom ETL. Start with the research tier on Hugging Face and upgrade to Commercial when you need full coverage.