使用Scikit-learn包的AgglomerativeClustering
AgglomerativeClustering 是 Scikit-learn 中的凝聚层次聚类算法:开始时每个样本自成一类,然后不断合并最相似的簇,直到达到指定簇数或距离阈值。
1. 基本用法
from sklearn.cluster import AgglomerativeClustering
# n_clusters:最终簇数
model = AgglomerativeClustering(n_clusters=3, linkage='ward')
labels = model.fit_predict(X)
print(labels)
fit_predict(X) 返回每个样本的簇标签,也可以通过 model.labels_ 获取。
2. 常用参数
AgglomerativeClustering(
n_clusters=2,
linkage='ward',
metric='euclidean', # 旧版 sklearn 中叫 affinity
distance_threshold=None,
connectivity=None,
compute_full_tree='auto',
compute_distances=False
)
主要参数:
| 参数 | 说明 |
|---|---|
n_clusters |
最终簇数。若设置 distance_threshold,则必须为 None |
linkage |
合并策略:'ward'、'complete'、'average'、'single' |
metric |
距离度量,默认 'euclidean'。旧版 Scikit-learn 中为 affinity |
distance_threshold |
距离阈值,超过该值不再合并,可自动决定簇数 |
connectivity |
连通性矩阵,用于限制哪些样本可以合并 |
compute_distances |
是否计算距离,通常用于后续分析 |
注意:
linkage='ward' 只能配合欧氏距离使用;如果使用其他距离,可选择 'complete'、'average' 或 'single'。
3. 完整示例
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
# 生成模拟数据
X, y_true = make_blobs(
n_samples=300,
centers=4,
cluster_std=0.8,
random_state=42
)
# 层次聚类对距离敏感,通常先标准化
X_scaled = StandardScaler().fit_transform(X)
# 创建模型
model = AgglomerativeClustering(
n_clusters=4,
linkage='ward'
)
# 聚类
labels = model.fit_predict(X_scaled)
# 可视化
plt.figure(figsize=(8, 6))
plt.scatter(
X_scaled[:, 0],
X_scaled[:, 1],
c=labels,
cmap='viridis',
s=40
)
plt.title('AgglomerativeClustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
4. 使用距离阈值自动确定簇数
如果不确定簇数,可以设置 distance_threshold:
model = AgglomerativeClustering(
n_clusters=None,
distance_threshold=1.0,
linkage='ward'
)
labels = model.fit_predict(X_scaled)
print("自动得到的簇数:", model.n_clusters_)
此时 n_clusters 必须为 None。distance_threshold 的取值与数据尺度有关,所以一般先标准化数据。
5. 评估聚类效果
如果有真实标签,可以用调整兰德指数等指标评估:
from sklearn.metrics import adjusted_rand_score
score = adjusted_rand_score(y_true, labels)
print("ARI:", score)
6. 注意事项
-
建议标准化数据
层次聚类基于距离,不同特征量纲差异大会影响结果。 -
计算复杂度较高
通常为 (O(n^2)) 或更高,不适合特别大的数据集。 -
ward与欧氏距离绑定
使用linkage='ward'时不要随便换其他距离度量。 -
不能直接画树状图
AgglomerativeClustering主要用于得到簇标签。如果需要树状图,可以结合scipy.cluster.hierarchy:
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
Z = linkage(X_scaled, method='ward')
plt.figure(figsize=(10, 6))
dendrogram(Z)
plt.show()
- 版本差异
新版 Scikit-learn 使用metric,旧版使用affinity。如果你使用的版本报错,可尝试:
AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='ward')
总结:
AgglomerativeClustering 适合中小规模数据的层次聚类。典型流程是:标准化数据 → 选择 n_clusters 或 distance_threshold → 设置 linkage → fit_predict 得到标签。
- 点赞
- 收藏
- 关注作者
评论(0)