35
ML
Metrics
Datasets
Advanced Clustering
Advanced clustering algorithms new in v1.0.0: Agglomerative, GaussianMixture, SpectralClustering, OPTICS, MiniBatchKMeans, MeanShift, Birch, and AffinityPropagation. This example uses deepbox/ml, deepbox/metrics, deepbox/datasets and focuses on AgglomerativeClustering, GaussianMixture, SpectralClustering, OPTICS, MiniBatchKMeans, MeanShift, Birch, AffinityPropagation; silhouetteScore, adjustedRandScore; makeBlobs, makeMoons.
Deepbox Modules Used
deepbox/mldeepbox/metricsdeepbox/datasetsWhat You Will Learn
- Use deepbox/ml for AgglomerativeClustering, GaussianMixture, SpectralClustering, OPTICS, MiniBatchKMeans, MeanShift, Birch, AffinityPropagation.
- Use deepbox/metrics for silhouetteScore, adjustedRandScore.
- Use deepbox/datasets for makeBlobs, makeMoons.
- Advanced clustering algorithms new in v1.0.0: Agglomerative, GaussianMixture, SpectralClustering, OPTICS, MiniBatchKMeans, MeanShift, Birch, and AffinityPropagation.
Source Files
index.ts
1/**2 * Example 35: Advanced Clustering3 *4 * New in v1.0.0: Agglomerative, GaussianMixture, SpectralClustering,5 * OPTICS, MiniBatchKMeans, MeanShift, Birch, and AffinityPropagation.6 */78import { makeBlobs, makeMoons } from "deepbox/datasets";9import { adjustedRandScore, silhouetteScore } from "deepbox/metrics";10import {11 AffinityPropagation,12 AgglomerativeClustering,13 Birch,14 GaussianMixture,15 KMeans,16 MeanShift,17 MiniBatchKMeans,18 OPTICS,19 SpectralClustering,20} from "deepbox/ml";2122console.log("=".repeat(60));23console.log("Example 35: Advanced Clustering");24console.log("=".repeat(60));2526// ============================================================================27// Generate synthetic datasets28// ============================================================================2930// Well-separated blobs for standard clustering31const [XBlobs, yBlobs] = makeBlobs({32 nSamples: 200,33 centers: 4,34 clusterStd: 0.8,35 randomState: 42,36});3738// Non-convex moons for advanced methods39const [XMoons, yMoons] = makeMoons({40 nSamples: 200,41 noise: 0.1,42 randomState: 42,43});4445console.log(`Blobs dataset: ${XBlobs.shape[0]} samples, ${XBlobs.shape[1]} features, 4 clusters`);46console.log(`Moons dataset: ${XMoons.shape[0]} samples, ${XMoons.shape[1]} features, 2 clusters`);4748// ============================================================================49// Part 1: MiniBatchKMeans50// ============================================================================51console.log("\n⚡ Part 1: MiniBatchKMeans");52console.log("-".repeat(60));5354// MiniBatchKMeans is a faster variant of KMeans that uses mini-batches55const mbkmeans = new MiniBatchKMeans({56 nClusters: 4,57 batchSize: 50,58 maxIter: 100,59});60mbkmeans.fit(XBlobs);6162const mbkLabels = mbkmeans.predict(XBlobs);63const mbkSil = silhouetteScore(XBlobs, mbkLabels);64const mbkAri = adjustedRandScore(yBlobs, mbkLabels);6566console.log("MiniBatchKMeans (k=4, batchSize=50):");67console.log(` Silhouette Score: ${mbkSil.toFixed(4)}`);68console.log(` Adjusted Rand Index: ${mbkAri.toFixed(4)}`);69console.log(` Cluster centers shape: ${mbkmeans.clusterCenters.shape}`);7071// Compare with standard KMeans72const kmeans = new KMeans({ nClusters: 4, randomState: 42 });73kmeans.fit(XBlobs);74const kmLabels = kmeans.predict(XBlobs);75const kmSil = silhouetteScore(XBlobs, kmLabels);76console.log(` KMeans Silhouette (for comparison): ${kmSil.toFixed(4)}`);7778// ============================================================================79// Part 2: Agglomerative Clustering80// ============================================================================81console.log("\n🌲 Part 2: Agglomerative Clustering");82console.log("-".repeat(60));8384// Agglomerative clustering builds a hierarchy by merging closest clusters85const aggWard = new AgglomerativeClustering({86 nClusters: 4,87 linkage: "ward",88});89aggWard.fit(XBlobs);9091const aggLabels = aggWard.labels;92const aggSil = silhouetteScore(XBlobs, aggLabels);93const aggAri = adjustedRandScore(yBlobs, aggLabels);9495console.log("Agglomerative (Ward linkage, k=4):");96console.log(` Silhouette Score: ${aggSil.toFixed(4)}`);97console.log(` Adjusted Rand Index: ${aggAri.toFixed(4)}`);9899// Try different linkages100for (const linkage of ["complete", "average", "single"] as const) {101 const agg = new AgglomerativeClustering({ nClusters: 4, linkage });102 agg.fit(XBlobs);103 const sil = silhouetteScore(XBlobs, agg.labels);104 console.log(` ${linkage.padEnd(10)} linkage — Silhouette: ${sil.toFixed(4)}`);105}106107// ============================================================================108// Part 3: Gaussian Mixture Model109// ============================================================================110console.log("\n📊 Part 3: Gaussian Mixture Model");111console.log("-".repeat(60));112113// GMM models data as a mixture of Gaussian distributions114const gmm = new GaussianMixture({115 nComponents: 4,116 maxIter: 100,117});118gmm.fit(XBlobs);119120const gmmLabels = gmm.predict(XBlobs);121const gmmSil = silhouetteScore(XBlobs, gmmLabels);122const gmmAri = adjustedRandScore(yBlobs, gmmLabels);123124console.log("Gaussian Mixture (4 components):");125console.log(` Silhouette Score: ${gmmSil.toFixed(4)}`);126console.log(` Adjusted Rand Index: ${gmmAri.toFixed(4)}`);127128// ============================================================================129// Part 4: Spectral Clustering130// ============================================================================131console.log("\n🌀 Part 4: Spectral Clustering");132console.log("-".repeat(60));133134// Spectral Clustering uses eigenvalues of similarity matrix — good for non-convex shapes135const spectral = new SpectralClustering({136 nClusters: 2,137 affinity: "rbf",138 gamma: 10,139});140spectral.fit(XMoons);141142const specLabels = spectral.labels;143const specSil = silhouetteScore(XMoons, specLabels);144const specAri = adjustedRandScore(yMoons, specLabels);145146console.log("Spectral Clustering on Moons (k=2, RBF kernel):");147console.log(` Silhouette Score: ${specSil.toFixed(4)}`);148console.log(` Adjusted Rand Index: ${specAri.toFixed(4)}`);149150// ============================================================================151// Part 5: OPTICS152// ============================================================================153console.log("\n🔬 Part 5: OPTICS");154console.log("-".repeat(60));155156// OPTICS: density-based clustering that doesn't require specifying eps157const optics = new OPTICS({158 minSamples: 5,159});160optics.fit(XBlobs);161162const optLabels = optics.labels;163const optAri = adjustedRandScore(yBlobs, optLabels);164165console.log("OPTICS (minSamples=5):");166console.log(` Adjusted Rand Index: ${optAri.toFixed(4)}`);167console.log(` Reachability values: ${optics.reachability.shape}`);168169// ============================================================================170// Part 6: MeanShift171// ============================================================================172console.log("\n🎯 Part 6: MeanShift");173console.log("-".repeat(60));174175// MeanShift finds clusters by seeking high-density regions176const meanshift = new MeanShift({177 bandwidth: "auto",178});179meanshift.fit(XBlobs);180181const msLabels = meanshift.labels;182const msSil = silhouetteScore(XBlobs, msLabels);183184console.log("MeanShift (auto bandwidth):");185console.log(` Silhouette Score: ${msSil.toFixed(4)}`);186console.log(` Cluster centers shape: ${meanshift.clusterCenters.shape}`);187188// ============================================================================189// Part 7: Birch190// ============================================================================191console.log("\n🌿 Part 7: Birch");192console.log("-".repeat(60));193194// Birch: scalable clustering using CF-tree data structure195const birch = new Birch({196 nClusters: 4,197 threshold: 0.5,198 branchingFactor: 50,199});200birch.fit(XBlobs);201202const birchLabels = birch.labels;203const birchSil = silhouetteScore(XBlobs, birchLabels);204const birchAri = adjustedRandScore(yBlobs, birchLabels);205206console.log("Birch (k=4, threshold=0.5):");207console.log(` Silhouette Score: ${birchSil.toFixed(4)}`);208console.log(` Adjusted Rand Index: ${birchAri.toFixed(4)}`);209210// ============================================================================211// Part 8: Affinity Propagation212// ============================================================================213console.log("\n💬 Part 8: Affinity Propagation");214console.log("-".repeat(60));215216// Affinity Propagation: message-passing algorithm, auto-determines number of clusters217const ap = new AffinityPropagation({218 damping: 0.9,219 maxIter: 200,220});221ap.fit(XBlobs);222223const apLabels = ap.labels;224const apSil = silhouetteScore(XBlobs, apLabels);225226console.log("Affinity Propagation (damping=0.9):");227console.log(` Silhouette Score: ${apSil.toFixed(4)}`);228console.log(` Cluster centers shape: ${ap.clusterCenters.shape}`);229230// ============================================================================231// Summary Comparison232// ============================================================================233console.log("\n📋 Clustering Comparison on Blobs Dataset");234console.log("-".repeat(60));235236console.log("┌─────────────────────────┬────────────┬──────────┐");237console.log("│ Algorithm │ Silhouette │ ARI │");238console.log("├─────────────────────────┼────────────┼──────────┤");239240const comparisons = [241 { name: "KMeans", sil: kmSil, ari: adjustedRandScore(yBlobs, kmLabels) },242 { name: "MiniBatchKMeans", sil: mbkSil, ari: mbkAri },243 { name: "Agglomerative (Ward)", sil: aggSil, ari: aggAri },244 { name: "Gaussian Mixture", sil: gmmSil, ari: gmmAri },245 { name: "MeanShift", sil: msSil, ari: adjustedRandScore(yBlobs, msLabels) },246 { name: "Birch", sil: birchSil, ari: birchAri },247 { name: "Affinity Propagation", sil: apSil, ari: adjustedRandScore(yBlobs, apLabels) },248];249250for (const c of comparisons) {251 const name = c.name.padEnd(23);252 const sil = c.sil.toFixed(4).padStart(10);253 const ari = c.ari.toFixed(4).padStart(8);254 console.log(`│ ${name} │ ${sil} │ ${ari} │`);255}256console.log("└─────────────────────────┴────────────┴──────────┘");257258// ============================================================================259// Summary260// ============================================================================261console.log("\n💡 Key Takeaways");262console.log("-".repeat(60));263console.log("• MiniBatchKMeans: fast KMeans for large datasets using mini-batches");264console.log("• Agglomerative: hierarchical clustering with different linkage criteria");265console.log("• Gaussian Mixture: soft clustering with probabilistic assignments");266console.log("• Spectral: graph-based, excels at non-convex cluster shapes");267console.log("• OPTICS: density-based, no need to specify epsilon parameter");268console.log("• MeanShift: auto-discovers number of clusters via density modes");269console.log("• Birch: memory-efficient, scalable to very large datasets");270console.log("• Affinity Propagation: auto-determines cluster count via message passing");271272console.log("\n✅ Advanced Clustering Example Complete!");273console.log("=".repeat(60));274Console Output
$ npx tsx 35-advanced-clustering/index.ts
See the example README for the expected console and artifact output.