Data Science project 03
Customer Segmentation Data Science Project
Build a complete customer segmentation workflow with reproducible Python code, traceable calculations, validation checks, and honest limitations.
Explore Data Science training in VizagView all project ideas
Analysis question
What behavioural groups appear in scaled recency, frequency, and monetary-value features?
Dataset
A reproducible synthetic customer table containing recency in days, order count, and revenue for 500 anonymous customer IDs.
Requirements
- Python 3.10 or later
- A terminal or command prompt
python -m pip install numpy pandas scikit-learn- About 45-60 minutes to build and review
Method and data checks
Standardise the three RFM fields, fit four K-means clusters with multiple initialisations, assign a segment number, and profile each segment with medians.
- Feature scaling prevents revenue magnitude from dominating distances
- A fixed seed and n_init make fitting repeatable
- Silhouette score provides a compact separation check
- Profiles use medians to reduce outlier influence
Complete Python code
Save the program as ds_customer_segmentation.py. The dataset generator or loader, analysis functions, output, and reproducibility controls are included.
"""Reproducible RFM customer segmentation with K-means."""
from __future__ import annotations
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler
def make_demo_customers(n: int = 500, seed: int = 42) -> pd.DataFrame:
rng = np.random.default_rng(seed)
return pd.DataFrame({
"customer_id": [f"C{i:04d}" for i in range(1, n + 1)],
"recency_days": rng.integers(1, 365, n),
"orders": np.maximum(1, rng.negative_binomial(3, 0.35, n)),
"revenue": np.round(rng.lognormal(7.3, 0.8, n), 2),
})
def segment_customers(data: pd.DataFrame, clusters: int = 4, seed: int = 42) -> tuple[pd.DataFrame, pd.DataFrame, float]:
features = ["recency_days", "orders", "revenue"]
if len(data) <= clusters:
raise ValueError("Number of rows must exceed the number of clusters")
scaled = StandardScaler().fit_transform(data[features])
labels = KMeans(n_clusters=clusters, random_state=seed, n_init=20).fit_predict(scaled)
result = data.copy()
result["segment"] = labels
profile = result.groupby("segment").agg(customers=("customer_id", "size"), median_recency=("recency_days", "median"), median_orders=("orders", "median"), median_revenue=("revenue", "median")).reset_index()
return result, profile, float(silhouette_score(scaled, labels))
def main() -> None:
_, profile, score = segment_customers(make_demo_customers())
print(f"Silhouette score: {score:.3f}")
print(profile.round(2).to_string(index=False))
print("Segments describe patterns; they do not explain causes or individual intent.")
if __name__ == "__main__":
main()
Run the project
- Create and activate a virtual environment.
- Install dependencies with
python -m pip install numpy pandas scikit-learn. - Run
python ds_customer_segmentation.py. - Reconcile row counts and totals before interpreting patterns.
- Read the limitations before substituting any real dataset.
Expected analytical output
Customer-level segment assignments, a segment profile table, and a silhouette score.
Interpretation and responsible-use limits
Clusters describe patterns in the chosen variables; they do not explain customer motives or guarantee that four groups are commercially useful. Do not use segment numbers to make unfair or sensitive decisions.
Ways to extend the project
Compare cluster counts, test stability across seeds and periods, add cohort context, name segments only after review, and validate actions through controlled experiments.
Continue learning Data Science
Try the next project, return to the Softenant project library, or explore the Data Science course in Vizag for guided data cleaning, analysis, visualisation, and portfolio feedback.