The Story That Explains Hierarchical Clusteringवह कहानी जो Hierarchical Clustering समझाती है一个讲清层次聚类的故事
She picks up the two books that feel most similar (same subject, same author) and puts them together. Then she looks again, finds the next closest pair (or a book closest to an existing pile), and merges them. She keeps going — always merging the two closest piles — until everything is in one big pile.
At any moment she could stop and say: "These groups make sense for my library." The full history of every merge is drawn as a branching diagram called a dendrogram.
That is Hierarchical Clustering: it builds a complete tree of merges, so you can cut the tree at any level and get any number of clusters — without choosing K in advance.
वह वे दो किताबें उठाती है जो सबसे ज़्यादा मिलती-जुलती लगती हैं (एक ही विषय, एक ही लेखक) और उन्हें साथ रख देती है। फिर दोबारा देखती है, अगला सबसे पास का जोड़ा (या किसी ढेर के सबसे पास वाली किताब) खोजती है, और उन्हें मिला देती है। वह यही करती रहती है — हमेशा दो सबसे पास वाले ढेर मिलाती है — जब तक सब एक बड़े ढेर में न आ जाए।
किसी भी पल वह रुककर कह सकती है: "ये groups मेरी library के लिए सही हैं।" हर merge का पूरा इतिहास एक शाखाओं वाले चित्र में बनता है, जिसे dendrogram कहते हैं।
यही Hierarchical Clustering है: यह merges का पूरा पेड़ बनाता है, ताकि आप पेड़ को किसी भी स्तर पर काटकर जितने चाहें उतने clusters पा सकें — पहले से K चुने बिना।
她拿起两本感觉最相似的书(同一主题、同一作者),把它们放在一起。然后再看一遍,找出下一对最接近的书(或离某个书堆最近的一本),把它们合并。 她一直这样做 —— 每次都合并最接近的两堆 —— 直到所有书都在一大堆里。
任何时刻她都可以停下来说:“这些分组对我的图书馆来说很合理。”每一次合并的完整历史被画成一张分叉图,叫作树状图(dendrogram)。
这就是层次聚类(Hierarchical Clustering):它构建一棵完整的合并树,你可以在任何高度切开这棵树,得到任意数量的簇 —— 无需事先指定 K。
Hierarchical clustering is one of the oldest and easiest-to-explain clustering methods in unsupervised machine learning. Unlike K-Means — where you must choose the number of clusters before you begin — hierarchical clustering builds a full nested structure of groups and lets you choose the level of detail after you have seen the data.
Hierarchical clustering, unsupervised machine learning के सबसे पुराने और समझाने में सबसे आसान clustering तरीकों में से एक है। K-Means के उलट — जहाँ शुरू करने से पहले clusters की संख्या चुननी पड़ती है — hierarchical clustering groups का पूरा nested ढाँचा बनाता है और data देखने के बाद detail का स्तर चुनने देता है।
层次聚类是无监督机器学习中最古老、也最容易解释的聚类方法之一。与 K-Means 不同 —— K-Means 必须在开始前确定簇的个数 —— 层次聚类会构建一个完整的嵌套分组结构,让你在看过数据之后再决定要多细的分组。
The result is not a flat split (like K-Means) but a tree of nested clusters. Every cluster at a higher level contains all the points of the clusters below it. This tree is called a dendrogram, and it is the signature output of the method.
नतीजा एक सपाट बँटवारा (K-Means जैसा) नहीं, बल्कि nested clusters का पेड़ होता है। ऊपर के स्तर का हर cluster अपने नीचे के clusters के सभी points रखता है। इस पेड़ को dendrogram कहते हैं, और यही इस तरीके की पहचान है।
结果不是像 K-Means 那样的平铺划分,而是一棵嵌套簇的树。较高层的每个簇都包含其下方各簇的全部点。 这棵树叫作树状图(dendrogram),是这种方法的标志性输出。
Hierarchical Clustering in Pictures — Understand It Before the Mathsतस्वीरों में Hierarchical Clustering — गणित से पहले समझें图解层次聚类 — 先看懂,再学公式
Six words are enough to read every dendrogram on this page. Learn them from the pictures first.
इस page का हर dendrogram पढ़ने के लिए छह शब्द काफ़ी हैं। पहले इन्हें तस्वीरों से सीखें।
读懂本页所有树状图,只需要六个词。先通过图片学会它们。
Everyday trees you already knowरोज़ के पेड़ जिन्हें आप पहले से जानते हैं你早已熟悉的日常“树”
| Everyday thingरोज़ की चीज़日常事物 | How it is like hierarchical clusteringयह hierarchical clustering जैसा कैसे है它与层次聚类的相似之处 |
|---|---|
| 🌳 Family tree🌳 Family tree🌳 家谱 | Siblings join first (very similar), then cousins, then the whole family. The height of a join = how distant the relatives are.पहले भाई-बहन जुड़ते हैं (बहुत मिलते-जुलते), फिर cousins, फिर पूरा परिवार। जोड़ की ऊँचाई = रिश्तेदार कितने दूर हैं।先是兄弟姐妹(非常相似),再是堂表亲,最后是整个家族。连接的高度 = 亲戚关系有多远。 |
| 🏆 Sports tournament bracket🏆 Sports tournament bracket🏆 体育比赛对阵表 | Read it backwards: pairs join round by round until one champion "cluster" is left.इसे उल्टा पढ़ें: जोड़े round-दर-round मिलते जाते हैं जब तक एक champion "cluster" न बचे।倒过来看:每一轮两两合并,直到只剩一个冠军“簇”。 |
| 📁 Folders on your computer📁 Computer के folders📁 电脑里的文件夹 | Files inside sub-folders inside folders: nested groups. You choose how deep to look.Folders के अंदर sub-folders के अंदर files: nested groups. कितना गहरा देखना है, आप चुनते हैं।文件夹里套子文件夹,子文件夹里放文件:嵌套分组。看多深由你决定。 |
| 🐾 Tree of life (biology)🐾 Tree of life (biology)🐾 生命之树(生物学) | Humans and chimps join low, dogs join higher, fish join near the top. Exactly a dendrogram.इंसान और chimps नीचे जुड़ते हैं, कुत्ते ऊपर, मछलियाँ लगभग सबसे ऊपर। बिल्कुल dendrogram.人和黑猩猩在低处相连,狗在更高处,鱼几乎在顶端。完全就是一张树状图。 |
Start with every point alone, keep joining the two closest groups, and write down how far apart they were each time. That written record is the dendrogram. Linkage decides what "closest groups" means; the cut decides how many clusters you keep.
हर point को अकेले शुरू करें, बार-बार दो सबसे पास वाले groups जोड़ें, और हर बार लिखें कि वे कितने दूर थे। वही लिखा हुआ record dendrogram है। Linkage तय करता है कि "सबसे पास वाले groups" का मतलब क्या है; cut तय करता है कि आप कितने clusters रखेंगे।
每个点先各自为一组,然后不断合并最接近的两组,并记下每次合并时它们相距多远。 这份记录就是树状图。连接方式决定“最接近的两组”是什么意思;切割位置决定你保留几个簇。
Two Flavours — Agglomerative vs Divisiveदो तरीके — Agglomerative vs Divisive两种方式 — 凝聚式 vs 分裂式
There are two directions to build a hierarchy: from the bottom up, or from the top down.
Hierarchy बनाने की दो दिशाएँ हैं: नीचे से ऊपर, या ऊपर से नीचे।
构建层次结构有两个方向:自底向上,或自顶向下。
Both directions describe a tree of nested groups. Note: they do not always produce the same tree — agglomerative makes the best choice at the bottom, divisive at the top.
दोनों दिशाएँ nested groups का एक पेड़ बताती हैं। ध्यान दें: वे हमेशा एक ही पेड़ नहीं बनातीं — agglomerative नीचे सबसे अच्छा चुनाव करता है, divisive ऊपर।
两个方向描述的都是嵌套分组的树。注意:它们不一定得到同一棵树 —— 凝聚式在底层做最优选择,分裂式在顶层做最优选择。
When people say "hierarchical clustering" they almost always mean agglomerative clustering. Divisive methods are elegant but rarely found in mainstream ML libraries. This tutorial focuses on agglomerative clustering.
जब लोग "hierarchical clustering" कहते हैं तो लगभग हमेशा उनका मतलब agglomerative clustering होता है। Divisive तरीके सुंदर हैं पर आम ML libraries में कम मिलते हैं। यह tutorial agglomerative clustering पर ध्यान देता है।
人们说“层次聚类”时,几乎总是指凝聚式聚类。分裂式方法很优雅,但主流机器学习库中很少提供。本教程重点讲凝聚式聚类。
Step by Step: How Agglomerative Clustering WorksStep by Step: Agglomerative Clustering कैसे काम करता है一步一步:凝聚式聚类如何运作
| A | B | C | D | E | |
|---|---|---|---|---|---|
| A | — | 10 | 50 | 70 | 90 |
| B | 10 | — | 45 | 65 | 85 |
| C | 50 | 45 | — | 20 | 60 |
| D | 70 | 65 | 20 | — | 40 |
| E | 90 | 85 | 60 | 40 | — |
Orange cell = the smallest distance, merged next. Green = distances to the newly merged cluster, with the calculation shown below. Switch the linkage to see how the heights change (complete uses max, average uses the mean).
नारंगी cell = सबसे छोटी दूरी, जो अगली merge होगी। हरा = नए merged cluster तक की दूरियाँ, नीचे गणना के साथ। Linkage बदलकर देखें कि heights कैसे बदलती हैं (complete max लेता है, average औसत)।
橙色格子 = 最小距离,下一步就合并它。绿色 = 到新合并簇的距离,计算过程显示在下方。切换连接方式,看看合并高度如何变化(全连接取最大值,平均连接取均值)。
With single linkage the merge heights are 10, 20, 40, 45. Cut at height 30 and you get 2 clusters: {A, B} and {C, D, E}. Cut at height 15 and you get 3 clusters: {A, B}, {C, D}, {E}. One run gives you every possible clustering at once — the main advantage over K-Means. Switch to complete linkage in the simulator: the order of merges stays the same here, but the heights become 10, 20, 60, 90.
Single linkage में merge heights 10, 20, 40, 45 हैं। Height 30 पर काटें तो 2 clusters मिलते हैं: {A, B} और {C, D, E}. Height 15 पर काटें तो 3 clusters: {A, B}, {C, D}, {E}. एक run सभी संभव clusterings एक साथ देता है — K-Means पर यही मुख्य बढ़त है। Simulator में complete linkage चुनें: यहाँ merges का क्रम वही रहता है, पर heights 10, 20, 60, 90 हो जाती हैं।
单连接下的合并高度是 10、20、40、45。在高度 30 处切,得到 2 个簇:{A, B} 和 {C, D, E}。 在高度 15 处切,得到 3 个簇:{A, B}、{C, D}、{E}。运行一次就同时得到所有可能的聚类 —— 这是相对 K-Means 的主要优势。 在模拟器中换成全连接:这里的合并顺序不变,但高度变成 10、20、60、90。
Now with 12 points on a mapअब map पर 12 points के साथ现在换成地图上的 12 个点
Left: 12 points; the orange line joins the two groups merged last. Right: the dendrogram growing — the height of each joint is the merge distance. Move "Cut into" to choose the number of clusters, and try different linkages.
बाएँ: 12 points; नारंगी line आख़िरी merge हुए दो groups को जोड़ती है। दाएँ: बढ़ता dendrogram — हर जोड़ की ऊँचाई merge की दूरी है। Clusters की संख्या चुनने के लिए "इतने में काटें" खिसकाएँ, और अलग linkages आज़माएँ।
左:12 个点,橙色线连接最近一次合并的两组。右:逐步生长的树状图 —— 每个连接点的高度就是合并距离。拖动“切成”选择簇数,并试试不同的连接方式。
Linkage Criteria — How to Measure Distance Between ClustersLinkage Criteria — Clusters के बीच दूरी कैसे मापें连接准则 — 如何度量簇与簇之间的距离
Once two points form a cluster, how far is that cluster from the others? The rule that answers this is the linkage criterion. It is the most important choice in hierarchical clustering.
जब दो points एक cluster बना लेते हैं, तो वह cluster बाकियों से कितना दूर है? इसका जवाब देने वाला नियम linkage criterion है। Hierarchical clustering में यही सबसे ज़रूरी चुनाव है।
两个点合成一个簇之后,这个簇离其他簇有多远?回答这个问题的规则叫作连接准则(linkage criterion)。它是层次聚类中最重要的选择。
| LinkageLinkage连接方式 | Cluster shapeCluster का आकार簇的形状 | Outlier sensitivityOutliers का असर对离群点敏感度 | Chaining?Chaining?链式效应? | Best forकिसके लिए最适合 |
|---|---|---|---|---|
| Single | Any / long, curvedकोई भी / लंबा, मुड़ा任意 / 细长弯曲 | Very highबहुत ज़्यादा很高 | Yesहाँ是 | Curved shapes with clear gapsसाफ़ gaps वाले मुड़े आकार间隙清晰的弯曲形状 |
| Complete | Compactसघन紧凑 | Highज़्यादा高 | Noनहीं否 | Compact groups of similar sizeएक जैसे आकार के सघन groups大小相近的紧凑组 |
| Average | Moderateमध्यम中等 | Moderateमध्यम中等 | Rarelyकम ही很少 | Any distance metric; biologyकोई भी distance metric; biology任意距离度量;生物学 |
| Ward | Compact & balancedसघन & संतुलित紧凑且均衡 | Moderate (uses squared distances)मध्यम (squared distances)中等(使用距离平方) | Noनहीं否 | Most tabular data ⭐ज़्यादातर tabular data ⭐大多数表格数据 ⭐ |
| Centroid | Moderateमध्यम中等 | Moderateमध्यम中等 | Possible + inversionsसंभव + inversions可能 + 倒置 | Rarely recommendedकम ही सुझाया जाता很少推荐 |
Choose a dataset. Each panel cuts its own dendrogram into the true number of groups. The percentage in the corner is how many points land in their true group. No linkage wins everywhere.
एक dataset चुनें। हर panel अपने dendrogram को groups की असली संख्या में काटता है। कोने का प्रतिशत बताता है कि कितने points अपने असली group में पहुँचे। कोई भी linkage हर जगह नहीं जीतता।
选择一个数据集。每个面板把自己的树状图切成真实的组数。角上的百分比表示有多少点落在了真实所属的组。没有哪种连接方式能处处取胜。
Ward's method minimises variance, which only makes sense with Euclidean distance. scikit-learn even refuses other metrics with linkage='ward'.
If you need cosine, Manhattan or correlation distance, use average or complete linkage.
Ward's method variance घटाता है, जिसका मतलब सिर्फ़ Euclidean distance के साथ बनता है। scikit-learn तो linkage='ward' के साथ दूसरे metrics स्वीकार ही नहीं करता।
अगर cosine, Manhattan या correlation distance चाहिए, तो average या complete linkage इस्तेमाल करें।
Ward 方法最小化方差,这只有在欧氏距离下才有意义。scikit-learn 在 linkage='ward' 时甚至直接拒绝其他度量。
如果需要余弦、曼哈顿或相关距离,请用 average 或 complete 连接。
Distance Metrics — What Does "Similar" Mean?Distance Metrics — "मिलता-जुलता" का मतलब क्या?距离度量 — “相似”到底指什么?
Before measuring the distance between clusters, we need the distance between two points. The choice changes the result a lot.
Clusters के बीच दूरी मापने से पहले हमें दो points के बीच की दूरी चाहिए। यह चुनाव नतीजे को बहुत बदल देता है।
在度量簇间距离之前,我们需要先定义两点之间的距离。这个选择会极大地影响结果。
Drag A and B. Orange = Euclidean (straight line), blue = Manhattan (city blocks), purple = the angle used by cosine distance (measured from the origin 0,0).
A और B को खींचें। नारंगी = Euclidean (सीधी line), नीली = Manhattan (city blocks), बैंगनी = cosine distance वाला कोण (origin 0,0 से मापा गया)।
拖动 A 和 B。橙色 = 欧氏距离(直线),蓝色 = 曼哈顿距离(街区路线),紫色 = 余弦距离使用的夹角(从原点 0,0 量起)。
If your data has Age (0–100), Salary (20,000–200,000) and Height (1.5–2.0 m), Euclidean distance will be controlled almost completely by Salary — the other features disappear.
Apply StandardScaler (mean 0, standard deviation 1) or MinMaxScaler before hierarchical clustering, unless your features are already in the same units.
अगर आपके data में Age (0–100), Salary (20,000–200,000) और Height (1.5–2.0 m) हैं, तो Euclidean distance पर लगभग पूरा कब्ज़ा Salary का होगा — बाकी features ग़ायब हो जाएँगे।
Hierarchical clustering से पहले StandardScaler (mean 0, standard deviation 1) या MinMaxScaler लगाएँ, जब तक आपके features पहले से एक ही unit में न हों।
如果数据里有年龄(0–100)、工资(20,000–200,000)和身高(1.5–2.0 米),欧氏距离几乎完全由工资决定 —— 其他特征等于消失了。
除非特征本来就是同一单位,否则在层次聚类前请使用 StandardScaler(均值 0、标准差 1)或 MinMaxScaler。
The Dendrogram — Reading It Like a ProDendrogram — Pro की तरह पढ़ना树状图 — 像专家一样阅读
dendrogram(color_threshold=…) colours each branch below the threshold differently, so cluster membership is easy to see.
SciPy का dendrogram(color_threshold=…) threshold से नीचे की हर शाखा को अलग रंग देता है, ताकि cluster membership आसानी से दिखे।
SciPy 的 dendrogram(color_threshold=…) 会给阈值以下的每个分支涂上不同颜色,簇的归属一目了然。
Merge heights near the top: 1.08, 1.17, then a jump to 5.17 and 7.13. The empty band between 1.17 and 5.17 is the biggest gap, so K = 3 is the natural answer.
ऊपर के पास merge heights: 1.08, 1.17, फिर छलाँग 5.17 और 7.13 पर। 1.17 और 5.17 के बीच का ख़ाली हिस्सा सबसे बड़ा gap है, इसलिए K = 3 स्वाभाविक जवाब है।
靠近顶部的合并高度:1.08、1.17,然后跳到 5.17 和 7.13。1.17 到 5.17 之间的空白带是最大间隙,所以 K = 3 是自然的答案。
Drag anywhere on the dendrogram to move the red cut. The scatter plot on the right colours the points by the clusters you get. The orange band marks the biggest gap. Change the true number of groups to test the rule.
लाल cut खिसकाने के लिए dendrogram पर कहीं भी खींचें। दाईं ओर का scatter plot आपको मिले clusters के रंग में points दिखाता है। नारंगी पट्टी सबसे बड़ा gap दिखाती है। नियम जाँचने के लिए groups की असली संख्या बदलें।
在树状图上任意位置拖动,移动红色切割线。右侧散点图按你得到的簇给点上色。橙色带标出最大间隙。改变真实组数来检验这条规则。
Look for the longest stretch of height with no merges. Cut inside it. The number of vertical lines you cross is a good K. This is the most common way to choose K from a dendrogram — the hierarchical version of the elbow method. Always confirm it with the silhouette score (Section 09).
ऊँचाई का वह सबसे लंबा हिस्सा खोजें जिसमें कोई merge न हो। उसके अंदर काटें। जितनी खड़ी lines कटती हैं, वह एक अच्छा K है। Dendrogram से K चुनने का यह सबसे आम तरीका है — elbow method का hierarchical रूप। हमेशा silhouette score से पुष्टि करें (Section 09)।
找出没有任何合并的最长一段高度,在其中切一刀。穿过的竖线条数就是一个好的 K。 这是从树状图选择 K 最常用的方法 —— 相当于层次聚类版的肘部法。务必再用轮廓系数确认(第 09 节)。
Time and Memory — How Big Can the Data Be?समय और Memory — Data कितना बड़ा हो सकता है?时间与内存 — 数据能有多大?
Hierarchical clustering needs the distance between every pair of points. That is what limits it. Here are real timings from SciPy on 5-feature data:
Hierarchical clustering को points के हर जोड़े के बीच दूरी चाहिए। यही इसकी सीमा है। 5-feature data पर SciPy की असली timings ये हैं:
层次聚类需要每一对点之间的距离,这正是它的瓶颈。下面是 SciPy 在 5 个特征的数据上的真实计时:
import time
import numpy as np
from scipy.cluster.hierarchy import linkage
from sklearn.cluster import KMeans
rng = np.random.default_rng(0)
KMeans(5, n_init=1, random_state=0).fit(rng.normal(size=(500, 5))) # warm-up run
print(f"{'n':>6} | {'distance matrix':>15} | {'Ward linkage':>12} | {'K-Means (K=5)':>13}")
for n in [1000, 2000, 4000, 8000, 16000]:
X = rng.normal(size=(n, 5))
mem_mb = n * (n - 1) / 2 * 8 / 1e6 # condensed matrix, 8 bytes per float
t0 = time.time(); linkage(X, method='ward'); t_hc = time.time() - t0
t0 = time.time(); KMeans(5, n_init=1, random_state=0).fit(X); t_km = time.time() - t0
print(f"{n:>6} | {mem_mb:>12.0f} MB | {t_hc:>10.2f} s | {t_km:>11.2f} s")
Each time n doubles, the memory grows 4× and the Ward time grows roughly 4× too — that is O(n²). K-Means stays almost flat. (Your times will differ by machine; the growth pattern will not.)
हर बार n दोगुना होने पर memory 4× बढ़ती है और Ward का समय भी लगभग 4× — यही O(n²) है। K-Means लगभग सपाट रहता है। (आपकी machine पर समय अलग होगा; बढ़ने का pattern नहीं।)
n 每翻一倍,内存增长 4 倍,Ward 的耗时也大约增长 4 倍 —— 这就是 O(n²)。K-Means 几乎不变。(不同机器的耗时会不同,但增长规律不会变。)
| AlgorithmAlgorithm算法 | Timeसमय时间 | MemoryMemory内存 | Practical limit (laptop)व्यावहारिक सीमा (laptop)实际上限(笔记本) |
|---|---|---|---|
| Naive agglomerativeसीधा agglomerative朴素凝聚式 | O(n³) | O(n²) | a few thousand rowsकुछ हज़ार rows几千行 |
SciPy linkage / scikit-learn | O(n²) | O(n²) | ~20,000–30,000 rows~20,000–30,000 rows约 2–3 万行 |
scikit-learn with connectivityscikit-learn connectivity के साथscikit-learn + connectivity | much less (sparse graph)बहुत कम (sparse graph)低得多(稀疏图) | O(n·k) | 100,000+ rows100,000+ rows10 万行以上 |
| K-Means (comparisonतुलना对比) | O(n·K·t) | O(n·K) | millions of rowsलाखों-करोड़ों rows数百万行 |
Move the slider to change the number of rows. Bars use a log scale. Times are extrapolated from the real measurements above.
Rows की संख्या बदलने के लिए slider खिसकाएँ। Bars log scale पर हैं। समय ऊपर के असली measurements से आगे बढ़ाया गया है।
拖动滑块改变行数。条形图使用对数刻度。耗时由上面的真实测量外推得到。
Hierarchical clustering stores about n²/2 distances. For 10,000 rows that is 50 million numbers — about 400 MB at 8 bytes each, before any other work. For data above a few tens of thousands of rows, use K-Means, Mini-Batch K-Means, DBSCAN or BIRCH — or run hierarchical clustering on a representative sample.
Hierarchical clustering लगभग n²/2 दूरियाँ रखता है। 10,000 rows के लिए यह 5 करोड़ numbers हैं — 8 bytes प्रति number पर लगभग 400 MB, और कोई काम शुरू होने से पहले। कुछ दसियों हज़ार rows से बड़े data के लिए K-Means, Mini-Batch K-Means, DBSCAN या BIRCH इस्तेमाल करें — या एक प्रतिनिधि sample पर hierarchical clustering चलाएँ।
层次聚类要存储约 n²/2 个距离。1 万行就是 5000 万个数 —— 每个 8 字节,约 400 MB,这还没开始做其他计算。 超过几万行的数据,请用 K-Means、Mini-Batch K-Means、DBSCAN 或 BIRCH —— 或者在有代表性的样本上运行层次聚类。
Evaluating Cluster QualityCluster Quality जाँचना评估聚类质量
There are no true labels, so we use internal scores that only look at the data and the clusters.
कोई असली labels नहीं हैं, इसलिए हम internal scores इस्तेमाल करते हैं जो सिर्फ़ data और clusters देखते हैं।
没有真实标签,所以我们使用只看数据和簇本身的内部指标。
Cut the dendrogram at several heights (K = 2, 3, … 10), compute the silhouette for each K, and look for the highest score. Because the tree is built only once, trying many cuts is cheap. Combine it with the biggest-gap rule and with what makes sense for your problem.
Dendrogram को कई ऊँचाइयों पर काटें (K = 2, 3, … 10), हर K का silhouette निकालें, और सबसे ऊँचा score देखें। पेड़ सिर्फ़ एक बार बनता है, इसलिए कई cuts आज़माना सस्ता है। इसे सबसे बड़े gap वाले नियम और अपनी problem की समझ के साथ मिलाएँ।
在多个高度切开树状图(K = 2、3、… 10),计算每个 K 的轮廓系数,找出最高分。因为树只需构建一次,尝试多种切法成本很低。 再结合最大间隙法则和对问题本身的理解来做决定。
Python Implementation — Full WalkthroughPython Implementation — पूरा WalkthroughPython 实现 — 完整演练
A complete implementation using scipy (for the dendrogram) and scikit-learn (for pipelines). Every output below is the real output of the code.
scipy (dendrogram के लिए) और scikit-learn (pipelines के लिए) से पूरा implementation. नीचे का हर output code का असली output है।
使用 scipy(画树状图)和 scikit-learn(用于流水线)的完整实现。下面每个输出都是代码真实运行的结果。
Step 1 — Import Libraries and Generate DataStep 1 — Libraries import करें और Data बनाएँ第 1 步 — 导入库并生成数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# scipy — dendrogram plotting
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from scipy.spatial.distance import pdist
# sklearn — clustering + evaluation
from sklearn.cluster import AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, davies_bouldin_score
from sklearn.datasets import make_blobs
# Reproducibility
np.random.seed(42)
# Generate 3-cluster synthetic data
X, y_true = make_blobs(
n_samples=150,
centers=3,
cluster_std=0.8,
random_state=42
)
print(f"Dataset shape: {X.shape}")
Step 2 — Scale FeaturesStep 2 — Features scale करें第 2 步 — 缩放特征
# Always scale before distance-based algorithms
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
print("Mean per feature: ", X_scaled.mean(axis=0).round(4) + 0.0) # + 0.0 turns -0.0 into 0.0
print("Std per feature: ", X_scaled.std(axis=0).round(4))
Step 3 — Build the Linkage Matrix and Plot the DendrogramStep 3 — Linkage Matrix बनाएँ और Dendrogram plot करें第 3 步 — 构建连接矩阵并画树状图
# Build the full linkage matrix using Ward's method
Z = linkage(X_scaled, method='ward', metric='euclidean')
# Z is an (n-1) x 4 matrix; each row:
# [cluster_i, cluster_j, distance, count_in_new_cluster]
np.set_printoptions(suppress=True) # plain numbers, no 1e+01
print("Linkage matrix shape:", Z.shape)
print("First 3 merges:\n", Z[:3].round(3))
print("Last 3 merge heights:", Z[-3:, 2].round(2))
# ── Plot the dendrogram ─────────────────────────────────────
plt.figure(figsize=(14, 6))
plt.title('Hierarchical Clustering Dendrogram (Ward Linkage)', fontsize=14)
plt.xlabel('Sample Index')
plt.ylabel('Distance (Ward)')
dendrogram(
Z,
color_threshold=5.0, # 5 sits inside the big gap (1.49 → 13.06) → 3 colours
leaf_font_size=8,
above_threshold_color='grey'
)
# Draw a horizontal cut line at height = 5
plt.axhline(y=5.0, color='red', linestyle='--', label='Cut threshold')
plt.legend()
plt.tight_layout()
plt.show()
Each row of Z is one merge: [cluster i, cluster j, merge height, size of the new cluster]. Ids 0–149 are the original points; id 150 is the first new cluster, and so on. The last three heights (1.49 → 13.06 → 20.43) show a huge gap, which is why color_threshold=5.0 gives 3 colours.
Z की हर row एक merge है: [cluster i, cluster j, merge height, नए cluster का size]. Ids 0–149 असली points हैं; id 150 पहला नया cluster है, और इसी तरह आगे। आख़िरी तीन heights (1.49 → 13.06 → 20.43) एक बड़ा gap दिखाती हैं, इसीलिए color_threshold=5.0 3 रंग देता है।
Z 的每一行是一次合并:[簇 i, 簇 j, 合并高度, 新簇大小]。编号 0–149 是原始点;150 是第一个新簇,依此类推。最后三个高度(1.49 → 13.06 → 20.43)之间有巨大间隙,所以 color_threshold=5.0 会得到 3 种颜色。
Step 4 — Extract Clusters and EvaluateStep 4 — Clusters निकालें और जाँचें第 4 步 — 提取簇并评估
# ── Method A: scipy fcluster (cut dendrogram at K=3) ───────
labels_scipy = fcluster(Z, t=3, criterion='maxclust')
# ── Method B: sklearn AgglomerativeClustering ──────────────
# Production-grade, integrates with sklearn pipelines
hac = AgglomerativeClustering(
n_clusters=3,
linkage='ward',
metric='euclidean'
)
labels_sklearn = hac.fit_predict(X_scaled)
# ── Evaluation metrics ──────────────────────────────────────
sil = silhouette_score(X_scaled, labels_sklearn)
dbi = davies_bouldin_score(X_scaled, labels_sklearn)
print(f"Silhouette Score : {sil:.4f} (higher = better, max=1.0)")
print(f"Davies-Bouldin : {dbi:.4f} (lower = better, min=0.0)")
print(f"Cluster sizes : {np.bincount(labels_sklearn)}")
Step 5 — Silhouette for Every Cut to Find the Best KStep 5 — सबसे अच्छा K खोजने के लिए हर Cut का Silhouette第 5 步 — 对每种切法计算轮廓系数,找出最佳 K
# Cut dendrogram at K = 2 to 8 and score each
k_range = range(2, 9)
sil_scores = []
for k in k_range:
labels = fcluster(Z, t=k, criterion='maxclust')
sil_scores.append(silhouette_score(X_scaled, labels))
best_k = k_range[int(np.argmax(sil_scores))]
best_sc = max(sil_scores)
print(f"Best K = {best_k} → Silhouette = {best_sc:.4f}")
for k, sc in zip(k_range, sil_scores):
bar = '█' * int(sc * 50)
marker = ' ← BEST' if k == best_k else ''
print(f" K={k} {bar} {sc:.4f}{marker}")
K = 3 wins clearly (0.88), matching the 3 blobs we generated and the big gap in the dendrogram.
K = 3 साफ़ जीतता है (0.88), जो हमारे बनाए 3 blobs और dendrogram के बड़े gap से मेल खाता है।
K = 3 明显胜出(0.88),与我们生成的 3 个团以及树状图中的大间隙一致。
Hierarchical vs K-Means — When to Use WhichHierarchical vs K-Means — कब कौन सा层次聚类 vs K-Means — 何时用哪个
| Propertyगुण特性 | Hierarchical ClusteringHierarchical Clustering层次聚类 | K-Means |
|---|---|---|
| Choose K in advance?K पहले से चुनना?需要预先指定 K? | No — choose after seeing the dendrogramनहीं — dendrogram देखकर चुनें不需要 —— 看了树状图再选 | Yes — before runningहाँ — चलाने से पहले需要 —— 运行前就要定 |
| Cluster shapeCluster का आकार簇的形状 | Depends on linkage (single can follow curves)Linkage पर निर्भर (single curves के साथ चल सकता है)取决于连接方式(单连接能跟随曲线) | Round, similar spreadगोल, एक जैसा फैलाव圆形、分散程度相近 |
| ScalabilityScalability可扩展性 | O(n²) memory — tens of thousands of rowsO(n²) memory — दसियों हज़ार rowsO(n²) 内存 —— 几万行 | O(n·K·t) — millions of rowsO(n·K·t) — लाखों rowsO(n·K·t) —— 数百万行 |
| Same result every run?हर run में वही नतीजा?每次结果都一样? | Yes (no random start)हाँ (कोई random शुरुआत नहीं)是(没有随机初始化) | Only with a fixed random_stateसिर्फ़ तय random_state के साथ只有固定 random_state 时才是 |
| Handles outliersOutliers संभालना处理离群点 | Depends on linkageLinkage पर निर्भर取决于连接方式 | Centroids get pulledCentroids खिंच जाते हैं质心会被拉偏 |
| Easy to explainसमझाना आसान易于解释 | Very — the tree tells the storyबहुत — पेड़ कहानी बताता है非常 —— 树本身就在讲故事 | Moderateठीक-ठाक一般 |
| Best useसबसे अच्छा इस्तेमाल最佳用途 | Exploration, biology, small/medium dataExploration, biology, छोटा/मध्यम data探索分析、生物学、中小数据 | Large data, K roughly knownबड़ा data, K का अंदाज़ा पता大数据、大致知道 K |
Use hierarchical clustering when the data has up to a few tens of thousands of rows, you do not know K, you want an explainable result, or you need to show a tree to stakeholders. Use K-Means when the data is large, K is roughly known, and speed matters more than the tree. A common workflow: run hierarchical clustering on a sample to choose K, then run K-Means on the full data with that K.
Hierarchical clustering तब इस्तेमाल करें जब data में कुछ दसियों हज़ार rows तक हों, K पता न हो, समझाने लायक नतीजा चाहिए, या stakeholders को पेड़ दिखाना हो। K-Means तब इस्तेमाल करें जब data बड़ा हो, K का अंदाज़ा हो, और पेड़ से ज़्यादा speed ज़रूरी हो। एक आम workflow: K चुनने के लिए एक sample पर hierarchical clustering चलाएँ, फिर उसी K से पूरे data पर K-Means चलाएँ।
当数据不超过几万行、不知道 K、需要可解释的结果,或要向相关人员展示树形结构时,用层次聚类。 当数据量大、大致知道 K、速度比树更重要时,用 K-Means。 常见流程:先在样本上运行层次聚类确定 K,再用这个 K 在全量数据上运行 K-Means。
Common Pitfalls and How to Avoid Themआम ग़लतियाँ और उनसे कैसे बचें常见陷阱及规避方法
StandardScaler or MinMaxScaler first.StandardScaler या MinMaxScaler चलाएँ।StandardScaler 或 MinMaxScaler。linkage="average" or "complete".linkage="average" या "complete" इस्तेमाल करें।linkage="average" 或 "complete"。connectivity graph to scikit-learn.connectivity graph दें।connectivity 图。🏪 Customer Segmentation for a Retail BankRetail Bank के लिए Customer Segmentation零售银行的客户分群
Goal: find natural customer segments with hierarchical clustering so the marketing team can tailor loans, savings products and digital-banking upgrades to each segment.
लक्ष्य: hierarchical clustering से स्वाभाविक customer segments खोजना ताकि marketing team हर segment के लिए loans, savings products और digital-banking upgrades तैयार कर सके।
目标:用层次聚类找出自然的客户群,让市场团队为每个群体定制贷款、储蓄产品和数字银行升级方案。
Real bank data is private, so we simulate it — but with 4 hidden customer types built in. If every column is generated independently at random (a common shortcut), there are no real segments; the silhouette stays near 0.1–0.2 and any "profiles" you print are just noise. The algorithm is never told the types.
असली bank data private होता है, इसलिए हम उसे simulate करते हैं — पर उसमें 4 छिपे customer types रखकर। अगर हर column अलग-अलग random बनाया जाए (एक आम shortcut), तो कोई असली segment नहीं होता; silhouette 0.1–0.2 के आसपास रहता है और जो भी "profiles" छापें वे सिर्फ़ noise हैं। Algorithm को types कभी नहीं बताए जाते।
真实银行数据是隐私数据,所以我们用模拟数据 —— 但其中内置了 4 种隐藏的客户类型。如果每一列都独立随机生成(常见的偷懒做法),就不存在真正的客户群;轮廓系数只有 0.1–0.2 左右,打印出来的“画像”只是噪声。算法从不知道这些类型。
Step 1 — Load and ExploreStep 1 — Load करें और देखें第 1 步 — 加载并查看
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import silhouette_score
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
import matplotlib.pyplot as plt
rng = np.random.default_rng(42)
# Simulated bank customers from 4 hidden behaviour types.
# (Real data would come from the bank; the algorithm never sees 'types'.)
types = { # age income credit products monthly_txns count
'professional': (45, 85000, 745, 4, 55, 180),
'budget': (42, 32000, 600, 2, 20, 220),
'digital': (29, 52000, 690, 3, 75, 200),
'pre_retire': (60, 50000, 665, 2, 14, 200),
}
parts = []
for name, (age, inc, cred, prod, txn, m) in types.items():
parts.append(pd.DataFrame({
'age': rng.normal(age, 4, m).round().clip(21, 75),
'annual_income': rng.normal(inc, inc * 0.12, m).round(-2),
'credit_score': rng.normal(cred, 25, m).round().clip(300, 850),
'num_products': rng.poisson(prod, m).clip(1, 8),
'monthly_txns': rng.normal(txn, 6, m).round().clip(1, None),
}))
df = pd.concat(parts, ignore_index=True).sample(frac=1, random_state=42).reset_index(drop=True)
print(df.describe().round(1).loc[['count', 'mean', 'std', 'min', 'max']])
Step 2 — Preprocess and Choose KStep 2 — Preprocess करें और K चुनें第 2 步 — 预处理并选择 K
# Scale all features to zero mean, unit variance
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)
# Build Ward linkage matrix
Z = linkage(X_scaled, method='ward')
# Test K from 2 to 8
results = []
for k in range(2, 9):
labels = fcluster(Z, t=k, criterion='maxclust')
sil = silhouette_score(X_scaled, labels)
results.append({'k': k, 'silhouette': round(sil, 4)})
best = max(results, key=lambda x: x['silhouette'])
print(f"{'K':>4} {'Silhouette':>12}")
for r in results:
star = ' ← BEST' if r['k'] == best['k'] else ''
print(f" {r['k']:>2} {r['silhouette']:>12.4f}{star}")
K = 4 has the highest silhouette (0.47), but K = 3 and 5 are close. That is normal for real customer data: the silhouette says "about 3–5 groups", and the dendrogram gap plus business sense pick the final K. A silhouette around 0.45 means real but overlapping groups.
K = 4 का silhouette सबसे ऊँचा है (0.47), पर K = 3 और 5 पास हैं। असली customer data में यह आम है: silhouette कहता है "लगभग 3–5 groups", और dendrogram gap व business की समझ आख़िरी K चुनते हैं। लगभग 0.45 का silhouette मतलब असली पर कुछ overlap वाले groups.
K = 4 的轮廓系数最高(0.47),但 K = 3 和 5 也很接近。这在真实客户数据中很常见:轮廓系数告诉你“大约 3–5 组”,再由树状图间隙和业务判断决定最终的 K。0.45 左右的轮廓系数意味着组是真实存在的,但有一定重叠。
Step 3 — Final Clustering (K = 4) and Segment ProfilesStep 3 — Final Clustering (K = 4) और Segment Profiles第 3 步 — 最终聚类(K = 4)与客户群画像
# Apply final model with K=4
hac = AgglomerativeClustering(n_clusters=4, linkage='ward')
df['segment'] = hac.fit_predict(X_scaled)
# Profile each segment with mean values
profile = df.groupby('segment').agg(
count=('age', 'size'),
avg_age=('age', 'mean'),
avg_income=('annual_income', 'mean'),
avg_credit=('credit_score', 'mean'),
avg_products=('num_products', 'mean'),
avg_txns=('monthly_txns', 'mean')
).round(1)
print(profile.to_string())
Step 4 — Interpret and Name the SegmentsStep 4 — Segments समझें और नाम दें第 4 步 — 解读并命名客户群
| SegmentSegment客户群 | Nameनाम名称 | ProfileProfile画像 | Recommended productsसुझाए गए products推荐产品 |
|---|---|---|---|
| 0 | High-Value ProfessionalsHigh-Value Professionals高价值专业人士 | Age ~45, income ~£85K, credit ~745, ~4 products, ~55 txns/monthAge ~45, income ~£85K, credit ~745, ~4 products, ~55 txns/महीना约 45 岁,收入约 £85K,信用分约 745,约 4 个产品,每月约 55 笔交易 | Premium cards, wealth management, mortgage top-upsPremium cards, wealth management, mortgage top-ups高端信用卡、财富管理、房贷加额 |
| 1 | Budget-Conscious AdultsBudget-Conscious Adults精打细算型 | Age ~42, income ~£31K, credit ~600, ~2 products, ~20 txns/monthAge ~42, income ~£31K, credit ~600, ~2 products, ~20 txns/महीना约 42 岁,收入约 £31K,信用分约 600,约 2 个产品,每月约 20 笔交易 | Savings accounts, budgeting tools, credit-builder productsSavings accounts, budgeting tools, credit-builder products储蓄账户、预算工具、信用修复类产品 |
| 2 | Digital-Native Young EarnersDigital-Native Young Earners数字原生年轻族 | Age ~29, income ~£52K, credit ~691, ~3 products, ~75 txns/monthAge ~29, income ~£52K, credit ~691, ~3 products, ~75 txns/महीना约 29 岁,收入约 £52K,信用分约 691,约 3 个产品,每月约 75 笔交易 | Mobile-app features, cashback cards, starter investmentsMobile-app features, cashback cards, starter investments手机银行功能、返现卡、入门投资产品 |
| 3 | Pre-Retirement, Low ActivityPre-Retirement, Low Activity临近退休、低活跃 | Age ~60, income ~£49K, credit ~666, ~2 products, ~15 txns/monthAge ~60, income ~£49K, credit ~666, ~2 products, ~15 txns/महीना约 60 岁,收入约 £49K,信用分约 666,约 2 个产品,每月约 15 笔交易 | Retirement savings, fixed deposits, low-fee accountsRetirement savings, fixed deposits, low-fee accounts养老储蓄、定期存款、低费率账户 |
Built from the real output above. Segment 0 leads on income, credit and products; segment 2 leads on transactions; segment 3 is the oldest and least active.
ऊपर के असली output से बना। Segment 0 income, credit और products में आगे है; segment 2 transactions में; segment 3 सबसे उम्रदराज़ और सबसे कम active है।
根据上面的真实输出绘制。客户群 0 在收入、信用分和产品数上领先;客户群 2 在交易次数上领先;客户群 3 年龄最大、最不活跃。
Ward linkage on scaled features recovered the 4 customer types almost exactly (segment sizes 180 / 219 / 200 / 201 vs the true 180 / 220 / 200 / 200). The silhouette pointed to K = 4, but only narrowly — so the final choice also used the business story. Each segment now has a clear profile the bank can act on.
Scaled features पर Ward linkage ने 4 customer types लगभग बिल्कुल सही पकड़ लिए (segment sizes 180 / 219 / 200 / 201, असली 180 / 220 / 200 / 200)। Silhouette ने K = 4 बताया, पर थोड़े ही अंतर से — इसलिए आख़िरी फ़ैसले में business की कहानी भी देखी गई। अब हर segment का साफ़ profile है जिस पर bank काम कर सकता है।
在缩放后的特征上使用 Ward 连接,几乎完全还原了 4 种客户类型(各群大小 180 / 219 / 200 / 201,真实为 180 / 220 / 200 / 200)。 轮廓系数指向 K = 4,但优势很小 —— 所以最终决定还参考了业务逻辑。现在每个客户群都有了银行可以据此行动的清晰画像。
🧬 Gene Expression Clustering in BioinformaticsBioinformatics में Gene Expression Clustering生物信息学中的基因表达聚类
Goal: find groups of co-expressed genes with hierarchical clustering, using average linkage and correlation distance, and show them as a clustered heatmap — the standard picture in genomics.
लक्ष्य: average linkage और correlation distance के साथ hierarchical clustering से co-expressed genes के groups खोजना, और उन्हें clustered heatmap के रूप में दिखाना — genomics की standard तस्वीर।
目标:用平均连接和相关距离做层次聚类,找出共表达的基因组,并以聚类热图展示 —— 这是基因组学中的标准图。
Two genes can follow the same up-and-down pattern while one is simply "louder" (higher numbers). What matters biologically is the shape: do they rise and fall together? Correlation distance = 1 − Pearson r. 0 = same shape, 1 = unrelated, 2 = exact opposite. The simulator below shows what goes wrong with Euclidean distance.
दो genes एक ही ऊपर-नीचे वाले pattern पर चल सकते हैं जबकि एक बस "तेज़" हो (बड़े numbers)। Biology में आकार मायने रखता है: क्या वे साथ बढ़ते-घटते हैं? Correlation distance = 1 − Pearson r. 0 = वही आकार, 1 = कोई संबंध नहीं, 2 = बिल्कुल उल्टा। नीचे का simulator दिखाता है कि Euclidean distance से क्या गड़बड़ होती है।
两个基因可以遵循同样的升降模式,而其中一个只是“更响”(数值更大)。生物学上重要的是形状:它们是否同升同降? 相关距离 = 1 − Pearson r。0 = 形状相同,1 = 无关,2 = 完全相反。下面的模拟器展示了用欧氏距离会出什么问题。
Each row is a gene, each column a day; colour = expression. The left strip shows the true pattern of each gene, the right strip the group found (average linkage, cut into 3). Some genes are louder than others on purpose.
हर row एक gene है, हर column एक दिन; रंग = expression. बाईं पट्टी हर gene का असली pattern दिखाती है, दाईं पट्टी मिला हुआ group (average linkage, 3 में काटा)। कुछ genes जान-बूझकर बाकियों से तेज़ हैं।
每行是一个基因,每列是一天;颜色 = 表达量。左边的色条是每个基因的真实模式,右边的色条是找到的组(平均连接,切成 3 组)。有些基因被故意设置得比其他基因“更响”。
Step 1 — Simulate Gene Expression DataStep 1 — Gene Expression Data simulate करें第 1 步 — 模拟基因表达数据
import numpy as np
import pandas as pd
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from scipy.spatial.distance import pdist, squareform
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
import seaborn as sns
np.random.seed(99)
conditions = ['D0', 'D1', 'D2', 'D4', 'D7', 'D14', 'D21', 'D28']
# Create 3 co-expression groups of ~17 genes each
# Group A: genes that peak early then drop off
base_A = np.array([3.0, 5.2, 7.8, 9.1, 6.4, 3.5, 1.8, 1.2])
# Group B: genes that rise late and stay high
base_B = np.array([1.0, 1.2, 1.5, 4.8, 6.2, 7.1, 7.4, 7.9])
# Group C: genes that are switched off step by step
base_C = np.array([8.5, 7.2, 5.1, 3.3, 2.1, 1.5, 1.0, 0.8])
rows = []
for i in range(17):
rows.append(base_A + np.random.normal(0, 0.4, 8))
for i in range(17):
rows.append(base_B + np.random.normal(0, 0.4, 8))
for i in range(16):
rows.append(base_C + np.random.normal(0, 0.4, 8))
gene_names = [f"GENE_{i+1:02d}" for i in range(50)]
expr = pd.DataFrame(rows, index=gene_names, columns=conditions)
print("Expression matrix shape:", expr.shape)
print(expr.head(3).round(2))
Step 2 — Correlation Distance MatrixStep 2 — Correlation Distance Matrix第 2 步 — 相关距离矩阵
# 1 − Pearson correlation as distance between genes
corr_dist = pdist(expr.values, metric='correlation')
corr_matrix = squareform(corr_dist)
print("Distance matrix shape:", corr_matrix.shape)
print(f"Min dist: {corr_dist.min():.4f} | Max dist: {corr_dist.max():.4f}")
print(f"Median dist: {np.median(corr_dist):.4f}")
Step 3 — Cluster Genes with Average LinkageStep 3 — Average Linkage से Genes cluster करें第 3 步 — 用平均连接对基因聚类
# Average linkage on precomputed correlation distances
Z_genes = linkage(corr_dist, method='average')
# Find optimal K via silhouette
best_k, best_sil = 2, -1
for k in range(2, 8):
labels = fcluster(Z_genes, t=k, criterion='maxclust')
sil = silhouette_score(corr_matrix, labels, metric='precomputed')
if sil > best_sil:
best_k, best_sil = k, sil
print(f" K={k} silhouette={sil:.4f}")
print(f"\nOptimal K = {best_k} (silhouette = {best_sil:.4f})")
# Apply final clustering
gene_labels = fcluster(Z_genes, t=best_k, criterion='maxclust')
expr['cluster'] = gene_labels
Step 4 — Biological InterpretationStep 4 — Biological व्याख्या第 4 步 — 生物学解读
for c in sorted(expr['cluster'].unique()):
genes_in = expr[expr['cluster'] == c].drop('cluster', axis=1)
mean_expr = genes_in.mean()
print(f"\n── Cluster {c} ({len(genes_in)} genes) ──────────────")
print("Mean expression per timepoint:")
for cond, val in mean_expr.items():
bar = '■' * int(val)
print(f" {cond:>4}: {bar:<12} {val:.2f}")
print(f" Genes: {', '.join(genes_in.index[:5].tolist())} ...")
# Picture: clustered heatmap with the same dendrogram on the rows
# sns.clustermap(expr.drop(columns="cluster"), row_linkage=Z_genes, col_cluster=False, cmap="viridis")
Note: fcluster numbers clusters 1, 2, 3 in its own order, so "Cluster 1" here is the late-rising group (genes 18–34), not genes 1–17. Always read the profile, never assume the number.
ध्यान दें: fcluster clusters को अपने क्रम में 1, 2, 3 number देता है, इसलिए यहाँ "Cluster 1" देर से बढ़ने वाला group है (genes 18–34), genes 1–17 नहीं। हमेशा profile पढ़ें, number पर भरोसा न करें।
注意:fcluster 按自己的顺序给簇编号 1、2、3,所以这里的“Cluster 1”是后期上升组(基因 18–34),而不是基因 1–17。一定要看画像,不要想当然地看编号。
| ClusterCluster簇 | Expression patternExpression pattern表达模式 | Possible biological meaningसंभावित biological मतलब可能的生物学含义 | Next stepअगला कदम下一步 |
|---|---|---|---|
| 1 (17 genes) | Late, sustained — low until D2, then rises and stays highदेर से, टिकाऊ — D2 तक कम, फिर बढ़कर ऊँचा रहता है后期持续型 —— D2 前很低,之后上升并保持高位 | Long-term adaptation; possible resistance pathwayलंबी अवधि का adaptation; संभावित resistance pathway长期适应;可能的耐药通路 | Monitor for resistanceResistance पर नज़र रखें监测耐药性 |
| 2 (17 genes) | Early response — peaks at D4, then fallsशुरुआती प्रतिक्रिया — D4 पर peak, फिर गिरावट早期响应型 —— D4 达峰后下降 | Acute response to the treatmentTreatment पर तुरंत प्रतिक्रिया对处理的急性响应 | Check for acute toxicity markersAcute toxicity markers जाँचें检查急性毒性标志物 |
| 3 (16 genes) | Switched off — high at D0, falls steadilyबंद होते हुए — D0 पर ऊँचा, लगातार गिरता逐渐关闭型 —— D0 很高,随后持续下降 | Genes suppressed by the treatmentTreatment से दबाए गए genes被处理抑制的基因 | Check for off-target suppressionOff-target suppression जाँचें检查脱靶抑制 |
Correlation distance with average linkage separated the 50 genes into 3 co-expression clusters with a silhouette of 0.98 — almost perfect, because the simulated patterns are very clean (real data is noisier).
The interpretations above are hypotheses for the lab to test, not conclusions. This "clustered heatmap" workflow (for example seaborn.clustermap) is a standard tool for RNA-seq and microarray data.
Average linkage के साथ correlation distance ने 50 genes को 0.98 silhouette के साथ 3 co-expression clusters में बाँटा — लगभग perfect, क्योंकि simulated patterns बहुत साफ़ हैं (असली data में ज़्यादा noise होता है)।
ऊपर की व्याख्याएँ lab के जाँचने के लिए hypotheses हैं, निष्कर्ष नहीं। यह "clustered heatmap" workflow (जैसे seaborn.clustermap) RNA-seq और microarray data का standard औज़ार है।
相关距离加平均连接,把 50 个基因分成了 3 个共表达簇,轮廓系数 0.98 —— 几乎完美,因为模拟的模式非常干净(真实数据噪声更大)。
上面的解读是供实验室验证的假设,而不是结论。这种“聚类热图”流程(例如 seaborn.clustermap)是 RNA-seq 和芯片数据分析的标准工具。
scikit-learn API Quick Referencescikit-learn API Quick Referencescikit-learn API 速查
Run on the scaled bank data from Case Study 01:
Case Study 01 के scaled bank data पर चलाया गया:
在案例 01 缩放后的银行数据上运行:
from sklearn.cluster import AgglomerativeClustering
# Full parameter reference
model = AgglomerativeClustering(
n_clusters=4, # int or None (if distance_threshold used)
metric='euclidean', # 'euclidean','manhattan','cosine','precomputed'
linkage='ward', # 'ward','complete','average','single'
distance_threshold=None, # set this instead of n_clusters to cut by distance
connectivity=None, # connectivity matrix (e.g. from kneighbors_graph)
compute_full_tree='auto',# 'auto', True, False
compute_distances=False # set True if you need .distances_ attribute
)
labels = model.fit_predict(X_scaled)
# Useful post-fit attributes
print("n_clusters_ : ", model.n_clusters_) # actual number of clusters
print("n_leaves_ : ", model.n_leaves_) # number of leaves (= n samples)
print("n_connected_: ", model.n_connected_components_) # connectivity components
compute_distances=True if you want to build one from children_ and distances_).
AgglomerativeClustering — Pipelines में फ़िट होता है और flat labels लौटाता है। अपना dendrogram plot नहीं (अगर children_ और distances_ से बनाना हो तो compute_distances=True set करें)।
AgglomerativeClustering —— 可放入 Pipeline,返回平铺的标签。自己不画树状图(如需用 children_ 和 distances_ 自行构建,设置 compute_distances=True)。
predict() for new rows — to label new data, train a classifier on the cluster labels or assign new rows to the nearest cluster centre.
SciPy से explore करें (dendrogram + silhouette) और K चुनें, फिर pipeline के final model के लिए scikit-learn इस्तेमाल करें। ध्यान दें: AgglomerativeClustering में नई rows के लिए predict() नहीं है — नए data को label देने के लिए cluster labels पर classifier train करें या नई rows को सबसे पास वाले cluster centre को दें।
先用 SciPy 探索(树状图 + 轮廓系数)确定 K,再在流水线中用 scikit-learn 作为最终模型。注意:AgglomerativeClustering 没有针对新数据的 predict() —— 要给新数据打标签,可以用簇标签训练一个分类器,或把新数据分给最近的簇中心。
Golden Rules — Hierarchical ClusteringGolden Rules — Hierarchical Clustering黄金法则 — 层次聚类
StandardScaler before computing distances. Unscaled features let large-range columns control the result — the cause of most "bad" clusterings.StandardScaler चलाएँ। बिना scale के बड़ी range वाले columns नतीजे पर कब्ज़ा कर लेते हैं — ज़्यादातर "ख़राब" clusterings की यही वजह है।StandardScaler。不缩放,取值范围大的列就会主导结果 —— 大多数“糟糕”聚类都源于此。pdist(X, metric="correlation") with linkage(..., method="average").pdist(X, metric="correlation") को linkage(..., method="average") के साथ इस्तेमाल करें।pdist(X, metric="correlation") 配合 linkage(..., method="average")。