পাঠ ৩১ · ৪৫-এর মধ্যে · মডিউল ৫

K-Means ক্লাস্টারিং

K-Means clustering — Lloyd's algorithm
৭ মিনিট পড়া মাঝারি · Intermediate sklearn

এই পাঠে যা শিখবেন

  • K-Means-এর objective function ও Lloyd's iterative algorithm
  • K-Means++ initialization কেন matter
  • $k$ বাছাইয়ের দু'টি methodology — elbow ও silhouette
  • scikit-learn-এ KMeans — Bangladesh telecom customer segmentation
  • K-Means কোথায় ভেঙে পড়ে — non-spherical, varying density

১ · Unsupervised শেখা — label ছাড়া structure

M1-M4 জুড়ে আমরা supervisedSupervised Learningপ্রতিটি training example-এ feature ($X$) ও label ($y$) দু'টোই দেওয়া। মডেল $X \to y$ mapping শেখে। regression ও classification — দু'টোই supervised। learning করেছি — feature ও label দু'টোই থাকে। কিন্তু বাস্তবে অনেক সময় label পাওয়া যায় না — শুধু feature। Daraz-এ ১০ লাখ গ্রাহকের কেনাকাটার ইতিহাস আছে, কিন্তু কেউ "premium" বা "casual" tag দেয়নি। তবু আমরা চাই — গ্রাহকদের এমন গোষ্ঠীতে ভাগ করতে যাতে similar behavior একসাথে থাকে।

এটাই unsupervised learningUnsupervised Learningডেটায় label নেই — মডেল নিজেই pattern, structure বা group আবিষ্কার করে। Clustering, dimensionality reduction, density estimation — এই ছাতার নিচে। — label ছাড়া pattern খোঁজা। সবচেয়ে সাধারণ unsupervised task হলো clustering — point-গুলোকে group-এ ভাগ করা। আর clustering-এর অলিখিত রাজা হলো — K-Means।

Clustering-এর মূল ধারণা

একই ক্লাস্টারের point-গুলো পরস্পরের কাছে; ভিন্ন ক্লাস্টারের point-গুলো দূরে। "কাছে/দূরে" সাধারণত Euclidean দূরত্ব দিয়ে মাপা হয়। আমাদের লক্ষ্য — এমন একটি partition খোঁজা যা within-cluster দূরত্ব minimize করে।

২ · K-Means-এর objective

$n$ টি point $\{\mathbf{x}_1, \ldots, \mathbf{x}_n\}$ ($\mathbf{x}_i \in \mathbb{R}^d$), আমরা $k$ টি centroid $\{\boldsymbol{\mu}_1, \ldots, \boldsymbol{\mu}_k\}$ ও প্রতিটি point-এর জন্য একটি cluster assignment $z_i \in \{1, \ldots, k\}$ খুঁজি। Objective — WCSS (within-cluster sum of squares):

$$J(\boldsymbol{\mu}, \mathbf{z}) = \sum_{i=1}^n \| \mathbf{x}_i - \boldsymbol{\mu}_{z_i} \|^2$$

প্রতিটি point থেকে তার assigned centroid পর্যন্ত squared দূরত্বের যোগ। ছোট মান = টাইট cluster। এই $J$-কে অন্য নামেও ডাকা হয় — inertia (sklearn-এ এই নাম)।

$J$ একই সাথে $\boldsymbol{\mu}$ ও $\mathbf{z}$-এর উপর নির্ভরশীল — দু'টোই unknown। যৌথভাবে minimize NP-hard। তাই Lloyd সরল বিকল্প — pairwise alternation।

৩ · Lloyd's algorithm — দু'টি ধাপের পুনরাবৃত্তি

Stuart Lloyd (১৯৫৭, Bell Labs)-এর কালজয়ী idea — যৌথ optimize কঠিন, কিন্তু একে fix করে অন্য optimize সহজ। তাই alternating:

ধাপ ০ (Initialization): $k$ টি random centroid বাছাই (বা smart — K-Means++)।

ধাপ ১ (Assignment / "E-step"): প্রতিটি point-কে নিকটতম centroid-এ assign:

$$z_i = \arg\min_{j} \|\mathbf{x}_i - \boldsymbol{\mu}_j\|^2$$

ধাপ ২ (Update / "M-step"): প্রতিটি ক্লাস্টারের নতুন centroid = সেই ক্লাস্টারের সব point-এর গড়:

$$\boldsymbol{\mu}_j = \frac{1}{|C_j|} \sum_{i \in C_j} \mathbf{x}_i$$

ধাপ ৩: ১ ও ২ পুনরাবৃত্তি যতক্ষণ assignment বদলায় না (convergence)।

ভাবুন ঢাকা শহরের বিভিন্ন এলাকায় ১০০ গ্রাহক ছড়ানো। আপনি ৫টি delivery hub খুলবেন। প্রথমে ৫টি random জায়গায় hub বসান। তারপর প্রতিটি গ্রাহক নিকটতম hub-এ যায় (assignment)। প্রতিটি hub তার গ্রাহকদের কেন্দ্রে সরে যায় (update)। আবার প্রতিটি গ্রাহক নিকটতম hub বাছে — হয়তো এবার hub বদলেছে কেউ। এভাবে চলতে থাকে যতক্ষণ hub-এর অবস্থান স্থির হয়।

৪ · Convergence — কেন থামে?

প্রতিটি ধাপে $J$ কমে অথবা একই থাকে — কখনো বাড়ে না। কারণ:

  • Assignment ধাপে: প্রতিটি point-কে নিকটতম centroid-এ পাঠালে — সেই point-এর contribution $\|\mathbf{x}_i - \boldsymbol{\mu}_{z_i}\|^2$ minimum। তাই $J$ ↓।
  • Update ধাপে: ক্লাস্টারের mean = সেই ক্লাস্টারের sum-of-squared-distance-এর minimizer (calculus দিয়ে প্রমাণ)। তাই $J$ ↓।

$J$ যেহেতু lower bound (≥ 0) ও monotonically decreasing — algorithm finite ধাপে থামে। তবে — সম্পূর্ণ global minimum-এ পৌঁছানোর গ্যারান্টি নেই। শুধু local minimum।

৫ · Initialization-এর গুরুত্ব — K-Means++

Random initialization-এ ভাগ্য খারাপ হলে — দু'টি random centroid দু'টি কাছাকাছি জায়গায় পড়তে পারে, ক্লাস্টার merge হয়ে যায়। সমাধান K-Means++ (Arthur-Vassilvitskii, ২০০৭):

  1. প্রথম centroid — uniformly random একটি point।
  2. পরের প্রতিটি centroid — ইতিমধ্যে নির্বাচিত centroid থেকে দূরের point-এর pick হওয়ার সম্ভাবনা বেশি (proportional to $D(\mathbf{x})^2$)।
  3. $k$ centroid না হওয়া পর্যন্ত পুনরাবৃত্তি।

sklearn-এ default init="k-means++" — তাই এটা বেশিরভাগ সময় হয়েই যাচ্ছে। সাথে n_init=10 মানে ১০বার আলাদা init-এ চালিয়ে best solution রাখে।

K-Means — Lloyd's iteration assign → update → repeat ধাপ ০ · Init random centroid ধাপ ১ · Assign নিকটতম centroid → color ধাপ ২ · Update centroid = মানে গড় পুনরাবৃত্তি যতক্ষণ centroid বদলায়
Lloyd's algorithm — random init → প্রতিটি point নিকটতম centroid-এ → centroid = ক্লাস্টার-গড় → পুনরাবৃত্তি যতক্ষণ স্থির।

৬ · $k$ কত হবে — Elbow ও Silhouette

K-Means-এর সবচেয়ে কঠিন প্রশ্ন — $k$ কী? Algorithm নিজে বলবে না। দু'টি জনপ্রিয় heuristic:

Elbow method: $k = 1, 2, \ldots, 10$-এ inertia plot। যেখানে inertia "elbow"-এর মত ভাঁজ — সেটাই $k$। কারণ — এর পর আরও cluster যোগ করলে inertia কমার হার slow।

Silhouette score: প্রতিটি point-এর জন্য:

$$s(i) = \frac{b(i) - a(i)}{\max(a(i), b(i))}$$

যেখানে $a(i)$ = নিজের ক্লাস্টারে গড় দূরত্ব, $b(i)$ = নিকটতম other ক্লাস্টারে গড় দূরত্ব। $s \in [-1, 1]$ — ১ মানে চমৎকার, ০ মানে boundary, ঋণাত্মক মানে ভুল ক্লাস্টারে। সব point-এর গড় $\bar{s}$ যে $k$-তে maximum — সেটাই বাছাই।

৭ · sklearn-এ K-Means — telecom case study

Bangladesh-এর একটি telecom কোম্পানির গ্রাহকদের ৩টি feature: monthly recharge (BDT), call duration (min), data usage (GB)। ১০০০ গ্রাহককে clusters-এ ভাগ করি।

Python · sklearn
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# synthetic Bangladesh telecom users
np.random.seed(0)
n = 1000
recharge = np.concatenate([np.random.normal(150, 30, 400),     # low-tier
                           np.random.normal(450, 60, 400),     # mid-tier
                           np.random.normal(1200, 200, 200)])  # heavy
duration = np.concatenate([np.random.normal(50,  15, 400),
                           np.random.normal(180, 40, 400),
                           np.random.normal(400, 80, 200)])
data_gb  = np.concatenate([np.random.normal(0.5, 0.2, 400),
                           np.random.normal(3.0, 0.8, 400),
                           np.random.normal(12,  3,   200)])

X = np.column_stack([recharge, duration, data_gb])

# scaling অপরিহার্য — না হলে recharge dominate
X_scaled = StandardScaler().fit_transform(X)

kmeans = KMeans(n_clusters=3, init="k-means++",
                n_init=10, random_state=0)
labels = kmeans.fit_predict(X_scaled)

print("Cluster sizes:", np.bincount(labels))
print(f"Inertia (WCSS): {kmeans.inertia_:.1f}")
print("Centroids (scaled):\n", kmeans.cluster_centers_.round(2))

    
৩টি cluster পাওয়া উচিত — low/mid/heavy user। Cluster size প্রায় ৪০০, ৪০০, ২০০ — যেমন data generate করা। Centroid-এর scaled coordinate দেখলে কোন ক্লাস্টারে কী pattern বুঝবেন। Marketing team এই segmentation-এর ওপর tailored offer বানাতে পারে।

৮ · Elbow ও silhouette plot

Python · sklearn
from sklearn.metrics import silhouette_score

inertias, silhouettes = [], []
for k in range(2, 9):
    km = KMeans(n_clusters=k, n_init=10, random_state=0).fit(X_scaled)
    inertias.append(km.inertia_)
    silhouettes.append(silhouette_score(X_scaled, km.labels_))

print("k\tinertia\t\tsilhouette")
for k, i, s in zip(range(2, 9), inertias, silhouettes):
    print(f"{k}\t{i:.1f}\t\t{s:.3f}")

    
Inertia $k$-এর সাথে কমতে থাকে — কিন্তু $k=3$-এ "elbow"। Silhouette সাধারণত $k=3$-এ সর্বোচ্চ — দু'টিই একই $k$ suggest করছে। যদি দু'টি পদ্ধতি ভিন্ন কথা বলে — domain knowledge দিয়ে decide।

৯ · K-Means কোথায় ভেঙে পড়ে

  • Non-spherical cluster: দু'টি concentric ring — K-Means ভুল ভাগ করবে। এজন্য DBSCAN বা spectral clustering।
  • Varying density/size: একটি বড় sparse cluster ও একটি ছোট dense — K-Means বড়টিকে ভেঙে ফেলে।
  • Outlier: mean outlier-এ টানা যায় → centroid বিকৃত। K-Medoids ভাল alternative।
  • High dimension: curse of dimensionality — দূরত্ব meaningless। আগে PCA।
  • $k$ আগে দিতে হয়: data-driven নয় — heuristic দিয়ে বেছে নিতে হয়।
Scaling না করে K-Means কখনো নয়। Recharge ১৫০-১২০০, data GB ০.৫-১২ — scale না করলে recharge dominate করবে, data-র signal হারাবে। সবসময় StandardScaler বা MinMaxScaler।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ K-Means শুধু local minimum guarantee দেয়। তাহলে production-এ এটা trust কেন? K-Means++ ও multiple init কতদূর সমাধান?

চমৎকার — প্রকৃত optimization theory-এর প্রশ্ন। K-Means NP-hard problem-এর greedy approximation। Practical কেন কাজ করে — উত্তর তিন ভাগে।

(১) Local minima বনাম global:

  • Random init-এ একটি বড় ঝুঁকি — দু'টি কাছাকাছি cluster একই centroid নিয়ে নেয়, একটি দূরের cluster ভাগ হয়ে যায়।
  • Inertia minimize করলেও — semantic অর্থে ভুল clustering।
  • Data-এ যত বেশি well-separated cluster — local minimum-এর সংখ্যা কম, convergence-এ একই solution।

(২) K-Means++ — provable bound:

  • Arthur-Vassilvitskii (২০০৭) প্রমাণ করেছেন — K-Means++ initialization $O(\log k)$-competitive।
  • অর্থাৎ — global optimum-এর $\log k$ গুণের মধ্যে expected solution।
  • Random-এর তুলনায় ৫-১০× বেশি সম্ভাবনা ভাল solution-এর।

(৩) Multiple init (n_init):

  • sklearn default n_init=10 — ১০বার আলাদা init-এ চালিয়ে best inertia রাখে।
  • Probability(সব ১০ বারই bad init) → vanishingly small।
  • Cost — ১০× compute, কিন্তু K-Means দ্রুত — usually OK।

Production-এ practical assurance:

  • Stability check: ভিন্ন seed-এ run করে cluster assignment-এর agreement মাপুন (ARI score)।
  • Silhouette consistency: ভিন্ন init-এ silhouette একই থাকলে — solution stable।
  • Domain validation: cluster-এর interpretation business-এ বোঝায় কি?
  • Mini-batch K-Means: বড় ডেটায় — কিছুটা noisy কিন্তু online updateable।

কখন trust হয় না:

  • High-dim, noisy data — different init-এ very different result।
  • Cluster শুধু marginally separated।
  • $k$ ভুল।

মূল উপলব্ধি: K-Means heuristic, কিন্তু practically robust algorithm — কারণ K-Means++ ও n_init-এর combo বেশিরভাগ realistic dataset-এ near-optimal solution-এ নিয়ে যায়। Production-এ stability check + domain validation-ই গ্যারান্টি।

প্র ০২ $k$ বাছাইয়ে elbow ও silhouette কোনটা ভাল? এই দু'টি ছাড়া আর কোন criterion আছে?

$k$ selection — clustering-এর সবচেয়ে অস্পষ্ট সিদ্ধান্ত। কোনো single "correct" উত্তর নেই।

Elbow method:

  • সবচেয়ে সরল — visual inspection।
  • Subjective — "elbow" কোথায় ব্যাখ্যাকারীর ওপর নির্ভরশীল।
  • Strong elbow না থাকলে useless।
  • Computationally cheap।

Silhouette score:

  • Quantitative — single number।
  • Geometric meaning — within vs between cluster compactness।
  • $O(n^2)$ — বড় ডেটায় ধীর।
  • Spherical cluster assume — non-convex-এ misleading।

আরও criteria:

  • Calinski-Harabasz index: between-cluster variance / within-cluster variance। বড় = ভাল। দ্রুত।
  • Davies-Bouldin index: cluster-এর "similarity"-এর গড় (with nearest)। ছোট = ভাল।
  • Gap statistic (Tibshirani, ২০০১): actual inertia বনাম random data-এর expected inertia compare।
  • BIC/AIC (Gaussian Mixture): probabilistic — model selection-এ classical।
  • X-means: K-Means-এর extension যা $k$ auto-select।
  • Stability/bootstrap: subsample-এ similar result কতটা।

Best practice — multiple criteria:

  • Elbow + silhouette + domain knowledge — তিনটিই agree করলে confident।
  • সব disagree হলে — হয়তো clustering structure-ই দুর্বল।
  • Business interpretability — final tiebreaker।

Bangladesh telecom context:

  • Marketing team প্রায়ই ৩-৫টি tier চায় (low/mid/high/premium/VIP) — domain $k$ আগে fix করতে পারে।
  • Statistical "best" $k=4$ হলেও business-এ ৫টি tier দরকার হলে — split প্রয়োগ।
  • "Best $k$" ≠ "useful $k$"।

মূল উপলব্ধি: $k$ selection statistical optimization নয়, business decision। Multiple criteria + domain knowledge — একমাত্র sane পদ্ধতি।

প্র ০৩ K-Means বনাম Gaussian Mixture Model (GMM) — কোথায় কোনটা? GMM-কে কি "soft K-Means" বলা যায়?

চমৎকার comparison। GMM ও K-Means গভীরভাবে সম্পর্কিত — কিন্তু philosophy ভিন্ন।

K-Means:

  • Hard assignment — প্রতিটি point ঠিক একটি cluster-এ।
  • Spherical, equal-variance cluster assume।
  • Distance-based।
  • Fast, simple।

GMM (Gaussian Mixture Model):

  • Soft assignment — প্রতিটি point প্রতিটি cluster-এ একটি probability।
  • Elliptical (covariance matrix) cluster — orientation, shape ভিন্ন হতে পারে।
  • Probabilistic — likelihood maximize (EM algorithm — L39)।
  • Slower, parameter বেশি।

GMM = soft K-Means?

  • আংশিক সত্য — covariance যদি spherical ও equal হয়, K-Means GMM-এর hard limit।
  • EM algorithm-এ E-step → soft assignment (responsibilities), M-step → mean ও covariance update।
  • K-Means = EM-এর approximation যেখানে responsibility দু'টি মাত্র {০, ১}।

কখন GMM:

  • Cluster overlap থাকে — soft assignment বাস্তবিক (e.g., topic modeling)।
  • Elongated/elliptical cluster shape।
  • Probability output দরকার (e.g., density-based outlier detection)।
  • Cluster size/density unequal।

কখন K-Means:

  • Large data, fast iteration দরকার।
  • Cluster well-separated, spherical।
  • Hard assignment-ই business-এ যথেষ্ট।
  • Interpretability সরল।

Bangladesh case:

  • Dhaka traffic — যানবাহন speed-volume-এ overlap। GMM ভাল।
  • Telecom user tier — clean separation, K-Means OK।
  • Document topic — GMM (LDA-এর precursor)।
  • Image segmentation — GMM (color distribution overlap)।

Hybrid approach:

  • K-Means দিয়ে quick initialize, তারপর GMM refine।
  • K-Means cluster-গুলোকে GMM init হিসেবে use।
  • 10-100× faster convergence।

মূল উপলব্ধি: K-Means simple but rigid; GMM flexible but expensive। Production-এ K-Means বেশি দেখা যায় শুধু simplicity-র জন্য — but cluster overlap থাকলে GMM superior।

প্র ০৪ Customer segmentation-এ ১ মিলিয়ন গ্রাহক, ১০০ feature। Naive K-Means slow — কী optimization আছে?

Million-row K-Means production বাস্তবতা — Daraz, bKash, GrameenPhone-এ এমন scale। সরাসরি sklearn KMeans on full data — RAM-এ fit হলেও slow।

Computational complexity:

  • প্রতি iteration $O(nkd)$ — $n$ point, $k$ cluster, $d$ dimension।
  • $n=10^6, k=10, d=100$ → প্রতি iteration ১০⁹ operation।
  • ১০-৫০ iteration → ১০-৫০ বিলিয়ন।

(১) MiniBatchKMeans:

  • প্রতি iteration-এ random batch (default ১০২৪) ব্যবহার।
  • Centroid online update — moving average।
  • ১০০× faster, কিছুটা noisier solution।
  • sklearn-এ MiniBatchKMeans(n_clusters=10, batch_size=1024)।

(২) Dimensionality reduction first:

  • PCA দিয়ে ১০০-D → ২০-D (L34)।
  • ৫× faster, signal preserved (যদি variance retain ৯৫%)।
  • Curse of dimensionality-এর কামড় কম।

(৩) Sample first, refine after:

  • ১০K random sample-এ K-Means → centroid।
  • Full data-এ একবার assignment।
  • Centroid update full data-এ একবার।
  • Hybrid speed/quality।

(৪) Approximate nearest neighbor:

  • Assignment ধাপে exact nearest centroid খোঁজা — bottleneck।
  • FAISS, Annoy, HNSW — approximate কাছের centroid দ্রুত।
  • $k$ বড় হলে (১০০+) extreme speedup।

(৫) Distributed:

  • Spark MLlib KMeans — petabyte data।
  • Each worker partial assignment, driver-এ centroid update।
  • Daraz scale-এ এটাই প্রমাণিত পথ।

(৬) GPU acceleration:

  • cuML (RAPIDS) — sklearn-API GPU implementation।
  • 10-100× speedup typical।
  • Distance computation embarrassingly parallel।

Recommended pipeline:

  1. Random sample ১০০K।
  2. StandardScaler + PCA (variance ৯৫%)।
  3. K-Means++ init, n_init=১০।
  4. Best centroid full data-এ assignment (একবার)।
  5. Centroid update + একবার iteration।

Memory concern:

  • $10^6 \times 100$ float32 = 400 MB — fit হবে।
  • distance matrix $n \times k$ = 40 MB — OK।
  • Pairwise distance ($n \times n$) — 4 TB — কখনো computer।

মূল উপলব্ধি: Million-row K-Means MiniBatch + dimensionality reduction-এর combo দিয়ে minutes-এ চলে। Pure speed-এর জন্য GPU বা Spark। Production secret — exact algorithm rare; smart approximation ই rule।

অনুশীলন

  1. হিসাব করুন: তিনটি 1-D point — ${1, 2, 9}$। K-Means $k=2$, init centroid $\mu_1=1, \mu_2=8$। দু'টি iteration হাতে চালান। Converged centroid কী?
    • Iter 1 assign: 1→μ₁ (dist 0 vs 7), 2→μ₁ (dist 1 vs 6), 9→μ₂ (dist 8 vs 1)। Cluster 1 = {1, 2}, Cluster 2 = {9}।
    • Iter 1 update: μ₁ = (1+2)/2 = 1.5; μ₂ = 9।
    • Iter 2 assign: 1→μ₁ (0.5 vs 8), 2→μ₁ (0.5 vs 7), 9→μ₂। Same assignment।
    • Convergence: assignment unchanged → stop। Final: μ₁=1.5, μ₂=9।
    • Inertia = (1-1.5)² + (2-1.5)² + (9-9)² = 0.25 + 0.25 + 0 = 0.5।
  2. NumPy-তে চেষ্টা: নিজের mini K-Means লিখুন (sklearn ছাড়া)।
    import numpy as np
    
    def kmeans(X, k, n_iter=20, seed=0):
        rng = np.random.default_rng(seed)
        # K-Means++ এর সরলরূপ — random init
        idx = rng.choice(len(X), k, replace=False)
        centroids = X[idx].copy()
        for _ in range(n_iter):
            # assign
            dists = np.linalg.norm(X[:, None] - centroids[None, :], axis=2)
            labels = dists.argmin(axis=1)
            # update
            new_c = np.array([X[labels == j].mean(axis=0)
                              if (labels == j).any() else centroids[j]
                              for j in range(k)])
            if np.allclose(new_c, centroids): break
            centroids = new_c
        return labels, centroids
    
    X = np.array([[1.0], [2.0], [9.0]])
    labels, c = kmeans(X, k=2)
    print("labels:", labels, "centroids:", c.ravel())
  3. ভাবুন: Bangladesh-এ একটি hospital chain রোগীদের clusters-এ ভাগ করতে চায় — preventive care planning। কোন ৪টি feature নেবেন? K-Means-এর সমস্যা কী হতে পারে?
    • Features: বয়স, BMI, blood pressure (গড়), glucose level (HbA1c)।
    • Scaling অপরিহার্য: বয়স ০-১০০, glucose ৪-১৫ — ভিন্ন scale।
    • $k$ বাছাই: domain — "low/medium/high risk" → $k=3$।
    • সমস্যা: patient cluster non-spherical (diabetic + obese একসাথে), GMM ভাল হতে পারে।
    • Outlier: rare condition (organ failure) — K-Medoids বা DBSCAN।
    • Sensitive feature: ethnicity, religion যোগ করা ethical concern।
    • Validation: doctor-এর domain expertise দিয়ে cluster interpretation check।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

কোড রানার কাজ না করলে? Google Colab ব্যবহার করুন।
পূর্ববর্তী পাঠ
পাঠ ৩০ · SVR