Training Clustering Models: K-Means, DBSCAN, HDBSCAN in Practice

Effective Data Clustering: Training K-Means, DBSCAN, HDBSCAN

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1284
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1240
  • image_logo-advance_0.webp
    B2B Advance company logo design
    696
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_logo-aider_0.webp
    AIDER company logo development
    917
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1031

Effective Data Clustering: Training K-Means, DBSCAN, HDBSCAN

We develop and train clustering models tailored to your data and business goals. Whether it's customer segmentation or text analysis, algorithms like K-Means, DBSCAN, and HDBSCAN form the foundation, but without proper tuning, results can be unsatisfactory. For example, on 500,000 records, naive K-Means yields a silhouette score of 0.19 and excessive noise. The cause is an incorrect choice of cluster count and an algorithm that doesn't account for data shape. Our pipeline automatically selects the algorithm and number of clusters, achieving stable, business-interpretable results.

MiniBatchKMeans with batch_size=2048 runs 10-15 times faster than standard K-Means on datasets >100k records, which is critical for operational analysis. For text data, we use HDBSCAN with preliminary UMAP dimensionality reduction — this allows extracting clusters of arbitrary shape without specifying their count.

The Problems Clustering Solves

Clustering is unsupervised learning that reveals hidden data structures: customer segments, thematic document clusters, anomalous transaction groups. The main problems we address:

  • Incorrect choice of cluster count. The elbow method often gives an ambiguous answer, and subjective selection leads to uninterpretable segments.
  • Scaling to large volumes. K-Means on 1 million records can take minutes; MiniBatchKMeans takes seconds.
  • Text clustering. Classical algorithms perform poorly on Bag-of-Words — embeddings and HDBSCAN are needed.

Our experience shows that a properly tuned clustering pipeline improves segmentation accuracy by up to 40% compared to ad-hoc approaches.

How to Choose a Clustering Algorithm?

Choosing the algorithm is a key decision. Compare the main methods.

Algorithm Cluster Count Cluster Shape Scale Application
K-Means Must specify Spherical >100K Customer segmentation
DBSCAN Auto Any ~50K Anomalies, geodata
HDBSCAN Auto Any >100K Texts, images
Agglomerative Must specify Any ~10K Document hierarchy
GMM Must specify Ellipsoidal ~50K Soft probabilities

In practice, for most tasks we use K-Means with MiniBatch for large data and HDBSCAN for texts and anomalies. GMM is good when clusters overlap.

Detailed quality metrics description
Metric Description Range Good Value
Silhouette Compactness and separation [-1,1] >0.3
Calinski-Harabasz Variance ratio [0,∞) Higher is better
Davies-Bouldin Average cluster similarity [0,∞) Lower is better

A combination of silhouette and Calinski-Harabasz gives a reliable determination of k. In our pipeline, we automatically compute a consensus value.

Practical Pipeline: K-Means with Automatic k Selection

from sklearn.cluster import KMeans, MiniBatchKMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score, calinski_harabasz_score import numpy as np import matplotlib.pyplot as plt class ClusteringPipeline: def __init__(self, scale: bool = True): self.scaler = StandardScaler() if scale else None self.model = None def find_optimal_k(self, X: np.ndarray, k_range: range = range(2, 20)) -> int: """Elbow method + silhouette for determining K""" if self.scaler: X = self.scaler.fit_transform(X) inertias = [] silhouettes = [] for k in k_range: kmeans = MiniBatchKMeans(n_clusters=k, random_state=42, batch_size=1024) labels = kmeans.fit_predict(X) inertias.append(kmeans.inertia_) if len(X) > 50000: sample_idx = np.random.choice(len(X), 10000) sil = silhouette_score(X[sample_idx], labels[sample_idx]) else: sil = silhouette_score(X, labels) silhouettes.append(sil) # Elbow method — inflection point diffs = np.diff(inertias) diffs2 = np.diff(diffs) elbow_k = k_range[np.argmax(diffs2) + 2] # Best silhouette best_sil_k = k_range[np.argmax(silhouettes)] # Consensus: average of two methods optimal_k = (elbow_k + best_sil_k) // 2 print(f"Elbow method: k={elbow_k}, Silhouette: k={best_sil_k}, Chosen: k={optimal_k}") return optimal_k def fit(self, X: np.ndarray, k: int = None): if self.scaler: X_scaled = self.scaler.fit_transform(X) else: X_scaled = X if k is None: k = self.find_optimal_k(X_scaled) self.model = MiniBatchKMeans(n_clusters=k, random_state=42, batch_size=2048, n_init=10) self.labels = self.model.fit_predict(X_scaled) return self def evaluate(self, X: np.ndarray) -> dict: X_scaled = self.scaler.transform(X) if self.scaler else X return { 'silhouette': silhouette_score(X_scaled, self.labels, sample_size=min(10000, len(X))), 'calinski_harabasz': calinski_harabasz_score(X_scaled, self.labels), 'n_clusters': len(np.unique(self.labels)), 'cluster_sizes': dict(zip(*np.unique(self.labels, return_counts=True))) } 

We use MiniBatchKMeans with batch_size=2048 to accelerate on large data. Example: on 500,000 records, the pipeline finds the optimal k in 2 minutes.

Case Study: Retail Customer Segmentation

Recently, we clustered the customer base of a large retailer (2 million records). We used MiniBatchKMeans with consensus k=7. Achieved silhouette of 0.42 — 0.15 higher than the previous solution. The clusters were homogeneous in purchase frequency, average basket size, and categories. The business used the segments for personalized mailings — conversion increased by 18%. The client engineer noted: "Clustering helped identify 7 segments that were previously non-obvious, and this directly impacted conversion."

HDBSCAN for Text Data

import hdbscan from sentence_transformers import SentenceTransformer def cluster_documents(texts: list[str], min_cluster_size: int = 10) -> list[int]: # Embeddings model = SentenceTransformer('all-MiniLM-L6-v2') embeddings = model.encode(texts, batch_size=256, show_progress_bar=True) # Dimensionality reduction before clustering from umap import UMAP umap_model = UMAP(n_components=10, random_state=42, metric='cosine') reduced = umap_model.fit_transform(embeddings) # HDBSCAN clusterer = hdbscan.HDBSCAN( min_cluster_size=min_cluster_size, metric='euclidean', cluster_selection_method='eom', prediction_data=True ) labels = clusterer.fit_predict(reduced) # -1 = noise/outlier print(f"Found {len(np.unique(labels[labels >= 0]))} clusters") print(f"Noise points: {(labels == -1).sum()}") return labels 

In a project clustering support tickets, we processed 100,000 tickets. HDBSCAN identified 15 thematic clusters and 12% noise (anomalous requests). Time-to-insight decreased from a week to an hour.

Work Process: From Analysis to Deployment

Our process includes:

  1. Analysis: defining the goal — what to cluster (customers, documents, transactions) and how to interpret.
  2. Design: choosing the algorithm, metrics, pipeline.
  3. Development: coding, hyperparameter optimization (k, min_cluster_size, distance metric).
  4. Validation: computing silhouette, Calinski-Harabasz, visualization (t-SNE, UMAP), business verification.
  5. Deployment: integration into production, monitoring cluster drift.

Timeline — from 2 to 4 weeks depending on data complexity.

How to Interpret Clusters?

def describe_clusters(X_df: pd.DataFrame, labels: np.ndarray) -> dict: """Automatic description of each cluster""" cluster_descriptions = {} for cluster_id in np.unique(labels): if cluster_id == -1: continue mask = labels == cluster_id cluster_df = X_df[mask] # Cluster centroid in feature space centroid = cluster_df.mean() # Most distinguishing features (above/below average) overall_mean = X_df.mean() diff = (centroid - overall_mean) / X_df.std() top_features = diff.abs().nlargest(5).index.tolist() cluster_descriptions[cluster_id] = { 'size': mask.sum(), 'size_pct': mask.mean(), 'top_features': {f: float(centroid[f]) for f in top_features}, 'centroid': centroid.to_dict() } return cluster_descriptions 

Good clustering has a silhouette score >0.3, business-interpretable clusters, and stability across runs (Jaccard similarity >0.8 between runs).

Cost and Savings

Our typical projects start at $5,000 for a full pipeline, depending on data complexity and volume. In the retail case above, the 18% conversion lift translated to an estimated annual revenue increase of $150,000 — a 30x ROI on the $5,000 investment.

What’s Included in the Work

  • Deliverables:
    • Documentation: report with algorithm choice, cluster descriptions, visualizations.
    • Pipeline code: clean, documented, with README.
    • Monitoring dashboard: silhouette plot, cluster stability.
    • Team training: 1-2 sessions on interpretation and model use.
    • Post-release support: 2 weeks of consultation.

Company Experience

With over 5 years in data science and 50+ clustering projects across retail, finance, and NLP, our team ensures robust and business-relevant results. We have successfully delivered for clients ranging from startups to Fortune 500 companies.

Get a consultation for your project — we will select the optimal algorithm and configure the pipeline for your data. Order clustering model training with quality guarantee.

Learn more about cluster analysis.