You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向AgglomerativeClustering传入稀疏距离矩阵触发TypeError的解决方案咨询

解决思路与方案

你的问题核心是:scikit-learn的AgglomerativeClustering不支持预计算的稀疏距离矩阵,而转成稠密矩阵又会内存爆炸。下面是几个实用的替代方案:

方案1:直接用归一化特征做层次聚类(最推荐)

你完全没必要提前计算全量距离矩阵——AgglomerativeClustering支持直接以特征向量为输入,并用余弦距离作为相似度度量,内存占用仅为embeddings本身的大小,10万样本完全没问题。

步骤:

  1. 先对embeddings做L2归一化(余弦距离计算要求特征向量归一化):
from sklearn.preprocessing import normalize
embeddings_norm = normalize(embeddings, norm='l2')
  1. 直接用归一化后的特征做聚类:
clustering = AgglomerativeClustering(
    n_clusters=None,
    distance_threshold=1 - similarity_threshold,  # 余弦距离 = 1 - 余弦相似度,和你之前的逻辑一致
    affinity='cosine',
    linkage=linkage
)
clustering.fit(embeddings_norm)

这个方案彻底避免了生成10万×10万的巨型矩阵,直接解决内存和稀疏矩阵不兼容的问题。

方案2:用Scipy层次聚类处理稀疏距离对

如果你一定要基于已生成的稀疏距离矩阵聚类,可以用scipy.cluster.hierarchy工具,它支持处理压缩形式的距离数据:

  1. 从稀疏矩阵中提取有效距离对(排除对角线和重复对):
import scipy.cluster.hierarchy as sch

# 获取非零元素的行、列索引和距离值
rows, cols = sm_matrix.nonzero()
dists = sm_matrix.data

# 过滤自身到自身的距离,只保留上三角部分避免重复
valid_mask = (rows != cols) & (rows < cols)
rows_valid = rows[valid_mask]
cols_valid = cols[valid_mask]
dists_valid = dists[valid_mask]

# 用单链接(适合稀疏场景)生成聚类树,再根据阈值生成标签
Z = sch.linkage(dists_valid, method=linkage)
labels = sch.fcluster(Z, t=1 - similarity_threshold, criterion='distance')

注:这个方案仅适合稀疏度极高的场景,且不同linkage方法的兼容性不同,操作较繁琐,优先选方案1。

方案3:换用支持稀疏矩阵的聚类算法

如果可以接受非层次聚类的结果,DBSCAN支持稀疏矩阵作为预计算距离输入:

from sklearn.cluster import DBSCAN

# 调整eps为你的距离阈值0.35,min_samples根据业务需求设置
dbscan = DBSCAN(eps=0.35, min_samples=3, metric='precomputed', n_jobs=-1)
cluster_labels = dbscan.fit_predict(sm_matrix)

DBSCAN是密度聚类,和层次聚类的聚类逻辑差异较大,需要根据你的业务场景判断是否适用。


内容的提问来源于stack exchange,提问作者Salihcan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:25:25