Shopping Segments
Part of the Unsupervised Learning section of Coddy's Machine Learning journey. Lesson 48 of 51.
An online plant shop knows its 240 customers only by what they do: orders a year, basket size, share bought on sale and days since the last order.
No one has labelled them. The owner wants a few segments she can describe in plain words, and a win-back email for the one that drifted away.
Let two methods agree on k: a ward tree suggests it, and the silhouette checks it against its neighbors. Then read every segment in real units.
Challenge
HardThe program reads where to cut the tree; the starter sets up a titled chart.
- Scale the features and cut a ward tree there. Print how many segments it makes.
- Print the k-means silhouette (3 decimals) for that k and each neighbor, then the best k.
- Refit with it into
plants["segment"]. Biggest first, letter each segment and print its real-unit means; then the one whose last order is oldest. - Scatter each segment labelled by its letter; legend, show.
For another shop, cut at 8:
Tree cut at 8.0: 3 segments
Silhouette at k = 2: 0.573
Silhouette at k = 3: 0.675
Silhouette at k = 4: 0.630
Best k: 3
A (70): 8.6 orders a year, 29 EUR baskets, 15% on sale, last order 23 days ago
B (50): 3.1 orders a year, 22 EUR baskets, 60% on sale, last order 53 days ago
C (30): 1.8 orders a year, 89 EUR baskets, 10% on sale, last order 148 days ago
Win-back email: segment Cand its chart:
Then Coddy describes yours.
Try it yourself
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from scipy.cluster.hierarchy import linkage, fcluster
# One row per customer of the plant shop
plants = pd.read_csv("plants.csv")
features = ["orders_per_year", "avg_basket_eur", "sale_share_pct", "days_since_order"]
# The height where the owner cuts the shop's tree, read off its dendrogram (3 or more segments)
cut = float(input())
fig, ax = plt.subplots()
ax.set_title("Plant Shop Segments")
ax.set_xlabel("Orders per year")
ax.set_ylabel("Average basket (EUR)")
# Write your code below
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Unsupervised Learning
1Finding Groups
Learning Without LabelsMeasuring SimilarityK-Means by HandK-Means in scikit-learnRecap: Gym Members7PCA in Practice
Seeing 64 DimensionsComponents as PatternsCompress and RebuildPCA Before a ModelRecap: Face Scanner10Project: Digit Explorer
Look at the DigitsShrink with PCACluster the DigitsName the ClustersFind the Odd OnesPractice on your own: Online Python compiler