继承sklearn Kmeans类自定义距离度量的可行性及聚类实现咨询
关于自定义距离度量的KMeans问题解答
一、重写_transform()是否影响聚类结果?
你的判断完全正确。sklearn的KMeans中,fit()方法是聚类的核心,它负责完成聚类中心初始化、样本簇分配、中心迭代更新的全流程,整个过程依赖内部硬编码的距离计算逻辑(默认是欧氏距离)。而_transform()方法仅在调用fit_transform()或单独调用transform()时生效,作用是计算已聚类样本到各中心的距离矩阵,不会对fit()阶段的簇划分、中心位置产生任何影响。重写它只会改变后续距离计算的输出结果,聚类本身的结果不会变化。
二、自定义距离度量的KMeans实现方法
1. 手动实现KMeans核心逻辑
直接编写KMeans的迭代流程,在距离计算环节替换成自定义度量,灵活性最高:
import numpy as np from sklearn.metrics.pairwise import pairwise_distances def custom_kmeans(X, n_clusters, max_iter=300, metric='cosine'): # 随机选择初始聚类中心 centers = X[np.random.choice(X.shape[0], n_clusters, replace=False)] for _ in range(max_iter): # 用自定义度量计算样本到中心的距离 distances = pairwise_distances(X, centers, metric=metric) # 分配样本到最近的簇 labels = np.argmin(distances, axis=1) # 更新聚类中心(取簇内样本均值) new_centers = np.array([X[labels == i].mean(axis=0) for i in range(n_clusters)]) # 收敛判断:中心不再变化则停止迭代 if np.allclose(centers, new_centers): break centers = new_centers return centers, labels
2. 使用支持自定义度量的第三方库工具
比如scikit-learn-extra中的KMedoids(K中心点算法),它支持任意自定义距离度量,适合无法用欧氏距离近似的场景:
from sklearn_extra.cluster import KMedoids from sklearn.metrics.pairwise import cosine_distances # 初始化KMedoids,指定自定义距离函数 kmedoids = KMedoids(n_clusters=3, metric=cosine_distances, random_state=42) cluster_labels = kmedoids.fit_predict(your_dataset)
3. 特征空间映射(仅适用于可转化的距离)
如果你的自定义距离可以通过特征变换转化为欧氏距离,先对数据做变换再用标准KMeans即可。比如余弦距离:
from sklearn.preprocessing import normalize from sklearn.cluster import KMeans # L2归一化数据,此时欧氏距离与余弦距离呈线性相关 normalized_X = normalize(your_dataset, norm='l2') # 用标准KMeans聚类,等价于基于余弦距离的聚类 kmeans = KMeans(n_clusters=3, random_state=42) labels = kmeans.fit_predict(normalized_X)
内容的提问来源于stack exchange,提问作者charumathi vasudevan
相关产品推荐
相关产品推荐

