ML Study Hub

Home / MLP / Week 12

Week 12 · Unsupervised learning in sklearn

Official syllabus line: Unsupervised learning
About 90 minEnd Term material (see exam radar)BSCS2008 · Ashish Tendulkar
Before you start: MLP weeks 1 and 2 (pipelines, scaling). MLT weeks 1 to 4 (PCA, k-means, GMM and EM) for the theory.
Watch first: the animated story of this weekAbout 1-2 minutes of real 3D animation with a friendly voice. Pause any time.
Read the words of the video
  1. Imagine a huge box of mixed-up buttons, with no labels on them. Nobody tells you how they should be grouped. Can a computer still sort them out? Yes! Unsupervised learning helps computers find patterns and structures in data all on their own, just like finding groups of similar buttons.
  2. Unsupervised learning has three main jobs. First, it sorts data into groups, like using `KMeans` for round piles or `DBSCAN` for any shape. Second, it simplifies descriptions using fewer numbers with `PCA`. Finally, it helps us judge if our grouping is good, using tools like the "elbow" of a curve or the "silhouette score."
  3. Let's see an example with DBSCAN. Imagine we have seven data points, and their labels after clustering are 0, 0, 1, 1, minus one, 0, and 1. How many real groups did we find? We have two clear clusters, labeled 0 and 1. The point labeled minus one is considered noise, meaning it doesn't belong to any cluster.
  4. For exams, remember: inertia always drops, so use the "elbow" or "silhouette score" to pick the best number of groups. A minus one label in DBSCAN means noise, not a cluster. PCA doesn't scale data for you, always scale first! Keep practicing, you're becoming a master of finding hidden patterns in data!

The one-minute story

Think of it like this

Imagine a huge box of mixed-up buttons with no labels. Nobody tells you the groups. Can the computer still sort them? Unsupervised learning says yes: look for structure on your own.

Three jobs, three tools:

  1. Sort into piles: KMeans (round piles, you pick how many), DBSCAN (any shape, it finds the number itself and flags loners as noise), GaussianMixture (soft, overlapping piles with probabilities).
  2. Describe each item with fewer numbers: PCA (keep the directions of biggest spread).
  3. Judge the answer when there is no answer key: the elbow of the inertia curve, the silhouette score, and the BIC for mixtures.

It is the practice partner of MLT weeks 1 to 4 and MLF week 6.

Tip

A note on where the numbers come from. The scikit-learn clustering and mixture modules would not load on the PC used to build this course, because of a Windows Application Control policy (we did not try to bypass it). So the KMeans, DBSCAN and Gaussian-mixture figures below were produced with careful NumPy re-implementations of the same algorithms on the same data, with real scikit-learn used for PCA and the metrics. The solutions (centres, inertia, silhouette, BIC) do not depend on the implementation for well-separated data; the iteration counts may differ by a few. On your own computer the scikit-learn code shown will run and should agree.

By the end of this week you can:

  • run KMeans, read cluster_centers_, labels_, inertia_, and choose kk with the elbow and silhouette;
  • explain when DBSCAN beats k-means and what eps, min_samples and the label −1-1 mean;
  • fit GaussianMixture, get soft assignments with predict_proba, and choose components with bic;
  • apply PCA: n_components, explained_variance_ratio_, inverse_transform, and choosing the number of components.

Words you need

Words you need
  • Inertia - the k-means objective: the total squared distance from each point to its centre. Smaller is tighter.
  • Elbow - the bend in the inertia-vs-kk curve, after which extra clusters add little.
  • Silhouette score - from −1-1 to +1+1: how much closer a point is to its own cluster than to the next nearest. Higher is better.
  • Core point / noise (DBSCAN) - a point with many close neighbours / a point belonging to no cluster (label −1-1).
  • BIC - a score that rewards fit but punishes extra parameters; lower is better.
  • Explained variance ratio - the share of total variance each principal component captures.

Idea 1: KMeans

from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, n_init=10, random_state=0).fit(X)     # X: scaled features
km.labels_            # the cluster of each training point, shape (n,)
km.cluster_centers_   # the centroids, shape (3, n_features)
km.inertia_           # sum of squared distances to the nearest centre
km.predict(new_X)     # nearest-centre label for new points
km.transform(X)       # distances to every centre, shape (n, 3)

Defaults worth knowing: n_clusters=8, init="k-means++" (smart seeding, MLT week 3), max_iter=300, tol=1e-4. n_init (the number of restarts, keeping the best) was 10 in older versions and is "auto" in recent ones; set it explicitly to avoid surprises. random_state makes the result repeatable. Scale your features first: k-means uses distances. KMeans has no partial_fit; MiniBatchKMeans does (for huge data).

fit_predict(X) fits and returns the labels in one call. inertia_ equals ∑i∥xi−μzi∥2\sum_i\|\mathbf x_i-\boldsymbol\mu_{z_i}\|^2 (we checked it by hand).

Choosing kk

We made 300 points from 3 blobs. The inertia for k=1,…,6k=1,\dots,6:

kk123456
inertia185533190465406353302

It collapses until k=3k=3, then barely moves: the elbow is at k=3k=3. (Inertia always falls as kk rises, so you cannot just pick the smallest.) The silhouette score gives a second opinion: 0.753,  0.811,  0.659,  0.479,  0.3200.753,\;\mathbf{0.811},\;0.659,\;0.479,\;0.320 for k=2,…,6k=2,\dots,6: best at k=3k=3 again. Use silhouette_score(X, km.labels_) (needs k≥2k\ge2).

At k=3k=3 the clusters are exactly the three blobs (100 points each, adjusted Rand index =1.0=1.0 against the truth). The centres were about (−8.54, 5.57)(-8.54,\,5.57), (−1.26, 4.39)(-1.26,\,4.39) and (9.62, 0.56)(9.62,\,0.56).

Where k-means fails

K-means draws round, equal-sized clusters (it assigns by distance to a centre). On the "two moons" data (300 points, two interleaved crescents) it cuts straight across both (adjusted Rand index only 0.23). It is also sensitive to outliers and needs kk in advance.

Idea 2: DBSCAN

from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.2, min_samples=5).fit(X)       # defaults: eps=0.5, min_samples=5
db.labels_                                         # cluster ids; -1 means NOISE
db.core_sample_indices_

The idea: a point is a core point if at least min_samples points (itself included) lie within distance eps of it. Clusters are chains of core points and their neighbours; points reachable from no core point are noise (label −1-1).

  • No n_clusters: DBSCAN finds the number itself.
  • Finds arbitrarily shaped clusters: on the moons it recovered both crescents perfectly (adjusted Rand index 1.0, 0 noise points) where k-means failed.
  • Handles outliers by labelling them −1-1.
  • Weak points: needs a sensible eps (a global density), struggles when clusters have very different densities, and it has no predict (it cannot label new points directly).

Idea 3: GaussianMixture

from sklearn.mixture import GaussianMixture
gm = GaussianMixture(n_components=3, covariance_type="full", n_init=3, random_state=0).fit(X)
gm.weights_       # mixing weights pi_k (sum to 1): about 0.33 each here
gm.means_         # the component means (same as the three blobs)
gm.covariances_   # one covariance per component
gm.predict(X)           # hard label: the most probable component
gm.predict_proba(X)     # SOFT assignments (responsibilities): each row sums to 1
gm.score_samples(X)     # log-likelihood of each point
gm.bic(X), gm.aic(X)

This is exactly the EM algorithm of MLT week 4. Defaults: n_components=1, covariance_type="full" (others: "tied", "diag", "spherical"). A point deep inside one blob has responsibilities like [0, 0, 1][0,\,0,\,1]; a point between two blobs would show a split such as [0.5, 0.5, 0][0.5,\,0.5,\,0].

Parameter count (full covariance, d=2d=2, K=3K=3): K(d+d(d+1)2)+(K−1)=3(2+3)+2=17K\big(d+\frac{d(d+1)}2\big)+(K-1)=3(2+3)+2=\mathbf{17}, which is what _n_parameters() reports.

Choosing the number of components with BIC (lower is better):

KK12345
BIC29312569230323282357

The minimum is at K=3K=3: the same answer as the elbow and the silhouette. BIC = −2ln⁡L+(#params)ln⁡n-2\ln L+(\#\text{params})\ln n: more components always raise the likelihood but also the penalty.

GMM vs k-means: k-means = hard assignment, equal round clusters; GMM = soft assignment, clusters can be elliptical and differently sized, and it is a generative model (gm.sample(n) draws new points).

Idea 4: PCA

from sklearn.decomposition import PCA
pca = PCA(n_components=2).fit(X)        # centres the data for you, but does NOT scale it
Z = pca.transform(X)                      # the new coordinates, shape (n, 2)
pca.components_                           # the principal directions, shape (2, n_features)
pca.explained_variance_ratio_             # share of variance per component
pca.inverse_transform(Z)                  # back to the original space (an approximation)

On the digits data (1797 images, 64 pixels):

  • The first two components explain only 28.5% of the variance (0.15 and 0.14), the first ten 73.8%.
  • PCA(n_components=0.95) (a number between 0 and 1) keeps as many components as needed to reach 95% of the variance: it chose 29 components, compressing 64 numbers to 29 with little loss.
  • Reconstruction error (mean squared error between the original and inverse_transform): 13.4 with 2 components, 0.77 with 30. More components, smaller error: exactly the "discarded eigenvalues" of MLT week 1.
  • The explained variances add up to the total variance (1202.15 for the digits), as the theory says.

To plot the cumulative variance: np.cumsum(pca.explained_variance_ratio_) and pick the "elbow" or the 95% mark.

Other facts:

  • PCA subtracts the mean for you but does not standardise: do that first when features have different units.
  • IncrementalPCA has partial_fit for huge data; KernelPCA(kernel="rbf") for curved structure; n_components="mle" guesses the dimension.
  • Use PCA inside a pipeline before a classifier to reduce dimensions and speed up training or reduce noise; for 2-D pictures of high-dimensional data you can also use t-SNE (visualisation only).

Solved examples

Solved example: 1. Read the elbow

Question. Inertias for k=1,…,5k=1,\dots,5 are 900, 400, 120, 100, 90900,\,400,\,120,\,100,\,90. Which kk?

Solution. The drop is huge up to k=3k=3 (400→120400\to120) and tiny after (120→100→90120\to100\to90): the elbow is k=3k=3.

Solved example: 2. Which algorithm?

Question. (a) Crescent-shaped groups plus a few stray points. (b) Customer groups where each person may partly belong to two groups. (c) 5 million points to cluster in k=10k=10 round groups, data arriving in chunks.

Solution. (a) DBSCAN (arbitrary shapes, labels strays as noise). (b) GaussianMixture (soft memberships via predict_proba). (c) MiniBatchKMeans with partial_fit.

Solved example: 3. How many components?

Question. Explained variance ratios are [0.50, 0.25, 0.12, 0.08, 0.05][0.50,\,0.25,\,0.12,\,0.08,\,0.05]. How many components reach at least 90%? What does PCA(n_components=0.9) choose?

Solution. Cumulative: 0.50, 0.75, 0.87, 0.95, 1.000.50,\,0.75,\,0.87,\,0.95,\,1.00. The first to reach ≥0.90\ge0.90 is the 4th, so 4 components, and PCA(n_components=0.9) gives n_components_ == 4.

Your turn

Your turn: 1. Inertia by hand

Points on a line 1, 2, 6, 71,\,2,\,6,\,7 with two clusters {1,2}\{1,2\} and {6,7}\{6,7\}. Give cluster_centers_ and inertia_.

Need a hint?

Cluster means, then squared distances.

Show the full solution

Centres 1.51.5 and 6.56.5. Inertia =0.25+0.25+0.25+0.25=1=0.25+0.25+0.25+0.25=\mathbf1.

Your turn: 2. DBSCAN labels

db.labels_ is [0, 0, 1, 1, -1, 0, 1]. How many clusters and how many noise points?

Need a hint?

−1-1 is not a cluster.

Show the full solution

2 clusters (labels 0 and 1) and 1 noise point (the −1-1).

Your turn: 3. Soft or hard

gm.predict_proba(x) returns [0.7, 0.2, 0.1]. What does gm.predict(x) return? Is k-means able to give the 0.7?

Need a hint?

predict takes the largest.

Show the full solution

Component 0. K-means only gives a hard label; the probabilities are a Gaussian-mixture feature.

Your turn: 4. PCA numbers

The 3 eigenvalues of the covariance matrix are 6, 3, 16,\,3,\,1. What are explained_variance_ratio_ and the 2-component reconstruction error?

Need a hint?

Ratios divide by the total 10; error is the discarded part.

Show the full solution

Ratios [0.6, 0.3, 0.1][0.6,\,0.3,\,0.1]. Keeping 2 components leaves out the eigenvalue 11: reconstruction error =1=1 (and 90% variance explained).

Your turn: 5. Which to scale?

Should you standardise features before KMeans? Before PCA? Before a decision tree?

Need a hint?

Distance-based or variance-based?

Show the full solution

Yes for KMeans (distances), yes for PCA (variance-driven; otherwise big-unit features dominate), no for a decision tree.

Exam radar

Exam radar

In MLP Quiz 1 summaries the unsupervised ideas are lighter, but "which algorithm / sklearn object can reduce, expand or generate feature representations?" and Euclidean distance appear; the End Term includes the last week of the course: KMeans attributes (inertia_, cluster_centers_, labels_), elbow/silhouette reasoning, DBSCAN's −1-1 noise label, GaussianMixture.predict_proba, PCA(n_components=0.95) and explained_variance_ratio_, and "which method can still recommend a brand-new item with no ratings?" (content-based filtering).

Partner theory in MLT: PCA in 25 of 60 Quiz 1 papers, EM in 46, k-means in 10.

Watch out - real exam trap
  • Inertia always falls as kk grows: use the elbow/silhouette, not the minimum.
  • DBSCAN's label −1-1 means noise, not "cluster −1-1"; it has no predict.
  • PCA(n_components=0.95) is a fraction of variance, not 0.95 components.
  • PCA does not scale for you; k-means needs scaled data.
  • Lower BIC is better (higher silhouette is better).
  • GaussianMixture.predict_proba rows sum to 1; k-means has no such thing.

Quick quiz

Quick quiz

In DBSCAN, a label of -1 means...

  • the largest cluster
  • the point is noise
  • an error occurred
  • the first cluster
Points not reachable from any core point are labelled -1.

PCA(n_components=0.95) selects...

  • 95 components
  • 0.95 components
  • enough components to explain 95 percent of the variance
  • components with eigenvalue 0.95
A number between 0 and 1 is read as the target fraction of variance.

For choosing the number of GaussianMixture components, we prefer the model with...

  • the highest BIC
  • the lowest BIC
  • the highest inertia
  • the most components
BIC penalises extra parameters; lower is better.

Select all TRUE statements. (select all that apply)

  • KMeans.inertia_ always decreases as n_clusters increases (for the best solution).
  • DBSCAN can find non-round clusters.
  • PCA scales the features automatically.
  • GaussianMixture gives only hard assignments.
PCA only centres the data, and GaussianMixture also provides soft probabilities.

Recap

Remember this
  • KMeans: cluster_centers_, labels_, inertia_; scale first; pick kk by elbow / silhouette. Round clusters only. MiniBatchKMeans has partial_fit.
  • DBSCAN: eps, min_samples; any shape; label −1-1 = noise; no predict.
  • GaussianMixture = EM: soft predict_proba, weights_, means_; choose KK by lowest BIC.
  • PCA: components_, explained_variance_ratio_, inverse_transform; n_components=0.95 keeps 95% variance (digits: 29 components); error = discarded variance.
Formulas to keep
  • Inertia =∑i∥xi−μzi∥2=\sum_i\|\mathbf x_i-\boldsymbol\mu_{z_i}\|^2; silhouette in [−1,1][-1,1]
  • DBSCAN defaults eps=0.5, min_samples=5; noise label −1-1
  • GMM parameters (full): K(d+d(d+1)2)+K−1K(d+\frac{d(d+1)}2)+K-1; BIC =−2ln⁡L+pln⁡n=-2\ln L+p\ln n (lower is better)
  • PCA: variance explained =∑≤kλ/∑λ=\sum_{\le k}\lambda/\sum\lambda; reconstruction error =∑>kλ=\sum_{>k}\lambda
Connected weeks (learn them together)

Practise with real exam questions

These come straight from past papers (with the real figures and the official answer key). Open 58 real questions on this week   All End Term papers