Interactive clustering playground

K-Means clustering visualization

Watch K-Means alternate between assigning points and moving centroids. Add observations, change the number of clusters, and inspect inertia one iteration at a time.

Free to useNo upload or sign-inRuns entirely in your browser
Live K-Means modelPowered by @kanaries/ml
Iteration0 / 2
Inertia (SSE)57.84
Library delta0.0e+0

Lloyd iterations: assignments and moving centroids

Feature 1Feature 2
Cluster 1Cluster 2Cluster 3

Inertia across iterations

Implementation check

The animation records transparent Lloyd assignment/update steps. A real @kanaries/ml KMeans model is also fit with the identical initial centers. Final centroid difference: 0.000e+0; library inertia: 22.727.

The moons preset demonstrates a limitation: centroid-based Voronoi regions cannot follow arbitrary curved clusters.

Fit K-Means in JavaScript or Python

import { Clusters } from '@kanaries/ml';

const model = new Clusters.KMeans(
  3,       // number of clusters
  1e-4,    // convergence tolerance
  undefined,
  100,     // maximum iterations
  42,      // random seed
  10       // k-means++ restarts
);

const labels = model.fitPredict(X);
console.log(model.getCentroids());
console.log(model.getInertia());

What K-Means clustering does

K-Means partitions unlabeled observations into a chosen number of groups. Each group is represented by a centroid, the coordinate-wise mean of its members. The algorithm seeks a partition with small within-cluster squared distances, formalized as inertia or within-cluster sum of squares. It is one of the most widely used baselines for exploratory segmentation.

Typical applications include grouping customers by behavior, compressing image colors, organizing documents after embedding, initializing other models, and summarizing a large set with representative centers. K-Means is fast and easy to interpret when its geometric assumptions fit the data, but the simplicity can also conceal important limitations.

An interactive K-Means visualization in JavaScript

The playground records each Lloyd iteration: assign every point to the nearest center, recompute centers from assigned points, and repeat. Select a preset, change k, add observations, or advance one iteration at a time. Colors show current assignments and the large cross-marked circles show centroids.

The visible history is computed explicitly so every transition can be inspected. Alongside it, the page fits Clusters.KMeans from @kanaries/ml with the same initial centers. The displayed centroid delta checks that the educational steps and production library converge to the same result. All fitting happens locally in the browser.

Assignment and centroid update steps

During assignment, each observation joins the centroid with the smallest squared Euclidean distance. This divides the plane into Voronoi regions with straight boundaries. During update, each centroid moves to the mean of its new members. That mean is the point minimizing the sum of squared distances for a fixed assignment, so the objective cannot increase after an update.

These alternating improvements eventually stabilize, but they guarantee only a local optimum. Reset the visualization to see deterministic farthest-first seeds used for clarity. Production K-Means commonly uses k-means++, which spreads initial centers probabilistically, then repeats fitting several times and retains the lowest-inertia run.

Choosing k without fooling yourself

The algorithm cannot discover how many groups you intended; k is an input. Inertia always falls or stays equal as k grows, reaching zero when every distinct point can become a center. Therefore, selecting the model with the smallest raw inertia would simply favor the largest allowed k.

An elbow plot looks for diminishing improvements, while the silhouette score compares cohesion with separation. Stability across resamples or initializations is another useful signal. Most importantly, clusters should support a real decision. A mathematically tidy partition can be useless when it does not align with actionable differences or when sensitive attributes create harmful segments.

Assumptions revealed by the presets

The blobs preset matches K-Means well: groups are compact, separated, and roughly spherical. The moons preset violates that shape assumption. Even when two curved bands are visually obvious, nearest-centroid regions stay convex and cut across them. Density-based or graph-based clustering is often a better fit for such geometry.

The uneven preset combines different cluster sizes and spreads. Squared distance gives faraway observations substantial influence, and a large diffuse group may be divided while small groups are merged. Outliers can pull means dramatically because a centroid is not a robust statistic. Scaling matters too: high-range features dominate distance unless units are standardized or deliberately weighted.

JavaScript K-Means and scikit-learn

The code comparison uses matching concepts: number of clusters, tolerance, maximum iterations, random seed, and multiple initializations. The JavaScript estimator exposes fitPredict, getCentroids, and getInertia; scikit-learn provides the analogous fitted attributes. Small differences can arise from initialization sequences, tie handling, or stopping rules, so compare objective quality and aligned centers rather than raw label numbers.

Read the K-Means JavaScript API guide for detailed options. Use the PCA visualization to inspect high-dimensional structure before clustering, or compare this unsupervised centroid rule with labeled voting in the KNN visualization.

A practical clustering workflow

Define an observation and feature set that matches the decision the clusters will support. Remove identifiers and leakage, handle missing values, and scale features according to meaningful differences. Fit several seeds for each candidate k, then compare inertia, silhouette, stability, cluster sizes, and sensitivity to outliers. Visualize more than a single convenient projection, because a two-dimensional view can hide separation or invent apparent overlap.

After selecting a solution, profile clusters using variables that were not allowed to dominate fitting. Give each group a descriptive interpretation, but avoid treating an algorithmic assignment as a natural or permanent identity. Test whether the segmentation changes an outcome through a controlled intervention. In deployment, store preprocessing and centers together, assign new observations with the same distance rule, and monitor feature drift, centroid distance, and cluster proportions. A surge in faraway points can mean the model no longer represents the population. Retraining should repeat validation rather than silently replacing centers, especially when cluster IDs drive customer experiences or operational policies.

Frequently asked questions

Questions about k-means clustering visualization

How does K-Means clustering work?

K-Means alternates two steps: assign each observation to its nearest centroid, then replace each centroid with the mean of its assigned observations. It stops when centers stabilize, inertia changes very little, or the iteration limit is reached.

What does k mean in K-Means?

k is the number of clusters and centroids the algorithm must produce. It is selected before fitting. Domain knowledge, silhouette analysis, stability, and an elbow plot of inertia can inform the choice.

What is inertia?

Inertia is the sum of squared distances from observations to their assigned centroids. Lloyd updates never increase it, but a lower value is automatic when k grows and does not by itself prove that clusters are meaningful.

Why can K-Means return different results?

Its objective has local optima, so different initial centers can lead to different partitions. K-means++ initialization, multiple restarts, and a fixed random seed improve reliability and reproducibility.

When is K-Means a poor choice?

K-Means struggles with curved, non-spherical, differently dense, or heavily outlier-contaminated groups. The moons and uneven presets make these assumptions visible.

Powered by @kanaries/ml — the scikit-learn-style ML library for JavaScriptnpmGitHub