• 📖 Cover
  • 📚 Contents
  • Ch 0
  • Ch 1
  • Ch 2
  • Ch 3
  • Ch 4

Chapter 4 — Finding Hidden Groups — Clustering Methods

What This Chapter Covers

Problem: we have customer records, but nobody has already told us which buying-pattern group each customer belongs to.

Example 1 — a wholesale distributor. We have 440 customers and each customer’s annual spending on six product categories. The sales manager asks: “Do some customers buy similar combinations of products, so we could test a different bundle for each group?”

The table records amounts spent, but has no ready-made buying-pattern segment for each customer. Channel tells us whether a customer is retail or a hotel/restaurant/café; it does not tell us these spending-based groups.

Example 2 — a mall (simulated customer data). We have customers’ annual income and spending scores. The marketing manager asks: “Can we find groups with similar income and spending patterns before trying different promotions?”

There is no supplied label such as “higher income, lower spending score.” We first find groups from the features, then describe what each group looks like.

In this chapter: choose features → measure similarity → form groups → understand the groups → propose an action to test. The group labels are an output of clustering, not an answer column supplied at the start.

This chapter follows the Fall 2026 one-lecture clustering topic: naïve grouping, distance measures, K-means, and choosing the number of clusters. Section 4.6 (hierarchical clustering) is optional and is not covered in the final exam. Section practices can also be completed after class; the group Colab project will be separate.

Chapter Roadmap

Section Business task
1 Define the grouping question and choose features
2 Measure distance and standardise features
3 Understand and run K-means
4 Compare plausible K values and check limitations
5 Profile customers and propose business actions
6 (Optional) Read a hierarchical tree — not covered in the final exam

Business Groups, Simple Rules, and Features

Define why a group would be useful before asking an algorithm to create one.

The Distributor’s Question

Business question: which wholesale customers have similar buying patterns, so the distributor can plan suitable product bundles?

One row = one customer’s annual spending record. The table contains 440 customers. A row summarises a whole year; it is not one shopping transaction or a count of items.

Column(s) What the values mean
Channel Customer type: 1 = hotel/restaurant/café (Horeca); 2 = retail
Region Customer location: 1 = Lisbon; 2 = Porto (Oporto); 3 = other regions
Fresh, Milk, Grocery, Frozen Annual spending on fresh products, milk products, groceries and frozen products
Detergents_Paper, Delicassen Annual spending on detergents/paper products and delicatessen products

The six spending columns use monetary units (m.u.); the source does not specify a currency. Channel and Region are category codes, not spending amounts or ordered scores.

Read the first row: Channel = 2 and Region = 3 identify a retail customer in another region. Fresh = 12,669 means annual fresh-product spending of 12,669 m.u. The preview shows four of the eight columns.

The supplied CSV has eight columns: two categorical codes and six annual spending measures. Its row index is a display position, not a feature for clustering. UCI category frequencies match the file codes: Channel 1 has 298 Horeca customers and Channel 2 has 142 retail customers; Region 1 has 77 Lisbon records, Region 2 has 47 Porto records and Region 3 has 316 other-region records. The course clusters the six spending features and uses Channel/Region afterwards for interpretation. The distributor planning question is an illustrative scenario; the annual records do not provide individual transaction dates or item quantities.

Sources: UCI Wholesale Customers: data and variable descriptions

Clustering Has No Response Y

Chapter 3 regression uses an outcome Y and predictors X. Clustering uses selected features X to form groups without fitting a known outcome. The resulting cluster numbers are created by the algorithm.

Input: customer featuresA: Milk, Grocery, ...B: Milk, Grocery, ...→Find similar recordsCompare selected featuresNo known outcome Y→Output: group labelsA → group 0; B → group 1Labels are created, not given

Chapters 1 and 2 taught data handling, rather than themselves being supervised-learning algorithms. Channel and Region may be used later to interpret clusters, but they are excluded from this spending-based feature matrix.

Start with a Simple Business Rule

A simple business rule separates customers whose annual Grocery spending is at least 10,000 monetary units (m.u.) from the others. m.u. means monetary units: the dataset does not specify a currency, so this is not an asserted HKD or USD amount. The rule uses one spending variable and a chosen cutoff; it may miss other purchase patterns.

Render the Rule’s Boundary

The vertical line is the chosen Grocery cutoff. Customers with very different Milk spending can be placed together by this one-variable rule. Change the cutoff to see how membership changes.

Render the Rule's Boundary

Choose Features That Define Similarity

Step 1 — choose what counts as similar. Use the six annual spending columns. Exclude identifiers, Channel, Region and earlier Cluster labels.

Step 2 — put those features on comparable scales. StandardScaler() creates a scaling tool; scaler.fit_transform(wholesale[features]) learns each column’s mean and standard deviation, then standardises its values. The result X is the numerical input for clustering.

Why? Distance-based clustering can be dominated by columns with larger numerical spreads—even when all columns use the same currency. Standardisation measures each gap in standard-deviation units. The next two slides show how.

Integer channel codes represent categories, not measured distances. Check missing values, duplicates and impossible negative spending first. Creating StandardScaler() alone does not change any data: fit_transform performs the calculation. The original wholesale table remains in monetary units, which we use later to interpret cluster profiles.

StandardScaler: One Calculation, Column by Column

Example: four customers have Income = [40,000, 60,000, 40,000, 60,000] and Score = [40, 40, 60, 60].

\[z=\frac{x-\text{column mean}}{\text{column standard deviation}}\]

Feature Mean SD used by the scaler Example after scaling
Annual Income (m.u.) 50,000 10,000 60,000 → (60,000 − 50,000) / 10,000 = 1
Spending Score (points) 50 10 40 → (40 − 50) / 10 = −1

Read the new values: 0 = at the column mean; +1 = one SD above; −1 = one SD below. Each varying column now has mean 0 and SD 1. These are unit-free values, not percentages or values restricted to 0–1.

The scaler works separately on each column, not across each customer row. It uses population standard deviation (ddof=0) across the supplied records. In this constructed example the squared Income deviations average 100,000,000, so SD = 10,000; Score SD = 10. Standardisation changes the units and spread, not the rank of customers within each feature. It does not force a normal distribution.

Sources: StandardScaler documentation

Why Scaling Changes Who Looks Close

Compare A = (40,000, 40) with B = (60,000, 40) and C = (40,000, 60). Use the column standard deviations from the previous example.

Before: original numerical unitsAfter: standard-deviation units A → B: Income gap onlyA → B: 20,000 / 10,000 = 2 20,000 2 A → C: Score gap onlyA → C: 20 / 10 = 2 20 (almost invisible on this scale) 2 C looks 1,000 times closer.B and C are equally far from A. Income units dominate the raw distance.Both gaps are two column SDs.

The point: K-means uses distances to assign customers to groups. Rescaling can change these distances and therefore the groups. In ISOM2600, always standardise the selected features with StandardScaler before fitting clustering models. This measures gaps relative to each feature’s spread; the business question still determines which features to include.

For these comparisons only one coordinate differs, so Euclidean distance equals that coordinate gap in absolute value. The raw bars share one scale within the left panel; the standardised bars share a different scale within the right panel. Standardisation is a required preprocessing step for clustering in ISOM2600. It does not guarantee meaningful clusters, remove outliers or make an irrelevant feature useful. Section 2 explains the distance formulas and standardisation calculation.

The Clustering Workflow

Define the business question → select features and inspect records → standardise features → choose K for K-means → fit, inspect and profile groups → test business actions.

Check whether the groups are distinct, stable and useful; revisit earlier choices when needed. A clustering result alone does not prove there are meaningful customer segments.

For K-means: specify the number of groups K before each fit. To compare K=3 and K=4, run the algorithm separately for each choice.

In-Class Practice: Improve the Rule

Try a Grocery cutoff of 8,000. Count both groups and compare their average Milk spending. Explain which feature the rule still ignores.

Section 1 Practice — Business Groups, Simple Rules, and Features

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Count customers

Warm-up. Print the number of customer rows.

Write your answer, then run it.

2. Select spending features

Warm-up. Print the first two rows of the six spending columns.

Write your answer, then run it.

3. Identify coded categories

Warm-up. Print the unique Channel codes.

Write your answer, then run it.

4. Apply a simple rule

Build your skills. Count customers with Grocery at least 10,000 m.u.

Write your answer, then run it.

5. Count both rule groups

Build your skills. Print counts for both sides of the Grocery rule.

Write your answer, then run it.

6. Profile a rule

Build your skills. Print average Milk spending for both Grocery-rule groups.

Write your answer, then run it.

7. Change the rule

Build your skills. Count customers classified high at cutoffs 8,000 and 12,000.

Write your answer, then run it.

8. Check feature completeness

Challenge. Print the total missing entries in the selected feature table.

Write your answer, then run it.

9. Compare distribution spread

Challenge. Print the mean and sample SD of Fresh and Grocery.

Write your answer, then run it.

10. Separate inputs from interpretation

Challenge. Print whether Channel or Region appears in features; add a sentence about their later use.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

Distance Measures and Standardisation

Calculate distances and standardise selected features before clustering.

Why Clustering Needs a Distance

To group similar customers, we need a numerical way to compare them. A distance converts differences in the selected features into one number: smaller means more similar under those features and scales.

For the example customer coordinates A=(1,1), B=(4,5), C=(1,2), Euclidean distance gives A–B=5 and A–C=1. C is closer to A than B is.

How clustering uses this number: K-means compares each customer with current centres; hierarchical clustering starts with customer-pair distances and uses a linkage rule to compare groups.

Changing the features or their scales can change who looks close. The next slide shows how to calculate the distance.

A distance is a numerical dissimilarity in the chosen feature space, not a claim that customers are similar in every business respect. These three points use illustrative feature values on comparable scales.

Euclidean Distance: A Straight-Line Gap

A and B are two customers; each customer has two features. These are illustrative feature values on comparable scales.

Customer Feature 1 (horizontal axis) Feature 2 (vertical axis)
A 1 1
B 4 5

Thus A = (1, 1) and B = (4, 5). Each pair lists one customer’s Feature 1 and Feature 2 values.

Feature 1Feature 2 A (1, 1)B (4, 5)4 − 1 = 35 − 1 = 4Distance = 5 Two features → one pointTwo customers → two pointsDistance → gap between them

\[d(A,B)=\sqrt{(4-1)^2+(5-1)^2}=\sqrt{3^2+4^2}=5\]

Square the difference in each feature, add the squared differences, then take the square root. With more features, include one squared difference for every feature.

A row represents a customer and a column represents a feature. In a two-feature plot, one customer becomes one point. The straight segment joins those two customer points; the dashed horizontal and vertical gaps form a right triangle. The Pythagorean theorem gives its diagonal length. Feature scales matter: raw gaps in different units can dominate the distance, as the preceding scaling example showed.

A Customer Distance Illustration

Consider two customers described by Age (years) and Income (thousands of monetary units): A=(35,60) and B=(28,80). The right triangle shows coordinate gaps of 7 years and 20 thousand monetary units. The raw Euclidean distance is about 21.19 in this mixed-unit feature space.

Customer coordinates, their Age and Income gaps, and straight-line distance

Manhattan Distance: Add Absolute Gaps

Return to A=(1,1) and B=(4,5) from our first distance example. Manhattan distance adds the absolute coordinate gaps: |4−1|+|5−1|=3+4=7, compared with Euclidean distance 5. Distance choice matters. Standard K-means optimises squared Euclidean distances; changing to Manhattan is not merely a KMeans parameter choice.

A (1,1)B (4,5)34Walk along the features: 3 + 4 = 7Straight-line shortcut: √(3² + 4²) = 5Same customers; different definitions of distance.

A Larger Numerical Scale Can Dominate

Income is in currency units; Age is years; Score is an illustrative spending score from 1 to 100. The Income difference dominates a raw distance even if we want all three features to matter.

StandardScaler: Centre and Scale Each Feature

For each feature, subtract its mean and divide by its standard deviation:

\[z_i=\frac{x_i-\bar{x}}{s_0},\qquad s_0=\sqrt{\frac{\sum_{i=1}^{n}(x_i-\bar{x})^2}{n}}\quad(\text{ddof}=0).\]

Why divide by n, not n − 1? Here we are rescaling the observed data, not estimating an unknown population variance. Using n makes the standardised column’s mean 0 and its SD 1 when checked with the same ddof=0 convention.

  • Statistics: sample variance uses n − 1 to correct bias when estimating population variance from a random sample.
  • Preprocessing: StandardScaler uses n as its scaling convention. This does not mean our customers are the entire population.
  • In pandas: .std() defaults to ddof=1; use .std(ddof=0) when checking StandardScaler.

fit_transform learns each column’s mean and scale, then transforms its values.

The general denominator is n − ddof: ddof=0 means divide the sum of squared deviations by n; ddof=1 means divide it by n−1. The sample-SD formula is \(s_1=\sqrt{\sum(x_i-\bar{x})^2/(n-1)}\). It is the sample variance \(s_1^2\), not generally the sample SD itself, that is unbiased under the usual random-sample assumptions. With five rows, values scaled using \(s_0\) have .std(ddof=0) = 1 but .std() = \(\sqrt{5/4}\approx1.118\). Both outputs can be correct because their denominators differ. If every feature uses the same n complete rows, changing all columns from ddof=0 to ddof=1 multiplies every standardised coordinate by the same \(\sqrt{(n-1)/n}\); relative Euclidean distances and the mathematical K-means partition objective are unchanged apart from a common scale. Use the library convention consistently.

Sources: StandardScaler documentation

Scaler Attributes and Methods

scaler.mean_ and scaler.scale_ are fitted attributes. .fit_transform(...), .transform(...), and .inverse_transform(...) are methods. The trailing underscore convention marks values learned during fitting.

Render Before and After Scaling

The left panel shows the very different raw numerical ranges; the right panel shows standardised values. In ISOM2600, use the standardised features for clustering. Scaling does not make every feature equally useful.

Render Before and After Scaling

Interactive Distance: Before and After Standardisation

Compare A–B with A–C before and after standardisation. The raw calculation is a diagnostic showing how numerical scales can dominate distance. For clustering in ISOM2600, use the standardised features.

Calculate Distances After Standardisation

Use the same formula on the standardised rows. A “closer” customer is closer under the selected features and scaling, not universally more similar.

Transform New Records with the Fitted Scaler

.transform() uses the existing means and scales. Fitting a new scaler on each new customer would destroy comparability. Use .inverse_transform() to recover centroids in business units.

Existing customersfit: learn mean and SDKeep the fitted scaler→New customertransform: reuse those valuesDo not fit a new scaler→Comparable coordinatesSame ruler for every customerThen assign a cluster

In-Class Practice: Check the SD Convention

Print standardised means, .std(), and .std(ddof=0). Explain why the two SD outputs differ even though the scaling worked correctly.

Section 2 Practice — Distance Measures and Standardisation

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Calculate one coordinate gap

Warm-up. Print the Income difference A minus B.

Write your answer, then run it.

2. Calculate raw Euclidean distance

Warm-up. As a before-scaling diagnostic, print the raw A–B distance rounded to three decimals. Clustering uses standardised features.

Write your answer, then run it.

3. Calculate Manhattan distance

Warm-up. As a before-scaling diagnostic, print raw A–B Manhattan distance. Clustering uses standardised features.

Write your answer, then run it.

4. Check standardised means

Build your skills. Print the three standardised means rounded to six decimals.

Write your answer, then run it.

5. Check population SD

Build your skills. Print standardised population SDs.

Write your answer, then run it.

6. Compare SD conventions

Build your skills. Print sample and population SD of standardised Age.

Write your answer, then run it.

7. Calculate standardised distance

Build your skills. Print A–B Euclidean distance on the standardised features.

Write your answer, then run it.

8. Compare two neighbours

Challenge. Print standardised A–B and A–C distances.

Write your answer, then run it.

9. Transform a new customer

Challenge. Use the existing scaler for Age=30, Income=50000, Score=70 and print the result.

Write your answer, then run it.

10. Reconstruct a scaling calculation

Challenge. Manually standardise Income with ddof=0; print whether it matches the scaled Income column.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

K-Means: Assign, Average, Repeat

Understand the steps with six points before fitting the larger customer table.

A Centroid Is a Coordinate-Wise Mean

For three points shown in prepared illustrative coordinates, (20,30), (30,50), and (40,40), the centroid is (30,40). It need not be an observed customer. A centroid is the coordinate-wise mean; Python clustering fits use standardised features.

Three points and their coordinate-wise mean centroid

The K-Means Algorithm

The final centroids are not known at the start. To find a group mean, we need to know its members; to assign members, we need centres. K-means solves this by repeating two operations: assign customers → recompute group means.

This is an iterative algorithm: new centres lead to new assignments, which lead to new centres. Keep K fixed during one fit. Follow the loop in the original lecture diagram, then work through the four illustrated steps below.

Manual diagrams use prepared schematic coordinates to show the algorithm. Python model fits always standardise the input features first.

This flow diagram is from the original lecture PPT, page16. The following four pages retain the teaching sequence of PPT pages18–21, using the six-customer coordinates from our interactive example. Iteration means repeating assignment and update, not recursion through a function calling itself. In software, convergence tolerance and an iteration limit also govern stopping; convergence does not prove a globally best clustering.

Original five-step K-means algorithm: initialise, assign, recompute means, reassign, repeat until assignments stop changing; arrow loops back.

K-Means Step 1: Choose Initial Centroids

Choose K=2 first. Each dot is a customer with two features. Start with centre 0 at A=(1,1) and centre 1 at C=(2,1). The grey customers have not yet been assigned.

These are starting guesses, not the final group means. We deliberately start both centres in the lower-left cloud so we can see why repeated updating is necessary. The software can choose starting centres automatically; here we set them for illustration.

Before: six unassigned customers00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1Choose two starting centres00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1

Adapted from the original PPT four-step K-means teaching sequence. Diagrams are recomputed from the same coordinates and memberships as the six-stage interactive demonstration. These are classroom features on comparable scales. These are prepared schematic coordinates for hand calculations; they do not replace the StandardScaler step in a Python model fit.

K-Means Step 2: Assign to the Nearest Centroid

Keep the centres fixed while assigning all customers. Compare each customer’s distance to both centres. Colour the customer according to the nearer centre.

The first assignment is A,B → group 0 and C,D,E,F → group 1. C is at centre 1, so its distance to that centre is zero.

Do not move a centre after assigning just one customer. Finish this assignment step first; then compute both group means.

Before: centres fixed, points grey00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1After: colour by nearest centre00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1

Adapted from the original PPT four-step K-means teaching sequence. Diagrams are recomputed from the same coordinates and memberships as the six-stage interactive demonstration. These are classroom features on comparable scales. These are prepared schematic coordinates for hand calculations; they do not replace the StandardScaler step in a Python model fit.

K-Means Step 3: Recompute the Centroids

Keep memberships fixed and average each feature within each group. The hollow circles mark the old centres; arrows point to the new means. Customer dots stay where they are.

Group 0 contains A and B:

\[\mu_0=\left(\frac{1+1}{2},\frac{1+2}{2}\right)=(1,1.5).\]

Group 1 contains C, D, E and F:

\[\mu_1=\left(\frac{2+7+8+8}{4},\frac{1+7+7+8}{4}\right)=(6.25,5.75).\]

Before: first assignments00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1After: move centres to group means00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1

Adapted from the original PPT four-step K-means teaching sequence. Diagrams are recomputed from the same coordinates and memberships as the six-stage interactive demonstration. These are classroom features on comparable scales. These are prepared schematic coordinates for hand calculations; they do not replace the StandardScaler step in a Python model fit.

K-Means Step 4: Reassign, Update, and Repeat

Moving a centre can change which centre is closest. With the updated centres, C is 1.118 from centre 0 and 6.374 from centre 1. C therefore switches from group 1 to group 0 (outlined in gold).

Compute the means again: A,B,C now give centre 0=(1.333,1.333); D,E,F give centre 1=(7.667,7.333). The centre update from Step 3 was not the final answer.

Check the assignments once more. Here nobody switches, so another mean calculation would give the same centres: stop. Other datasets may need more rounds.

Assign → update → assign → update → … → stable assignments and centres.

Reassign: C switches to group 000336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1Update again; then check stability00336699Feature X1X2ABCDEF● Customer× CentreGroup 0Group 1

Adapted from the original PPT four-step K-means teaching sequence. Diagrams are recomputed from the same coordinates and memberships as the six-stage interactive demonstration. These are classroom features on comparable scales. These are prepared schematic coordinates for hand calculations; they do not replace the StandardScaler step in a Python model fit.

Assignment Uses the Nearest Centroid

For any assignment step, compare distances to every current centre. Use the same feature scales as the clustering fit. The point joins the nearest centre; cluster numbers only name groups.

The following Python calculation is a separate distance example with P=(2,1), centre 0=(1,1) and centre 1=(8,8). Squared distances are 1 and 85, so P joins group 0. Squaring preserves which nonnegative distance is smaller.

Compute One Assignment in Python

For point P=(2,1) and centres (1,1) and (8,8), squared distances are 1 and 85. argmin() gives the zero-based position of the smaller value, so P joins cluster 0.

Point P = (2, 1)Compare BOTH centres→Centre 0 = (1, 1)(2−1)² + (1−1)² = 1← smaller: choose cluster 0→Centre 1 = (8, 8)(2−8)² + (1−8)² = 85

Recompute Each Centre with .loc and .mean()

For this assignment, A/B/C form cluster 0 and D/E/F form cluster 1. Select each cluster separately with .loc, then use .mean() to calculate its coordinate means. Put the two mean rows in a DataFrame: these are the updated centres.

Select cluster 0A=(1,1), B=(1,2), C=(2,1)→Average each columnX1: (1+1+2)/3 = 1.333X2: (1+2+1)/3 = 1.333→New centre(1.333, 1.333)Repeat for cluster 1

Interactive K-Means: Assign and Update

Press Play stages to watch initial centres → assignments → mean updates → stable assignments. Pause to explain a stage, use Next step to advance manually, or Reset steps to replay. Start with two centres in the same cloud. Watch customer C switch groups after the first update; update again, then check that assignments stay stable.

Fit KMeans in Python

First standardise X1 and X2 with StandardScaler. Create an estimator with K=2, a fixed random seed, and 10 initialisations. .fit_predict(X) fits the model to those standardised coordinates and returns one label per customer. The printed centres are also in standard-deviation units.

Sources: KMeans documentation

KMeans Attributes and Methods

Fitted attributes: .labels_, .cluster_centers_, .inertia_, .n_iter_. Methods: .fit(X), .fit_predict(X), .predict(new_X). Cluster IDs start at 0 in KMeans and are arbitrary labels, not ranks.

A seed makes a fit reproducible within the chosen implementation, data order, and settings. Different versions can change label numbering or details. Relabelling 0 as 1 does not change which observations belong together.

Render Fitted Groups and Centres

The model is fitted on standardised features. For this plot, scaler.inverse_transform(...) converts its centres back to the original X1/X2 coordinates, so stars and customer points use the same axes. Colour represents membership, not quality or profitability.

Render Fitted Groups and Centres

Assign a New Record

.predict() assigns a new point to a fitted centre; it does not update the centres. Transform the new record using the same fitted scaler before prediction. Do not fit a new scaler to it.

New point(1.5, 1.5)→Use fitted scalerThen compare centresKeep centres fixed→Assign to nearestCluster 0 in this exampleNo retraining during predict

In-Class Practice: Explain the Object

Print the shape of .cluster_centers_, count members per cluster, and assign (7.5,7.5) after transforming it with the fitted scaler. Explain which operation would retrain the centres.

Section 3 Practice — K-Means: Assign, Average, Repeat

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Count labels

Warm-up. Print the number of fitted labels.

Write your answer, then run it.

2. Read centre shape

Warm-up. Print the centre array shape.

Write your answer, then run it.

3. Count group sizes

Warm-up. Print sorted cluster membership counts.

Write your answer, then run it.

4. Calculate a manual centroid

Build your skills. Print the coordinate means for A,B,C.

Write your answer, then run it.

5. Read the objective

Build your skills. Print inertia rounded to three decimals.

Write your answer, then run it.

6. Assign a new nearby point

Build your skills. Transform (1.5,1.5) with the fitted scaler, then predict its cluster.

Write your answer, then run it.

7. Check a new point manually

Build your skills. Transform (1.5,1.5) with the fitted scaler. Calculate its squared distances to both standardised centres, then print the nearest-centre index.

Write your answer, then run it.

8. Verify group means

Challenge. Print whether the original-coordinate group means equal the inverse-transformed centres in label order.

Write your answer, then run it.

9. Reconstruct WCSS

Challenge. Use each standardised row in X and its assigned centre to reconstruct WCSS.

Write your answer, then run it.

10. Distinguish assignment and refitting

Challenge. Save centres, predict a new point, and print whether centres stayed unchanged.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

Choosing K and Checking the Result

Compare fit, separation, stability, and business usefulness rather than treating one plot as proof.

WCSS: What Does Each Symbol Mean?

WCSS = Within-Cluster Sum of Squares. Measure how tightly customers sit around their own group centres.

\[\mathrm{WCSS}=\sum_{i=1}^{n}\sum_{j=1}^{p}\left(x_{ij}-\mu_{c_i,j}\right)^2\]

Symbol Meaning in our customer data
\(n\) and \(i\) n customers in total; i identifies one customer (one row)
\(p\) and \(j\) p selected features; j identifies one feature (one column)
\(x_{ij}\) Customer i’s value of feature j, in the scale used for clustering
\(c_i\) The cluster assigned to customer i; with KMeans, one of 0, …, K−1
\(\mu_{c_i,j}\) Feature j of customer i’s assigned centre: the mean in that cluster
\((x_{ij}-\mu_{c_i,j})^2\) Squared gap for this customer and this feature
\(\sum_j\) then \(\sum_i\) Add across features for one customer, then across all customers

Only use the assigned centre: do not add distances from a customer to every centre. K is the number of clusters; each customer belongs to one of them.

The shorter vector notation is \(\mathrm{WCSS}=\sum_{i=1}^{n}\lVert\mathbf{x}_i-\boldsymbol\mu_{c_i}\rVert^2\). Here \(\mathbf{x}_i\) is customer i’s vector of p features, \(\boldsymbol\mu_{c_i}\) is its assigned cluster’s centre vector, and the squared Euclidean norm means the sum of the p squared coordinate differences. There is no final square root: WCSS sums squared distances. For fixed centres, assign each customer to the nearest centre; for fixed assignments, choosing each group mean minimises its squared gaps. These are the two alternating K-means operations.

Calculate WCSS: Square Each Assigned Gap

Within-Cluster Sum of Squares (WCSS) adds the squared distances from customers to their assigned centres. The diagram uses one group and one feature: its centre is 0, and WCSS = 4 + 1 + 9 = 14.

The Python code applies exactly the same rule to our earlier six-customer, two-feature K-means fit. assigned selects the correct centre for each row; subtract, square and sum across all rows and features. The result equals km.inertia_.

Smaller WCSS means more compact groups in the same feature space. Raw and standardised WCSS use different scales, so do not compare their numbers directly. More groups can reduce WCSS without making the segmentation more useful.

-2-13Centre = 0One-feature worked exampleSquared gaps: (−2)² + (−1)² + 3²WCSS = 4 + 1 + 9 = 14Add these contributions across all clusters.

The best possible WCSS is nonincreasing as K rises, because an extra centre cannot worsen the optimum. Separately fitted heuristic KMeans runs can land in local solutions, so observed fits need not follow the ideal trend perfectly. WCSS alone does not penalise adding groups.

Explore the Simulated Mall Customers

The original notebook creates 200 customers with Age, income in thousands of illustrative currency units, and a Spending Score. We retain its records, but omit its known construction labels from the feature table.

These records are constructed, not a sample from an identified mall. The visible patterns make algorithm behaviour easy to study; they do not establish how many real customer segments a mall has.

Render an Elbow Plot

Fit several K values and plot WCSS. A bend suggests diminishing improvement, but may be unclear or suggest several plausible choices. Compare neighbouring K values with business profiles and group sizes.

Render an Elbow Plot

Interactive K: Compare the Partition

Choose K=2,3,4,5, or 6 for the same standardised mall features. Compare group counts, WCSS, and centre positions in the original units. More colours do not automatically mean a better business segmentation.

Extension: Separation with a Silhouette Score

A silhouette score compares within-group and nearest-other-group distances. Values near +1 suggest separation; near 0 suggest boundary overlap; negative values suggest a point closer to another group. The mean is one diagnostic, not a unique answer for K.

Near +1Well inside its groupNear 0Near the group boundaryNegativeCloser to the other groupOutlined point belongs to blue. Positions are schematic; these are not calculated scores.

The score needs at least two represented groups and fewer groups than observations. It depends on the chosen features, scaling, and distance. A high score does not prove that clusters match business types.

Sources: Silhouette score

Render Neighbouring Choices

These three fits use the same standardised features and show the original-unit coordinates. K=3 merges patterns that K=5 separates; K=6 subdivides a pattern. Decide whether those distinctions support different actions.

Render Neighbouring Choices

Initialisation and Stability

Initialisation = choosing the K starting centres before assigning customers. The assign → update cycle improves a starting solution; different starts can end at different solutions. The first centres can therefore affect the final result.

init="k-means++" chooses starting centres that tend to be spread out. It still uses randomness; it does not guarantee the best possible solution.

n_init=10 means 10 complete attempts on the same data with the same K, each beginning from an initial centre configuration. Each attempt can contain many assign/update iterations. Keep the completed attempt with the smallest WCSS. It does not mean 10 clusters or 10 updates.

Read the code: K = 5 groups; 10 starts per fit. Fit A uses seed 42; fit B uses seed 7. Compare their final WCSS, then inspect the memberships and profiles.

Different starting centresRun 1 • •Run 2 • •→Repeat assign → updateEach start reaches a solutionSome solutions fit better→Keep the lowest WCSSAmong these n_init runsNot a global-optimum proof

K-means alternates nearest-centre assignment and coordinate-mean updates. This improves its within-cluster objective, but the objective is not jointly convex in assignments and centres: convergence does not establish the global minimum. Multiple starts reduce the chance of relying on one poor local solution. The fitted .n_iter_ reports the iterations used by the selected run, whereas n_init controls how many starts are tried. Explicit n_init=10 avoids relying on changing library defaults. With the same input order, library/environment and seed, results are reproducible; a fixed seed does not make the result optimal. Different seeds may still converge to the same solution.

Sources: KMeans parameters

Reproducible Does Not Mean Stable

Reproducible: repeat the same procedure with the same data, settings and random seed, and obtain the same result. random_state=42 makes this convenient; 42 is not a special or better seed.

Stable: the main customer patterns remain similar under reasonable changes. A fixed seed alone cannot demonstrate this.

Check What to look for
Change the seed; keep data, scaling and K fixed Similar WCSS, group sizes, memberships and original-unit profiles
Compare nearby K values Which groups split or merge? Do the extra groups support a useful action?
Keep features standardised and inspect extreme records Are the conclusions driven by units or a few unusual customers?

Compare memberships, not ID numbers. A group called 0 in one run can be called 2 in another with exactly the same customers. Similar WCSS alone also does not prove the memberships are the same.

If the substantive patterns change sharply, describe the segmentation as sensitive and investigate before using it for business decisions.

Method 10A0B0C1D1E1FMethod 2222111Same members together.Different ID numbers.Compare who shares a group, not the numeric value of a label.

Stability is an empirical assessment, not a guarantee of future validity. Changing K deliberately changes the number of groups, so identical membership is not the goal of that check; inspect the persistence of meaningful profiles and the consequences of splitting or merging. A justified change of scaling changes the definition of similarity, so explain any interpretation changes. Formal resampling and partition-comparison scores are optional extensions, not required for this beginner lesson.

Outliers and Shape Limitations

An outlier is a customer far from most other customers in the chosen feature space. K-means uses means and squared distances, so unusual values can have a large influence.

Why the square matters: a distance of 10 contributes 100 to WCSS; a distance of 1 contributes only 1. One far-away point can therefore outweigh many small gaps.

Our example: A–F originally form two compact groups. Add G=(25,25) and keep K=2. Standardise both features before fitting. In this fit, one centre is used for G alone, while A–F are combined. The plot converts centres back to the original coordinates. K-means has used a scarce centre to reduce the large squared error from G.

Check before acting: is G a data-entry error or a genuine unusual customer? Correct verified errors; investigate valid extremes. StandardScaler does not remove outliers, and unusual does not automatically mean wrong.

The illustration holds the six original coordinates and K=2 fixed, adding just G=(25,25). Before adding G, each cloud has three members. After fitting with the same random_state=42 and n_init=10, G forms its own group and the other six form another. Depending on its position, an outlier can instead pull a shared group mean toward itself. Both effects follow from minimising squared gaps. This is sensitivity of the model to the chosen data, not evidence that G is fraudulent or unimportant.

Outliers and Shape Limitations

Why Cluster Shape Matters for K-Means

K-means asks: which centre is closest? It represents each group by one mean point. This works naturally for compact, roughly round groups in the selected feature space.

Long or curved groups: points far apart along one meaningful shape may be nearer to another centre. K-means can split that shape or join parts of different shapes. Its nearest-centre boundaries are straight in two dimensions, so they cannot trace arbitrary curved groups.

Different spreads or sizes: a broad group can contribute many large squared gaps. K-means may split it to reduce WCSS, even when a smaller nearby group then gets merged with another.

What to do: inspect a scatter plot and the resulting memberships, check feature scaling, and consider another clustering method if the geometry does not match the business question. Increasing K may reduce WCSS without solving the interpretation problem.

Compact groupsOne centre fits each cloud well.Long / curved groupsOne centre cannot trace a curve.Very different spreadsA broad cloud can be split.

The round-group description is a geometric tendency of the squared-Euclidean, one-centre representation, not a probabilistic assumption of exactly spherical normal populations. Similar size and spread often make examples easier for K-means, but unequal size does not guarantee failure. The diagrams show intended shapes in constructed examples, not fitted outcomes or established real customer types. A two-dimensional projection is only a partial view when clustering uses more features.

Choose a Useful, Defensible K

There is no single number that chooses K for us. Compare several candidates using the same customers, features and scaling. Then explain why the chosen groups are useful.

Read this example: moving from K=4 to K=5 reduces WCSS by about 36.94; moving from K=5 to K=6 reduces it by only 4.19. That makes K=5 worth examining, but does not prove it is the right answer.

Ask three questions: Are groups reasonably compact? What customer differences do they describe? Can we use those differences? For example, if two new groups would receive exactly the same offer, the extra split may add little value.

A clear conclusion would be: “We will try K=5 because it captures useful income/score differences without the extra split at K=6. We will check the profiles and stability before using the groups.” This is a proposed decision for the simulated example, not a verified business result.

K = 4WCSS = 74.92Customers per group:78, 41, 42, 39K = 5WCSS = 37.98Customers per group:43, 38, 39, 38, 42K = 6WCSS = 33.79Customers per group:42, 23, 38, 38, 42, 17K=4 → 5: WCSS falls by 36.94K=5 → 6: WCSS falls by only 4.19Next: inspect profiles and stability. Does each extra group need a different action?

The original mall construction has five designed patterns, which helps illustrate the algorithm. That construction fact is not evidence that K=5 will be right for the wholesale case or a new customer database.

In-Class Practice: Compare K=4 and K=5

Fit both choices, compare WCSS and membership counts, and describe a tradeoff. Keep the features and scaling identical.

Section 4 Practice — Choosing K and Checking the Result

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Read feature shape

Warm-up. Print X.shape.

Write your answer, then run it.

2. Fit a candidate K

Warm-up. Fit K=3 and print inertia.

Write your answer, then run it.

3. Count a candidate’s groups

Warm-up. Fit K=3 and print membership counts.

Write your answer, then run it.

4. Compare WCSS at two K values

Build your skills. Print WCSS for K=3 and K=5.

Write your answer, then run it.

5. Create elbow values

Build your skills. Print WCSS for K=1,2,3,4.

Write your answer, then run it.

6. Calculate a silhouette

Build your skills. Fit K=5 and print the mean silhouette score.

Write your answer, then run it.

7. Compare seeds

Build your skills. Print K=5 inertia with seeds 42 and 7.

Write your answer, then run it.

8. Inspect a small group

Challenge. Fit K=6 and print the smallest cluster size.

Write your answer, then run it.

9. Calculate average squared distance

Challenge. Fit K=5 on the standardised features X. Print WCSS and the mean squared distance per customer (WCSS divided by the number of customers).

Write your answer, then run it.

10. Avoid a trivial K decision

Challenge. Fit K=1 and K equal to the number of distinct feature rows; print their WCSS. Explain why minimum WCSS alone is insufficient.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

Customer Profiles and Business Actions

Describe who is in each group, connect its centroid to its average features, and use that description to propose an action.

What Is a Cluster Profile?

K-means gives us a group number for each customer. A number such as “group 0” does not tell a manager what those customers are like.

A cluster profile is a short description of the customers in one group: how many there are, what their measured features are like, and how they differ from other groups. Here, we start with average annual spending in each product category.

Why do this? The sales manager needs to know which products a group tends to buy before proposing a suitable offer. “Group 0” gives no such information; “45 customers with higher average Grocery and Milk spending” does.

Profiling describes groups after clustering. It does not fit a second model or create new group assignments.

Cluster label“Group 0”Who are these customers?→Profile the group45 customers; mean spendingGrocery 28,656; Milk 19,386→Use the descriptionPropose a Grocery–Milk offerTest whether it helps

From Customers to a Centroid

A centroid is one point whose coordinates are the group’s feature means. For two features, average each column separately.

In this small illustration, group 0 contains A=(2,4), B=(4,4), C=(3,7), where coordinates are (Milk, Grocery) annual spending in thousands of monetary units.

\[ \text{Centroid of group 0} =\left(\frac{2+4+3}{3},\frac{4+4+7}{3}\right) =(3,5). \]

The star therefore represents mean Milk spending of 3,000 and mean Grocery spending of 5,000 per customer per year. It may lie between customers: it is not an actual customer, and not every customer spends these amounts.

Milk: annual spending (thousand m.u.)Grocery: annual spending (thousand m.u.)ABCDEF★★Dots = individual customersStar = coordinate meansBlue: group 0, centre (3,5)Green: group 1, centre (9,11)Illustrative data; not the 440-row case.

A Profile Is a Picture of the Group

“Picture” means a numerical description, not a photograph or a new customer. We can show the same group as a point on a scatter plot, a row of means, or a bar chart.

Small illustration Customers Mean Milk Mean Grocery Plain description
Group 0 3 3,000 5,000 Lower spending in these two categories
Group 1 3 9,000 11,000 Higher spending in these two categories

Connection: the two means in each row are that group’s centroid coordinates in original units. The profile adds context: group size, units and a description. Later we can also add the spread of values or the mix of customer types.

Use: compare these measured patterns to propose different offers. Limit: the averages do not tell us that every member is the same, or that the higher-spending group is more profitable.

The same centroid, shown as a spending profileGroup 0 · 3 customersMilk3,000Grocery5,000Group 1 · 3 customersMilk9,000Grocery11,000Mean annual spending per customer (m.u.); bars share the same scale.

Real Customers: Fit Groups, Then Count Members

Now apply the idea to the distributor’s 440 customers and six annual spending categories. We use K=3 as a working example; this does not establish that three is best.

Purpose of this code: attach a group label to every customer, then find how many customers each profile will describe.

Code What it does Why we need it
fit_transform(...) Standardises the six spending columns Makes distances comparable
km.fit_predict(X) Fits K-means and returns one label per row Identifies which customers belong together
wholesale["Cluster"] = ... Saves each row’s label Lets us select a group afterwards
value_counts().sort_index() Counts members in label order Shows how many customers support each summary

Read the result: group 0 has 45 customers; group 1 has 393; group 2 has 2. IDs 0, 1 and 2 are names, not a ranking. Next we calculate what each group buys.

440 customersSix annual spending columns→Scale → fit K=3Compare spending patternsAdd a Cluster label per row→Count the resultsGroup 0: 45; group 1: 393Group 2: 2 customers

Build the Profile: Select Customers, Then Average

Purpose of this code: turn the labels into a readable table of average purchases. We already know each customer’s group; we are describing those groups, not fitting them again.

  1. wholesale["Cluster"] == 0 finds group 0’s rows.
  2. .loc[..., features] keeps those customers and the six original spending columns. group0 is a table of 45 customers × 6 features.
  3. group0.mean() averages each column separately: six numbers, one group’s mean spending profile. Repeat for groups 1 and 2.
  4. pd.DataFrame(...) stacks the three summaries: one row per group, one column per category. profile is simply our chosen Python variable name.

Interpret: group 0 averages 28,656 m.u. on Grocery and 19,386 m.u. on Milk per customer per year, versus group 1’s 5,535 and 4,115. These are original-unit centroid coordinates for this converged K-means fit, not group totals.

Example: mean Grocery spending per customer per yearGroup 0: 45 customers28,656 m.u.Group 1: 393 customers5,535 m.u.These are averages per customer, not total purchases by the whole group.

The loading, scaling and fitting lines at the start recreate the same working segmentation so this Run box works independently. The new task begins at group0 = … . Each .mean() returns one mean per selected column; DataFrame uses the category names as column labels. round(0) changes only the displayed precision. A profile is an interpretation summary, not a pandas method or a second fitted model.

Centroid and Profile: The Same Means in Different Units

We already have the profile from .loc and .mean(). Why show another method? K-means has also stored the group means in km.cluster_centers_, but it fitted them in standardised units.

Same group, same average pattern, two coordinate scales: the model uses standardised coordinates for distance; the manager needs annual spending amounts. scaler.inverse_transform(...) converts the stored centres to those original units.

\[\text{Original-unit centre}=\text{column mean}+\text{standardised centre}\times\text{column SD}.\]

Here “column mean” and “column SD” come from all 440 customers used to fit the scaler, not only the chosen group. Use that same fitted scaler.

Read the result: group 0’s Grocery coordinate becomes about 28,656 m.u., matching the profile calculated directly from its customers. This is an alternative way to obtain the feature means; it adds no new customers, groups or business evidence.

Model: group 0 GroceryStandardised centre ≈ 2.1812→Undo the scaling7,951.28 + 2.1812 × 9,492.36Overall mean and SD→Manager: same averageGrocery ≈ 28,656 m.u.Per customer per year

Do not call fit_transform on the centres: that would learn a new unrelated scaling. Cluster ID is retained by row order in the centre table; sorting centres without carrying the corresponding ID can mislabel the profiles.

Inspect the Two-Customer Group

A profile is a summary. Check the customers behind it before treating it as a segment for a campaign. Group 2 contains only two customers, compared with 45 and 393 in the other groups.

Its mean Frozen spending is about 48,702 m.u. per customer per year. A large mean from two records is different evidence from a large mean shared by hundreds of customers.

Purpose of this code: value_counts() obtains group sizes; idxmin() finds the smallest group’s ID; .loc prints its actual customer records. Read the two rows to see what their average hides.

Check for verified data errors or genuine unusual customers. They may need individual attention; the profile alone does not justify a mass campaign or the name “VIP.”

Actual group sizes in the working wholesale fitCluster 045Cluster 1393Cluster 22Only 2 customers:inspect the recordsbefore naming a segment.

The group sizes are computed from the supplied snapshot and fixed settings. Do not name the tiny group VIP without profitability or relationship data. Change the seed, compare neighbouring K values and inspect extreme records while keeping the selected features standardised.

Render Original-Unit Spending Profiles

Purpose of this code: show the original-unit profile table as bars, so the manager can read actual average spending amounts. profile.T places categories on the horizontal axis; .plot.bar() draws one bar per group in each category.

Now read the same profiles in money amounts. The horizontal axis lists product categories. The vertical axis is mean annual spending per customer, in monetary units. The three bar colours represent the three groups.

For Grocery, group 0’s bar is about 28,656, compared with group 1’s 5,535. This tells the sales team how the groups’ average purchases differ.

Check who is behind each bar: group 0 has 45 customers, group 1 has 393, and group 2 has only 2. A tall bar for group 2 describes those two customers; it does not establish a large market opportunity.

Render Original-Unit Spending Profiles

Render Category Profiles in Comparable Units

Purpose of this code: draw the mean-feature table as colours so we can compare each group’s buying pattern across all six categories. It visualises the existing centroids; it does not fit new groups.

Read one square at a time. Rows are customer groups; columns are product categories. A square shows whether that group’s average spending is above or below the average for all 440 customers in that category.

Red / positive: above the category average. Blue / negative: below it. Near white / zero: close to it. A value of +1 means one category SD above the overall mean; it does not mean one monetary unit.

Start with group 0’s Grocery square, then compare its Milk square. Next read across group 1. This helps us compare buying patterns across categories with very different spending ranges.

The colour bar is limited to −2 to +2: values beyond those limits share the end colour. Colour alone does not show their exact magnitude, and red does not mean higher profit.

Render Category Profiles in Comparable Units

Extension: Compare Absolute and Compressed Spending

Optional: what if a few very large spending amounts drive the groups? log(1+x) compresses large values. For example, a rise from 1,000 to 10,000 is much smaller on a log scale than in raw monetary units.

The left panel fits standardised spending. The right panel first applies log(1+x), then standardises and fits K-means again. Customers can change colour because we changed how spending differences are measured.

Both plots display the same Grocery and Milk axes on log scales so we can see the points. Changing the plot axes alone would not change the fitted groups; changing the model inputs does.

Compare the group sizes and the original spending profiles before deciding whether this alternative helps. It changes the business question; it is not an automatic improvement.

The six-category fits are displayed through two original monetary variables on log axes. Those plotting axes are the same in both panels; the change in membership comes from the fitting transformation. This is an extension applying Chapter 2 feature transformations, not a requirement to transform every clustering problem.

Extension: Compare Absolute and Compressed Spending

Interpret with External Categories Afterwards

Do our spending groups mostly contain shops, or hotels/restaurants/cafés? We did not use Channel to create the groups. We can now use it to help describe them.

pd.crosstab(Channel, Cluster) makes a count table. Rows are customer types: 1 = hotel/restaurant/café; 2 = retail. Columns are the fitted clusters. A cell counts customers belonging to both its row type and its column group.

The second table uses normalize="columns": divide each count by that cluster’s total. Each column adds to 1, so it shows the customer-type mix within that group.

A spending group can contain both types. That is not automatically an error: we grouped customers by spending, not by their business label.

Create spending groupsUse the six spending columnsDo NOT include Channel→Look up customer typeChannel 1: hotel/café/etc.Channel 2: retail→Read the mixCount each type within a groupDivide by that group total

Compare the Simulated Mall Customer Profiles

Use the same reading method for the mall example. This constructed dataset uses two features: annual income (in thousands of illustrative currency units) and a spending score from 1 to 100.

For each group, select its customers, calculate mean income and mean score, then count its members. Compare the mean values with the other groups.

A group with relatively high income and low score can be called “higher income, lower spending score.” That name tells us exactly what was measured.

Do not rename it “disloyal customers” or “low-profit customers”: neither loyalty nor profit is in this table. A descriptive name is enough.

What the table measuresIncome and spending score→A supported nameHigher income, lower score→What we do not knowLoyalty, intentions or profitNeed additional evidence

Render Mall Profiles with Original-Unit Centres

Each dot is one customer; each star is one group’s average position. Read income from left to right and spending score from bottom to top.

A star near the upper right means that group has relatively high average income and high average score. A star near the lower right means high income but low score. Nearby dots need not have exactly the average values.

The star may lie between customers rather than on a dot. It is a mean, not necessarily an actual person. Income and score help describe customers; they do not directly measure the profit an offer would generate.

Render Mall Profiles with Original-Unit Centres

From Profile to a Testable Action

What could the distributor try for group 0? Its 45 customers average about 28,656 m.u. on Grocery and 19,386 m.u. on Milk. A combined Grocery–Milk offer is one idea worth testing.

Keep three statements separate:

  1. What we observed: this group already buys relatively more Grocery and Milk than the large group 1.
  2. What we propose: offer some suitable customers a Grocery–Milk bundle.
  3. What we need to learn: does the offer increase margin after the discount and campaign costs?

For a pilot, randomly assign eligible customers to an offer group and a comparison group where feasible, then compare results over the same period. Higher sales alone are not enough if the discount removes the extra margin.

Clustering suggests whom we might study. It does not show that an offer will work.

ObserveHigher Grocery and Milkin the measured profile→ProposeTry a joint-category bundleThis is a hypothesis→Test and measurePilot with a comparison groupMeasure incremental marginA descriptive cluster does not tell us whether the offer caused an improvement.

Compare pilot and suitable comparison customers, account for customer size and existing purchases, and assess campaign cost. Annual category spending does not show whether purchases would have happened without the offer.

In-Class Practice: A Sales Manager’s Memo

Write a short note to the distributor’s sales manager. Use the original spending amounts, not standardised coordinates.

  1. Find the group with the highest mean Grocery spending.
  2. Report its customer count and its average Grocery and Milk spending, with units.
  3. Give the group a plain descriptive name.
  4. Suggest one offer to test and one result to measure.

Use this structure: “Group __ contains __ customers. On average, each spends __ on Grocery and __ on Milk per year. We could test __ and measure __.” Do not promise that the offer will increase profit.

Section 5 Practice — Customer Profiles and Business Actions

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Count fitted groups

Warm-up. Print membership counts.

Write your answer, then run it.

2. Profile Grocery

Warm-up. Print average Grocery spending per group.

Write your answer, then run it.

3. Profile two categories

Warm-up. Build a profile table: one row per group, containing mean annual Milk and Grocery spending per customer (m.u.).

Write your answer, then run it.

4. Read original-unit centres

Build your skills. Inverse-transform the centres and print the first two categories.

Write your answer, then run it.

5. Identify a descriptive group

Build your skills. Print the cluster with the highest mean Grocery spending.

Write your answer, then run it.

6. Check group context

Build your skills. For the highest-mean-Grocery group, print its size and mean Milk spending.

Write your answer, then run it.

7. Inspect channel mix

Build your skills. Print a Channel-by-Cluster cross-tabulation.

Write your answer, then run it.

8. Inspect proportions

Challenge. Print the proportion of each Channel within each Cluster.

Write your answer, then run it.

9. Check centres against profiles

Challenge. Print whether inverse-transformed centres match group means in label order.

Write your answer, then run it.

10. Write an evidence-based proposal

Challenge. Print the high-Grocery group’s profile, followed by a bundle-pilot proposal that avoids claiming proven profit.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

Hierarchical Clustering: One Customer Story

Optional — not covered in the final exam.

Follow five customers through four merges, read their tree, and choose a cut.

Build Groups by Joining Two at a Time

Our manager has five customers, A–E. Hierarchical clustering starts with one group per customer and repeatedly joins two groups.

Five customers need four merges to become one group. We keep the whole history as a tree, then choose how many final groups to use.

Start: 5 groups{A} {B} {C} {D} {E}→Join two at a time5 → 4 → 3 → 2 → 1 groups→Keep the historyA tree records the mergesChoose final groups later

A Group Needs a Rule for Comparing Distances

Distance compares two customers. Linkage compares two groups.

Suppose A and B are already together. To compare {A,B} with C, we have two customer gaps: A–C=6 and B–C=5.

A linkage rule turns those gaps into one group-comparison value. The next three slides show three possible rules.

Group {A,B}ABGroup {C}A–C = 6B–C = 5How should we combine 6 and 5?: ?

Single Linkage Uses the Nearest Pair

Single linkage uses the smallest cross-group customer distance.

For {A,B} versus C, the two gaps are 6 and 5.

Single linkage = min(6,5) = 5. Only the closest pair determines this group comparison.

Group {A,B}ABGroup {C}A–C = 6B–C = 5Single linkage: min(6,5) = 5

Complete Linkage Uses the Farthest Pair

Complete linkage uses the largest cross-group customer distance.

For {A,B} versus C, the two gaps are 6 and 5.

Complete linkage = max(6,5) = 6. Even the farthest pair matters. We use this rule for the rest of the example.

Group {A,B}ABGroup {C}A–C = 6B–C = 5Complete linkage: max(6,5) = 6

Average Linkage Uses All Cross-Group Pairs

Average linkage uses the mean of all cross-group customer distances.

For {A,B} versus C, there are two pairs: A–C and B–C.

Average linkage = (6+5)/2 = 5.5. Both pairs contribute equally here.

Group {A,B}ABGroup {C}A–C = 6B–C = 5Average linkage: (6+5)/2 = 5.5

Read Our Five-Customer Distance Table

Each cell compares its row customer with its column customer. Smaller means more similar. The diagonal is zero; each pair appears twice.

A B C D E
A 0 2 6 10 9
B 2 0 5 9 8
C 6 5 0 4 5
D 10 9 4 0 3
E 9 8 5 3 0

We use these same five customers and same distances on every remaining slide.

The supplied distances retain the five-customer teaching example. They are not asserted to come from a particular set of Euclidean feature coordinates.

Merge 1: Join A and B at Height 2

At the start, each group contains one customer. Its comparison with another group is simply that customer-pair distance.

The smallest distance is A–B=2, so join them first.

We now have four groups: {A,B}, {C}, {D}, {E}.

Before{A} {B} {C} {D} {E}→Smallest gap = 2Join A + B→After{A,B} {C} {D} {E}

Merge 2: Update the Gaps, Then Join D and E

Use complete linkage to update the new group’s comparisons:

Current groups Group-comparison value
{A,B} and C max(6,5) = 6
{A,B} and D max(10,9) = 10
{A,B} and E max(9,8) = 9
C and D 4
C and E 5
D and E 3

The smallest current value is 3. Join D+E. Three groups remain: {A,B}, {C}, {D,E}.

Before{A,B} {C} {D} {E}→Smallest group gap = 3Join D + E→After{A,B} {C} {D,E}

Merge 3: C Joins {D,E} at Height 5

Compare the three remaining groups using the farthest cross-group pair:

Current groups Complete linkage
{A,B} and C max(6,5) = 6
C and {D,E} max(4,5) = 5
{A,B} and {D,E} max(10,9,9,8) = 10

The smallest of 6, 5 and 10 is 5. Join C with {D,E}.

The merge is at 5, even though C–D is 4: complete linkage also checks C–E=5.

Before{A,B} {C} {D,E}→Smallest group gap = 5Join C + {D,E}→After{A,B} {C,D,E}

Merge 4: Join the Final Two Groups at Height 10

Only {A,B} and {C,D,E} remain. Complete linkage checks all six cross-group customer pairs:

C D E
A 6 10 9
B 5 9 8

The largest is A–D=10, so the final merge height is 10. All five customers now belong to one group.

Before{A,B} {C,D,E}→Farthest pair = 10Join the two groups→After{A,B,C,D,E}

A Dendrogram Draws the Four Merges

A dendrogram is a picture of the merge history. Start at the customer names and follow branches upward.

Each horizontal join is one merge; its height is the complete-linkage distance. Read the four heights: 2, 3, 5, 10.

The left-to-right customer order only makes the tree easier to draw. It is not a ranking.

Complete-linkage merge heightABCDE23510

A Horizontal Cut Chooses the Final Groups

Keep joins below the cut. Customers connected below it belong together.

At height 4, A+B and D+E have joined, but C has not joined either group.

We obtain three groups: {A,B}, {C}, {D,E}.

Complete-linkage merge heightABCDE23510Cut at 4

Move the Cut and Watch the Groups Change

Use the same five-customer tree. Before moving the cut, predict who will stay together.

Try 1 → 4 → 6 → 11. You should see 5 → 3 → 2 → 1 groups.

Changing the cut reuses the same tree; it does not run the merging procedure again.

One Row of Z Records One Merge

Python calls the stored merge history Z, a linkage matrix. Five customers require four rows.

Read the first row [0,1,2,2]:

Entry Meaning
Left = 0 Customer A
Right = 1 Customer B
Height = 2 Join them at distance 2
Count = 2 The new group contains 2 customers

Original customer IDs 0–4 mean A–E. They are labels, not ranks.

Stored row[0, 1, 2, 2]→Read its entriesA + B; height 2Customer count 2→MeaningThe first merge is {A,B}

A New Node ID Refers to an Earlier Group

After a merge, Python gives the new group a node ID. Original customers are 0–4; new groups are 5–8.

New node Group it represents
5 {A,B}
6 {D,E}
7 {C,D,E}
8 {A,B,C,D,E}

The third row [2,6,5,3] therefore means: join customer C (node 2) with group {D,E} (node 6), at height 5, making a group of 3 customers.

Save the Merge Record Once, Reuse It

Z is a compact record of the whole tree. Each row refers to customers or earlier groups by ID.

We can reuse Z to draw the tree or choose a different cut, without computing the merges again. Rebuild it only if the customers, distances or linkage rule change.

Compute merges onceComplete linkage → Z→Draw the historydendrogram(Z)→Try different cutsfcluster(Z, cut height)Same Z; different groups

Python Computes the Merge Record We Worked Out

The code repeats our complete-linkage calculations and prints Z. The four merge heights should be 2, 3, 5, 10.

pd.read_csv(...) loads our distance table. squareform(...) repackages its upper-half pair distances for Python’s clustering function. It does not calculate new distances.

linkage(..., method="complete") performs the merges and returns their record. The printed column names help us read it.

The square table contains both A–B and B–A. squareform takes each unique pair once. Passing the full two-dimensional distance table directly to linkage would make it treat the rows as original feature vectors, rather than supplied pairwise distances.

Python Draws the Saved Tree

dendrogram(Z, ...) draws the merges already stored in Z. It does not perform a new clustering.

labels=... adds customer names. ax.axhline(4, ...) draws our horizontal cut at height 4.

Check the picture: the cut leaves {A,B}, {C}, {D,E}. Change the cut line to 6 and predict the result before running.

Python Draws the Saved Tree

Read the Diagram Before Writing Code

Using the same five-customer tree, explain why C joins {D,E} at height 5.

Point to the two relevant customer distances, name the linkage rule, and explain the maximum. Then complete the Section 6 practice on the course main page.

Section 6 Practice — Hierarchical Clustering: One Customer Story

Optional practice — Section 4.6 is not covered in the final exam.

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

1. Count merge rows

Warm-up. Print Z.shape.

Write your answer, then run it.

2. Read the first height

Warm-up. Print the first merge height.

Write your answer, then run it.

3. Read the final height

Warm-up. Print the last merge height.

Write your answer, then run it.

4. Read the final count

Build your skills. Print the final customer count.

Write your answer, then run it.

5. Cut before any merge

Build your skills. At height1, print the number of groups.

Write your answer, then run it.

6. Make three groups

Build your skills. At height4, print one group label per customer.

Write your answer, then run it.

7. Make two groups

Build your skills. At height6, print one group label per customer.

Write your answer, then run it.

8. Join everyone

Challenge. At height11, print the number of groups.

Write your answer, then run it.

9. Compare the three rules

Challenge. For {A,B} versus C, print single, complete and average linkage using gaps6and5.

Write your answer, then run it.

10. Read a group merge

Challenge. Print the third row of Z and explain it.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

Chapter Summary

Decision Python tools Check before claiming success
Define similarity Choose feature columns Units, identifiers, business purpose
Inspect records .isna(), .describe() Completeness, spread, unusual records
Standardise selected features StandardScaler ddof=0; weighting interpretation
Fit groups KMeans, .fit_predict() Seed, initialisations, arbitrary IDs
Choose K for K-means .inertia_, elbow, silhouette Sizes, stability, useful distinctions
Profile members .loc, .mean(), .value_counts() Original units, supported names
Propose actions A measurable pilot Profiles do not prove campaign effects
Optional extension (not covered in the final exam): inspect a tree linkage, dendrogram, fcluster Linkage meaning, cut heights, ties

A useful segmentation is a documented business choice: features + scaling + algorithm + K/cut + profiles + a plan to check the action.

Quiz Review

Work from question 1 to 10. Edit your Python box, click Run Code, review the result, then click Submit attempt. Reference answers unlock after all ten attempts are submitted. This records completion, not correctness. Each box runs independently. Progress is saved in this browser.

Submitted: 0 / 10

Question 1

Count wholesale customers whose Grocery spending is at least 10,000 m.u.

Write your answer, then run it.

Question 2

For A=(1,1), B=(4,5), print Euclidean and Manhattan distances.

Write your answer, then run it.

Question 3

Manually standardise classroom Income using ddof=0 and compare with StandardScaler.

Write your answer, then run it.

Question 4

Transform (1.5,1.5) with the fitted scaler, then print its distances to the standardised centres and its assigned cluster.

Write your answer, then run it.

Question 5

Reconstruct WCSS for the six-point fitted model using its standardised input X.

Write your answer, then run it.

Question 6

Print mall WCSS for K=4 and K=5 and a sentence explaining why the smaller value does not settle the business choice.

Write your answer, then run it.

Question 7

Print wholesale original-unit mean Milk and Grocery spending for each working group.

Write your answer, then run it.

Question 8

Inverse-transform wholesale centroids and verify that they match group means.

Write your answer, then run it.

Question 9

Print the largest wholesale group size and a cautious business proposal.

Write your answer, then run it.

Question 10

Optional — not covered in the final exam. For the five-customer complete-linkage tree, print group counts at cut heights 1,4,11.

Write your answer, then run it.

Reference answers are locked until all 10 attempts are submitted.

← PreviousChapter 3
 

Prof. Xuhu Wan · HKUST ISOM · Introduction to Business Analytics