liveBook · Manning

K-means clustering

As explained in Classic Computer Science Problems in Swift: Essential techniques for practicing programmers

K-means clustering is an iterative unsupervised learning algorithm that partitions data points into a predefined number of clusters by repeatedly assigning points to their nearest centroid and recomputing the centroids.

K-means groups data points into a chosen number of clusters. It assigns each point to its nearest cluster center, called a centroid, then moves each centroid to the mean of its assigned points. Repeating those steps reveals groupings that may not be obvious from looking at the data. section 6.2

A basic run follows this cycle:

  • Normalize dimensions so differences in scale do not cause larger-valued dimensions to dominate. section 6.2
  • Choose k, the number of clusters, and initialize their centroids randomly within the data’s range. section 6.2
  • Assign each point to its nearest centroid, then recompute each centroid from the mean of its assigned points. section 6.2
  • Repeat until centroids stop moving or a set iteration limit is reached. section 6.2

A Swift implementation can represent points through a shared interface that exposes their dimensions and distance. Normalization matters because otherwise a dimension with larger differences can dominate the clustering. section 6.1 section 6.2

Governors by age and longitude

With k set to 2, the algorithm groups state governors using longitude and age. One run finds a cluster of western states whose governors are relatively older. Random starting centroids can produce different results, and the pattern suggests correlation—not a conclusive explanation. section 6.3

Choosing k and useful starting centroids can take trial and error. Outliers may produce odd clusters, and the basic method can become impractical with many points and dimensions. Alternatives and extensions include k-means++, sampling, k-medians, and k-medoids. section 6.4

    public func run(maxIterations: UInt = 100) -> [Cluster] {
        for iteration in 0..<maxIterations {
            clusters.forEach{ $0.points.removeAll() } // clear all clusters
            assignClusters() // find clusters each is closest to - assign
            let lastCentroids = centroids // record centroids
            generateCentroids() // find new centroids
            if lastCentroids == centroids { // have centroids moved?
                print("Converged after \(iteration) iterations.")
                return clusters // they haven't moved, so we've converged
            }
        }

        return clusters
    }
}

The Swift run loop clears assignments, recalculates centroids, and returns when they stop changing. section 6.2

How Classic Computer Science Problems in Swift: Essential techniques for practicing programmers covers it

How deep it goes
Works through normalization, random initialization, assignment, centroid updates, and stopping, then notes extensions without detailing them.
Examples
Demonstrates three-dimensional points and clusters state governors by longitude and age.
What it assumes
Assumes rudimentary familiarity with means and standard deviations while defining point dimensions and distance.
What you can do after
Build it from scratch in Swift by defining multidimensional points and iterating nearest-centroid assignments and mean updates.
How it connects
Connects k-means to normalization, z-scores, Euclidean distance, k-means++, k-medians, and k-medoids.

Also explained in

Compare how 7 books explain K-means clustering →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Classic Computer Science Problems in Swift: Essential techniques for practicing programmers. The section links point to the parts of the book it draws on.