NBA Analytics Assistant
An offline Python analytics system that maps supported basketball questions to validated pandas tools, calculates auditable team statistics and returns structured answers through a deterministic, modular pipeline.
- Dataset
- 14,746 team game rows · 7,373 games
- Stack
- Python · pandas · pytest
- Capabilities
- 8 registered analytical tools
- Status
- Completed · 2026
Overview
The NBA Analytics Assistant is a deterministic analytical system for answering a controlled set of natural language style questions about team performance. It combines a structured data pipeline with a rule based query layer, allowing a user to request common statistics without giving the language layer permission to calculate or invent an answer.
Every reported statistic is produced by a registered pandas tool operating on a validated analytical view. The parser identifies a candidate request, the validator resolves and checks its arguments, the registry controls execution, and the formatter presents the completed result. This keeps interpretation, calculation and presentation separate and independently testable.
Problem framing
Structured sports data is easy to query when the user already knows the schema and the required dataframe operations. It is less accessible when the starting point is a question such as how a team has performed recently, what it allows defensively or how two teams compare over equivalent samples.
The engineering challenge was to make those questions convenient without turning the system into unrestricted conversation. Ambiguous team names, unsupported requests and invalid windows must fail clearly, while valid requests must always resolve to the same calculation over the same data.
Dataset structure
- Team game rows
- 14,746
- Games
- 7,373
- Raw schema
- 125
- Clean model
- 17
- Franchises
- 30
- Special teams
- 3
One team perspective per row
Two team rows per game
Columns before clean modelling
Validated analytical fields
Canonical NBA teams
Flagged and excluded from franchise tools
Each game normally appears twice, once from each team's perspective. A one to one pairing on the game identifier derives the opponent name and verifies that each row's points allowed match the paired team's points scored. Chronological sorting makes recent game windows reproducible, while the home and away field supports venue specific analysis where the selected tool permits it.
Architecture
Step 01
User query
Supported question
Step 02
Parser
Intent · raw arguments
Step 03
Candidate intent
Structured request
Step 04
Validator
Resolve · reject · clarify
Step 05
Closed registry
Controlled dispatch
Step 06
Pandas tool
Deterministic calculation
Step 07
Structured result
Data · errors · warnings
Step 08
Formatter
User facing answer
The closed registry is the only execution path. A request reaches an analytical tool only after parsing and validation succeed, and the formatter receives an already calculated result. New capabilities can be added as explicit registered tools without allowing arbitrary code execution or moving calculations into the language layer.
Data validation and clean model
- The exported index column is removed before the raw schema is validated.
- Required identifiers, dates, team fields and scoring columns are checked before transformation.
- Every game must contain exactly one home row and one away row.
- Opponent identity is derived through one to one game pairing rather than string assumptions.
- Points, point differential and paired opponent scoring are checked for consistency.
- Core analytical fields must be complete; missingness is profiled rather than silently hidden.
- Special teams are flagged explicitly and excluded from standard franchise analysis.
- The clean view is sorted deterministically and validated again after transformation.
Analytical tools
The assistant supports eight bounded analytical families. Each has a declared argument contract and returns the same structured result shape.
Recent game windows are applied after chronological ordering. Home and away filters are supported for the relevant single team tools and for profile comparison, while unsupported combinations are rejected rather than interpreted loosely.
Query execution example
For a request such as Compare Warriors and Celtics over the last 10 games, the parser proposes the comparison tool and preserves the two team surfaces and window. The validator resolves both names to canonical franchises, checks that the teams differ and validates the window. The registry then dispatches the request to the comparison tool, which computes equivalent team profiles from the clean view. The formatter presents the returned record, scoring and pace adjusted ratings without recalculating them.
A vague request such as Who is better? is outside the supported analytical contract. It returns a structured unsupported response instead of a prediction or an invented basketball opinion.
Testing strategy
Unit and parameterised tests exercise data validation, team resolution, parsing, argument validation, registry schemas, analytical tools, result contracts and formatting across normal and edge case inputs.
Integration and end to end tests execute the real chain from query through validation, dispatch, calculation and formatting. They also verify that parser or validation failures cannot trigger a tool.
Independent oracle tests recompute expected statistics directly from the source data rather than calling the same production helpers. This tests numerical correctness as well as code behaviour.
Adversarial and fuzz coverage checks malformed, ambiguous and unsupported input. Import and scope guards also protect the architectural boundaries and keep calculation code out of the assistant and presentation layers.
Engineering decisions and alternatives
Pandas keeps the analysis transparent and reproducible for a fixed, moderately sized dataset. A database or warehouse would become more appropriate for persistent multi user workloads, substantially larger data or continuously arriving records.
A rule based parser is deterministic, offline and straightforward to test against the supported question families. It trades unrestricted language flexibility for predictable behaviour. An optional LLM interpretation layer could be added later, but it would still need to pass through the same validator and closed registry.
Explicit tool registration prevents arbitrary execution and gives every capability a visible schema, validation contract and test surface. Extension means registering another bounded analytical tool rather than widening the assistant's authority.
The command line interface keeps attention on the analytics and system boundaries. A future web interface could reuse the same runtime and structured results without changing how statistics are calculated.
Limitations
- The system uses a fixed offline dataset and does not retrieve live game data.
- It describes historical performance and does not predict outcomes.
- It does not provide betting recommendations or market analysis.
- It supports eight defined question families rather than unrestricted conversation.
- The available interface is a CLI, not a deployed public web application.
- Some field definitions and missingness behaviour are specific to the supplied dataset.
Future improvements
- Add validated shot location and league relative team profiles.
- Separate shot selection from conversion analysis where the data supports it.
- Expose the existing runtime through a thin web interface.
- Add optional LLM assisted interpretation behind the unchanged validator and registry.
- Introduce live data only with explicit freshness, lineage and monitoring controls.
Technical evidence
The completed implementation includes the validated data model, eight pandas tools, deterministic query parsing, team canonicalisation, a closed dispatch registry, structured result contracts, response formatting, a reusable runtime, CLI output and extensive offline pytest coverage across numerical correctness, component boundaries, full query execution and safe failure.