惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
P
Proofpoint News Feed
D
DataBreaches.Net
C
Check Point Blog
L
LangChain Blog
量子位
美团技术团队
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
V
Visual Studio Blog
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
The GitHub Blog
The GitHub Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
腾讯CDC
M
MIT News - Artificial intelligence
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Building KNN from Scratch (Because import sklearn Feels L...
Darsh Ayde · 2026-06-14 · via DEV Community

Building K-Nearest Neighbors (KNN) From Scratch

Let's be real: in a production machine learning environment, we all just import scikit-learn and call it a day. But treating algorithms like black boxes can come back to bite you when those abstractions leak. Building K-Nearest Neighbors (KNN) from scratch is a fantastic exercise to actually understand the mechanics working under the hood.

At its core, KNN relies on a surprisingly simple geometric premise: a data point probably belongs to the same category as its closest spatial neighbors. Rebuilding this classifier from the ground up forces you to tackle some critical engineering challenges, such as:

  • Computing spatial geometry efficiently
  • Managing state during the voting process
  • Handling edge cases and algorithmic ties deterministically

In this post, we'll walk through the architectural decisions behind a pure Python implementation of KNN, translating textbook math into functional code.

1. The Distance Metric

import math

def _check_length(x, y):
    """Ensure both vectors have the same length."""
    if len(x) != len(y):
        raise ValueError("Vectors must be of same length")

def euclidean_distance(x, y):
    """Compute Euclidean distance between two vectors."""
    _check_length(x, y)

    sum_of_sq = sum(
        (i - j) ** 2
        for i, j in zip(x, y)
    )

    return math.sqrt(sum_of_sq)

The Goal

Calculate spatial similarity between vectors using Euclidean distance.

How It Works

KNN is fundamentally a geometry problem. The entire algorithm hinges on quantifying exactly how far apart points are in a given space.

If we're looking at a 2D plane, Euclidean distance comes straight from the Pythagorean theorem:

d=(x1−x2)2+(y1−y2)2 d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}

In machine learning, however, we're rarely dealing with just two dimensions. Fortunately, the formula generalizes neatly to an arbitrary number of dimensions:

d(x,y)=∑i=1n(xi−yi)2 d(\mathbf{x}, \mathbf{y}) = \sqrt{ \sum_{i=1}^{n} (x_i - y_i)^2 }

Where:

  • nn is the total number of dimensions.
  • xix_i and yiy_i are the coordinates of vectors x\mathbf{x} and y\mathbf{y} along dimension ii .

In the euclidean_distance() function above, notice the generator expression inside sum(). It evaluates lazily, meaning we avoid constructing an intermediate list of squared differences in memory. This is a deliberate design choice that scales well when working with high-dimensional data.

Also, don't overlook the _check_length() guard—it is structurally critical. Comparing vectors of different dimensions is mathematically invalid. Since Python's zip() function silently truncates to the shortest iterable, omitting this check could allow the function to fail silently and return incorrect results.

2. The Voting Mechanism and Tie-Breakers

def _get_majority_vote(neighbors):
    # ... early-exit validation skipped ...

    vote_count = {}
    min_distance_per_label = {}

    for neighbor in neighbors:
        label = neighbor["label"]
        distance = neighbor["distance"]

        vote_count[label] = vote_count.get(label, 0) + 1

        min_distance_per_label[label] = min(
            distance,
            min_distance_per_label.get(label, float("inf"))
        )

    best_label = None
    best_vote = -1
    best_distance = float("inf")

    for label in vote_count:
        votes = vote_count[label]
        dist = min_distance_per_label[label]

        if votes > best_vote or (
            votes == best_vote and dist < best_distance
        ):
            best_label = label
            best_vote = votes
            best_distance = dist

    return best_label

The Goal

Tally the neighbors' labels to determine the final classification while using spatial proximity as a deterministic tie-breaker.

How It Works

Counting votes is straightforward with a hash map, but robust edge-case management is what separates a demo implementation from production-ready code.

Imagine a scenario where k=4k = 4 and your query point sits exactly halfway between two Class A neighbors and two Class B neighbors. A naive implementation might simply choose whichever label appears first. That makes the classifier non-deterministic and biased by data ordering.

To address this, the implementation maintains a secondary dictionary:

min_distance_per_label

As the algorithm iterates through the neighbors, it tracks the minimum distance observed for each class label. If a voting tie occurs,

votesA=votesB \text{votes}_A = \text{votes}_B

the algorithm chooses the class whose nearest representative is closest to the query point.

Mathematically:

arg⁡min⁡c(min⁡x∈cd(x,q)) \arg\min_{c} \left( \min_{x \in c} d(x, q) \right)

Where:

  • cc is a class label.
  • qq is the query point.
  • d(x,q)d(x, q) is the distance between a training sample and the query point.

This approach anchors tie-breaking in actual spatial proximity rather than arbitrary ordering or randomness.

3. The Orchestrator

import numpy as np

def knn_predict(training_data, labels, query_point, k):
    # ... input validation skipped ...

    distances = [
        euclidean_distance(sample, query_point)
        for sample in training_data
    ]

    nearest_idx = np.argsort(distances)[:k]

    neighbors = [
        {
            "distance": distances[i],
            "label": labels[i]
        }
        for i in nearest_idx
    ]

    return _get_majority_vote(neighbors)

The Goal

Create a controller function that computes distances, isolates the top kk candidates, and delegates classification to the voting logic.

How It Works

Although a production implementation would include comprehensive validation and optimization, the core algorithm relies on one key operation:

np.argsort(distances)[:k]

Keeping multiple arrays synchronized during sorting can quickly become messy. Rather than zipping distances and labels together, sorting them, and then unpacking them again, we sort only the distance values and retrieve the corresponding indices.

numpy.argsort() returns the indices that would sort an array. This allows us to select the nearest neighbors without mutating the original data structures.

Mathematically, we're selecting:

argsort⁡(D)1 \operatorname{argsort}(D)_{1}

where DD is the vector of computed distances.

This is a common scientific-computing pattern because it preserves the relationship between distances and labels while avoiding unnecessary data transformations.

After selecting the nearest indices, we package the neighbors into lightweight dictionaries and pass them directly to the voting mechanism.

Final Thoughts

K-Nearest Neighbors is a unique machine learning algorithm because it behaves less like a traditional parameter-learning model and more like a combination of geometric reasoning and voting heuristics.

Unlike algorithms such as linear regression or neural networks, KNN performs no explicit training. It simply stores the dataset and uses distance as a proxy for similarity during prediction.

Building algorithms from scratch is one of the fastest ways to demystify machine learning. You quickly discover that much of the perceived complexity comes from standard software engineering concerns:

  • Performance optimization
  • State management
  • Data validation
  • Numerical stability

The mathematics matters, but so does thoughtful implementation.

Further Reading

To explore more machine learning projects and software engineering content: