All projects
// flagship, 5 case studies

Bicycle Accessibility & Equity in Greater Boston

Boston Cyclists Union UMass Center for Data Science & AI: Data Science for the Common Good, 2026

A research collaboration asking a question the city could not answer: how much of Boston’s bicycle network is actually reachable, once you account for how stressful the roads are to ride, and does that reachability fall unevenly across the people who live there?

96,232
Nodes analyzed
929,540
Residents allocated
279
Census tracts
6
Merged pull requests
// the question

Cycling infrastructure is usually assessed by what exists, miles of lane, counts of intersections. That says nothing about whether a rider can actually get anywhere without being forced onto a road they would not ride. Level of Traffic Stress captures how unpleasant a link is; combining it with network structure turns "what exists" into "what is usable".

The second half of the question is who that lands on. Once accessibility is scored at every intersection, it can be joined to Census demographics and tested for whether the shortfall is evenly distributed, which is the part an advocacy organization can take into a policy conversation.

The Data Science for the Common Good cohort seated on the atrium stairs
Data Science for the Common Good, the 2026 cohort, UMass Center for Data Science and Artificial Intelligence.

A team project. The case studies below are the parts Kinjal built and merged, each linked to its pull request. The repository also contains substantial work by others (LTS graph construction, origin-destination demand generation, road usage, corridor and one-way analysis) which is not claimed here.

The project team standing together in the atrium
The project team.
// selected technical case studies
  1. 01
    Getting people onto a graph

    Census-to-network population allocation

    Census data describes tracts. A road network describes intersections. Nothing connects the two, so before any equity question can be asked, population has to be moved onto the graph, deterministically, and without inventing or losing anyone.

    • Assigns tract population to nodes using clipped Voronoi area shares: nearest-node regions built across the street network, clipped to tract boundaries, matched with a KD-tree.
    • Computes areas in EPSG:26986 for metric accuracy while emitting EPSG:4326 for web and downstream use.
    • Conserves population by construction, with a unit test asserting it rather than an assumption that it holds.
    • Consolidated into one command-line interface covering Boston, Brookline, Cambridge, Somerville and combined Greater Boston, with the graph path required explicitly so a stale local GraphML can never be mistaken for the canonical one.
    929,540
    Population assigned
    279
    Tracts covered
    112,696
    Allocation rows
    • Python
    • GeoPandas
    • KD-tree
    • Voronoi
    • EPSG:26986
    • Census TIGER
  2. 02
    The core metric, and the machinery to run it

    Stress-aware accessibility, at city scale

    A graph algorithm measuring how much of the network is reachable from each intersection under traffic-stress-aware travel costs, compared against an ideal distance-only network. The ratio (between 0 and 1) is how much connectivity the stressful infrastructure costs you.

    • Bounded graph expansion under a configurable travel budget, handling loops, parallel edges and physical-road deduplication so one street is never counted twice.
    • Scored against a distance-only counterfactual, which is what makes the number interpretable rather than merely relative.
    • Runs in full, by shard, or as Slurm array jobs, with checkpointing, recovery of interrupted runs and shard merging.
    • Benchmarked before committing compute, and validated for exact node alignment between the pruned graph and the accessibility results.
    96,232
    Nodes scored
    277,077
    Directed edges
    0–1
    Relative accessibility
    • Python
    • NetworkX
    • Graph algorithms
    • Slurm
    • HPC
    • Checkpointing
  3. 03
    Deciding what is not really part of the network

    Network cleaning & graph quality auditing

    A real OSM-derived road graph carries disconnected fragments, driveways, parking aisles, mapping artefacts. Left in, they distort every accessibility score. Removing them by hand is neither reproducible nor defensible, so the pruning is a pipeline with an audit trail.

    • Inventories every weakly connected component and calculates its unique physical road mileage.
    • Always retains the largest component, then removes isolated nodes, components with no physical road segments, and components holding under a quarter-mile of road.
    • Writes audit files listing all components, removed components, removed nodes and a run summary, so a reviewer can check the decision, not just the outcome.
    97,850 → 96,232
    Nodes, before and after
    658
    Components removed
    0.25 mi
    Pruning threshold
    • Python
    • NetworkX
    • OSM
    • GraphML
    • Data QA
  4. 04
    Who the shortfall actually falls on

    Accessibility & demographic equity

    With population on the graph and accessibility scored at every node, the question becomes statistical: does bicycle accessibility differ systematically across demographic groups, and does that survive honest treatment of multiple testing?

    • An ACS pipeline pulling age, race and ethnicity, poverty, household income, vehicle access, renter status, disability and limited-English households, with consistency checks against assigned population.
    • Tract demographics converted to node-level features and joined to accessibility scores, producing population-weighted measures and dominant-tract assignments.
    • Population-weighted least-squares regressions at node level, with a mathematically duplicate specification identified and removed rather than quietly reported.
    • Benjamini–Hochberg FDR correction across the retained specifications, the difference between a finding and a fishing expedition.
    • A parallel tract-level model over 273 tracts giving a geographically interpretable view, retaining weighting, diagnostics, effect sizes and R².
    17
    Node-level specifications
    34
    Tract-level specifications
    FDR
    Multiple-testing correction
    • Python
    • statsmodels
    • WLS regression
    • Benjamini–Hochberg
    • Census ACS
  5. 05
    Does the result hold, and can anyone else run it?

    Sensitivity testing, mapping & reproducibility

    A finding that only exists at one set of assumptions is not a finding. This is the robustness work (re-running with the network and the spatial scale changed) plus the browser maps that let a non-technical partner explore the result, and the hardening that lets someone else reproduce it.

    • Recomputes accessibility with LTS 0 links excluded, testing whether the patterns depend on that classification.
    • Repeats the analysis across 1.5, 2.0 and 2.5-mile travel budgets, so conclusions are not an artefact of one arbitrary radius.
    • An interactive atlas layering demographics, accessibility, regression estimates, predictions and residuals, observed against expected, in the browser.
    • Regression scatterplots with prediction curves and statistical annotations, collected into an HTML gallery so findings travel beyond a coefficient table.
    • Machine-specific filesystem paths removed across the wider pipeline (destination extraction, LTS diagnostics, OD demand, route asymmetry) so the analysis runs the same locally and on UMass HPC, with no change to results.
    3
    Distance cutoffs tested
    27
    Repository tests passing
    3.10–3.12
    Python versions in CI
    • Python
    • Folium
    • GeoJSON
    • Sensitivity analysis
    • Ruff
    • GitHub Actions

Every figure above comes from the validation notes in the merged pull requests, each of which is linked from its case study.

Open the repository