Project 5

Build a Nearest-Neighbor System

Compare each query with a small set of labelled reference records, keep the nearest records in a deterministic order, and preserve the evidence behind every predicted label.

  • 8 milestones
  • Optional
  • Browser workspace

Project question: Can you compare each query with a small set of reference records, keep the nearest records in a deterministic order, and explain every predicted label?

What makes this a project

This project turns a supplied distance and voting rule into a complete, inspectable system. You will validate two small tables, calculate squared distances, order reference records, select a label from explicit vote evidence, predict every query, inspect the result, and save enough information to replay the run.

The project teaches faithful implementation of supplied rules. It does not claim that nearest neighbors learn a generally good classifier, that the coordinates are a useful representation, or that a checking fraction predicts future behavior. Those questions belong to later subjects.

You will produce:

  • validated reference and query records with stable identities;
  • a deterministic neighbor trace for every query;
  • vote counts and distance sums for every candidate label;
  • one prediction record per query in source order;
  • numerical and visual checking evidence;
  • saved artifacts and a separate replay record; and
  • a short report whose claims stay within the supplied data and rules.

What you should know first

The project follows the Python path through Chapter 13. You should be able to validate files and arrays, preserve IDs through selection and sorting, calculate reductions, compare finite numbers, create plots, organize several files, save result records, and replay a deterministic run. DATA-01 and DATA-03 are useful preparation but optional. The supplied records and rules provide the local boundary if you did not complete either project.

Supplied records

The read-only files contain two coordinate values and identity information:

  • data/reference_records.csv has unique record_id, finite value_1 and value_2, and a non-empty label;
  • data/query_records.csv has unique query_id, finite value_1 and value_2, and an expected_label used only for a bounded checking report;
  • data/dataset_manifest.json records the dataset identity and schema.

Reference and query IDs use separate namespaces. Coordinate columns have the supplied comparable units. Do not add an interpretation about what a coordinate means, choose a new scale, or call an expected label a future guarantee.

Distance and neighbor rules

For one query and one reference row, calculate squared distance:

(query_value_1 - reference_value_1) ** 2
+ (query_value_2 - reference_value_2) ** 2

The square root is not needed because it would preserve the order of non-negative distances. The configuration supplies an integer k with 1 <= k <= reference_count. Sort references by smaller squared distance, then by earlier row position in the validated reference file. Return each selected record's ID, label, squared distance, and original row position.

Select the predicted label by three rules:

  1. choose the greatest count among the selected neighbors;
  2. for tied counts, choose the smallest sum of squared distances for that label's selected neighbors;
  3. for a remaining exact tie, choose the lexicographically smallest label.

Save the count and distance-sum evidence for every candidate label. A label without its neighbor and vote trace is not enough evidence.

The project workspace

project/
  README.md
  data/reference_records.csv       # supplied, read only
  data/query_records.csv           # supplied, read only
  data/dataset_manifest.json       # supplied, read only
  src/config.py                    # reader implementation
  src/data.py                      # reader implementation
  src/distance.py                  # reader implementation
  src/neighbors.py                 # reader implementation
  src/predict.py                   # reader implementation
  src/report.py                    # reader implementation
  src/main.py                      # reader implementation
  output/                          # generated artifacts
  tests/public_cases.py            # supplied, read only

Keep loading, distance, ordering, prediction, and reporting independently inspectable. Implementation review may combine files only when doing so does not weaken those boundaries.

Project milestones

Work through these in order. Each milestone produces evidence used by the next one, while project completion remains separate from lesson progress.

  1. 1Validate and inspect reference and query records

    Check schemas, identities, coordinates, labels, manifest evidence, and k before calculating any distance.

  2. 2Implement and hand-check squared distance

    Calculate one-query and all-reference distances without changing the inputs, then reproduce three supplied cases by hand.

  3. 3Find ordered neighbors for one query

    Order every reference by squared distance and original row position, then retain the first k with a complete trace.

  4. 4Implement deterministic label selection

    Choose a label by count, selected-distance sum, and lexical order while preserving the evidence for every candidate label.

  5. 5Predict every query without losing identity

    Produce one source-ordered result per query and prove that IDs, neighbors, votes, and expected labels stay aligned.

  6. 6Inspect predictions numerically and visually

    Check matched and mismatched queries and plot traceable query-to-neighbor links without treating the picture as an explanation of cause.

  7. 7Save and replay the system

    Write configuration, data identity, predictions, traces, summaries, figure, runtime, and manifest evidence, then replay it separately.

  8. 8Write and audit the report

    Explain one complete prediction, every tie rule, checking evidence, replay, and limits without claiming future performance.

Required evidence

The completed project contains:

  • neighbor_config.json;
  • predictions.csv with query, expected, predicted, and match fields;
  • neighbor_traces.json with ordered IDs, distances, and row positions;
  • vote_traces.json with per-label counts and distance sums;
  • checking_summary.json;
  • neighbors_and_queries.png;
  • run_manifest.json and a replay agreement or mismatch record; and
  • a concise report.md.

Checks should include hand-computed distances, invalid and duplicate records, wrong coordinate widths, non-finite values, invalid k, equal-distance row ties, all three voting ties, reference-order preservation, no input mutation, one result per query, neighbor/vote reconstruction, artifact read-back, and figure-data checks. Automated checks cannot decide whether an explanation is justified; the final review must do that.

Limits

This project does not teach feature scaling or selection, learned representations, probability, classification theory, generalization, train/test policy, choosing k from evaluation, cross-validation, class imbalance policy, high-dimensional distance behavior, KD trees, approximate search, vector databases, or performance benchmarking. It also does not claim that the supplied coordinate representation or checking fraction is useful beyond this bounded fixture.

Review

The final review asks whether every query keeps its identity, distances and neighbors follow the stated order, each vote can be reconstructed, the checking summary agrees with the prediction records, replay uses a separate directory, and the report separates observations from hypotheses. State what this evidence supports and what it cannot show.