K-Means Segmenter
Four well-separated groups in feature space, each with its own target level. Cluster the training rows and predict a value per test row; predicting the global mean scores R-squared 0.00.
Higher is better. Scored on 16 held-out rows.
Dataset
x: feature 1 · y: feature 2
Each dot is one training row: feature 1 against feature 2, coloured by class.
What this lab teaches
Run Lloyd's algorithm to four centroids, then predict each test row with the mean training label of its nearest cluster.
Four groups in plain sight
The 36 training rows form four well-separated clouds around (0, 0.1), (0.25, 7.8), (7.6, -0.1), and (7.9, 7.9), with mean labels of roughly 2.25, 4.09, 7.92, and 9.84. The global-mean predictor scores R-squared 0.00 (the recorded baseline) and the target is 0.90.
Assignment then update
Assign every point to its nearest centroid under squared Euclidean distance, move each centroid to the mean of its assigned points, and repeat until assignments stop changing. Because both axes span about 0 to 10 and the clusters are far apart, the algorithm converges in a few iterations; an internal run reaches R-squared 0.984 on the 16 hidden rows.
Prediction is a lookup
For each test row, find the nearest training centroid and return that cluster's mean training label - never the test labels, which are not passed to predict(). The within-cluster label variation is small, so this piecewise-constant prediction explains almost all of the hidden variance.
Common pitfalls
- Seeding two centroids inside the same cloud and leaving another empty. Empty clusters divide by zero in the mean update; re-seed the empty centroid or leave it where it is.
- Returning the cluster index or the centroid coordinates instead of the cluster's mean label. The metric is R-squared against the target values, not cluster alignment.
- Stopping after one assignment pass. The first assignments depend entirely on the initial centroids, and a single round can leave a boundary in the wrong place.
Rules of the run
- Define predict(train_X, train_y, test_X) and return exactly one value per test row.
- Pure Python or numpy both run; no external data or network access.
- Return a numeric prediction for every test row.
- Cluster the training features into four groups; test labels are never passed to predict().
Hint
Run k-means on train_X with k=4, then return each test point's nearest-cluster mean training label.
Reference solution
Revealing doesn't affect your record — but try the hint first.