project-015 · Classical ML · retail
Client segments for a wholesale distributor: stable, actionable, and more than the channel label
A food and household-goods distributor wants three to six client segments to set delivery frequency and sales coverage. Do the clients' annual spending patterns support segments that are stable and actionable, and do they add information beyond the existing Horeca/Retail channel label?
- Licence
- CC BY 4.0 (as stated on the UCI page)
- Reference run
- none
At a glance
Data
Wholesale customers (UCI 292) (public) · 440 rows x 8 columns
Details on dataBaseline
Existing Channel label, and simple size tiers (tertiles of total spend). Any clustering must beat these on actionability and stability to be worth the complexity.
Details on baselineValidation
No ground truth. Validation is stability and usefulness: bootstrap Jaccard stability per cluster, split-half replication (fit on one half, assign the other, compare),…
Details on validationMetric
Per-cluster Jaccard stability, silhouette, BIC, split-half agreement (adjusted Rand), adjusted Rand versus Channel.
Details on metric
Success criterion
- Every retained segment has a bootstrap Jaccard stability of at least 0.75 (a practitioner threshold set before fitting) and contains at least 5% of clients.
- Silhouette and, for mixtures, BIC are reported, but the choice of k is justified by stability and actionability, not one index.
- Adjusted Rand index between segments and Channel is reported; segments that merely reproduce Channel are labelled as such.
- A one-page segment profile maps each segment to a proposed delivery or coverage action.
Context
The UCI data describe 440 clients of a wholesale distributor in Portugal: annual spending in monetary units on six product categories, the channel (Horeca 298, Retail 142) and region (Lisbon 77, Oporto 47, Other 316). Spending is strongly right-skewed (for example Fresh ranges from 3 to 112,151 against a mean around 12,000 per the provider's statistics). Clusters always exist in an algorithm's output; whether they are real and useful is the question.
Data
- Dataset
- Wholesale customers (UCI 292) (public)
- Licence
- CC BY 4.0 (as stated on the UCI page)
- Size
- 440 rows x 8 columns
- Verification
- identity verified
Access
Direct download (14.7 KB CSV) or ucimlrepo.fetch_ucirepo(id=292); no account. Fallback: none needed.
Grain
One row per client; spending is annual.
| Column | Meaning |
|---|---|
| Fresh / Milk / Grocery / Frozen | Annual spending (monetary units) per category |
| Detergents_Paper / Delicassen | Annual spending on detergents and paper; delicatessen |
| Channel | Horeca (hotel/restaurant/cafe) or Retail |
| Region | Lisbon, Oporto or Other |
EDA and data-quality rules
Log-transform spending (all values are positive per the provider's minimums) and check the result for remaining extremes.
Separate size from mix: total spend versus category shares; decide which the business segments on.
Identify extreme clients that would form one-member clusters and decide on a handling rule before fitting.
Region imbalance (316 'Other'): report region composition of every segment.
Baseline
Existing Channel label, and simple size tiers (tertiles of total spend). Any clustering must beat these on actionability and stability to be worth the complexity.
Features
Log spending per category, standardized; alternative representation: log total spend plus centred log-ratio shares (mix). Channel and Region are excluded from clustering inputs and used to describe and validate segments. PCA only for visualization.
Candidate methods
k-means with k-means++ initialization on log-standardized features
Simple, fast, and produces centroids the business can read; assumes roughly spherical clusters.
Gaussian mixture model with BIC for the number of components
Allows elliptical clusters and soft membership; BIC gives a likelihood-based view of k.
Ward hierarchical clustering
Shows nested structure and whether segments split naturally at several k.
Validation design
No ground truth. Validation is stability and usefulness: bootstrap Jaccard stability per cluster, split-half replication (fit on one half, assign the other, compare), silhouette and BIC across k = 2-8, and sensitivity to the feature representation and to removing extreme clients.
Leakage checks
Not predictive, but evaluating segments against Channel is circular if Channel is an input; keep it out of the features.
Bias and representativeness
Extreme clients can create one-member "segments"; region imbalance can make 'Other' dominate every profile; clusters are not personas and their names must not imply motives the data do not show.
Robustness checks
Log versus raw scale, absolute versus mix representation, with and without extremes, multiple seeds.
Technical metrics
Per-cluster Jaccard stability, silhouette, BIC, split-half agreement (adjusted Rand), adjusted Rand versus Channel.
Business interpretation
Segment sizes and spend shares, within-segment variation of the categories that drive delivery needs (Fresh, Frozen), and the proposed action per segment.
Error slices
Region composition per segment.
Channel composition per segment.
Extreme-spend clients: which segment absorbs them and how stable is it?
Implementation steps
Download, checksum; run the EDA rules; choose and justify the representation.
Compute baselines (Channel, size tiers).
Fit candidates over k = 2-8; compute silhouette, BIC and bootstrap stability.
Choose k and method by stability and actionability; run split-half and robustness checks.
Write the segment profile with actions and an honest note on what the segments are not.
Reproduction
Learner-built. One command; seeds for initialization and bootstrap in config; pinned environment; small enough to commit derived tables (CC BY 4.0 with attribution).
Limitations
440 clients and six spend variables; segments may not survive more detailed data.
Annual totals hide order frequency and seasonality, which matter for delivery planning.
Monetary units are unspecified; values cannot be compared with other markets.
Production and monitoring
Assign new clients to the nearest centroid with a distance threshold for 'unassigned'; refit yearly; monitor segment sizes and centroid drift; version segment definitions so that reports stay comparable.
Interview questions
k = 2 has the highest silhouette but the commercial team wants five segments. What do you recommend?
How do you show a segment is real rather than an artefact of k-means?
Why log-transform spending before clustering, and what does it change about the segments?
Postmortem and alternatives
A rule-based segmentation on size and mix may be as actionable and easier to maintain; the clustering earns its place only if it finds stable groups the rule misses. Order-level data would allow behaviour-based segments.
Rubric3 criteria
| Criterion | Meets | Exceeds |
|---|---|---|
| Representation choices | Justifies log scale and size-versus-mix representation. | Shows how segments change between representations and picks one for the business question. |
| Validation without labels | Bootstrap stability and silhouette/BIC across k. | Adds split-half replication and robustness to extremes, and drops unstable clusters. |
| Actionability | Profile with one action per segment and comparison with Channel. | Explains what the segments add beyond Channel and size tiers, with evidence. |
References5
- Wholesale customers
Dataset identity and descriptive statistics.
- Cluster-wise assessment of cluster stability
Bootstrap Jaccard stability per cluster.
- Silhouettes: A graphical aid to the interpretation and validation of cluster analysis
Silhouette width and its limits for choosing k.
- k-means++: The Advantages of Careful Seeding
k-means++ initialization.
- An Introduction to Statistical Learning: with Applications in Python
Unsupervised learning: k-means and hierarchical clustering.