如何为K-means及其他聚类算法计算silhouette_score?
解决K-means轮廓系数计算及复用至其他聚类算法的方案
首先,先修正你的K-means代码,确保它能正确运行——在较新的scikit-learn版本中,KMeans需要显式指定n_init参数(避免默认值的警告),同时我们可以把轮廓系数的计算封装成通用函数,方便复用给其他聚类算法。
修正后的K-means计算代码
import pandas as pd import numpy as np from sklearn.datasets import load_wine from sklearn.preprocessing import MinMaxScaler from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score # 加载数据并标准化 wine_data = load_wine() X_scaled = MinMaxScaler().fit_transform(wine_data.data) # 训练K-means模型(指定n_init避免版本警告) kmeans = KMeans(n_clusters=3, n_init='auto', random_state=42).fit(X_scaled) # 计算轮廓系数 silhouette_avg = silhouette_score(X_scaled, kmeans.labels_) print(f"For n_clusters = 3, The average silhouette_score is : {silhouette_avg:.4f}")
封装通用函数复用至其他聚类算法
为了高效给另外4种聚类算法计算轮廓系数,我们可以写一个通用函数,输入训练好的聚类模型和标准化后的特征数据,直接输出对应的轮廓系数:
def calculate_silhouette(cluster_model, X_scaled): """ 计算给定聚类模型的平均轮廓系数 参数: cluster_model: 已训练完成的聚类模型实例 X_scaled: 标准化后的特征数据集 返回: 平均轮廓系数(保留4位小数) """ labels = cluster_model.labels_ # 轮廓系数要求至少有2个有效簇,否则无法计算 unique_clusters = np.unique(labels) # 过滤掉DBSCAN/OPTICS这类算法可能生成的噪声标签-1 valid_clusters = unique_clusters[unique_clusters != -1] if len(valid_clusters) < 2: return "有效簇数不足2,无法计算轮廓系数" # 如果存在噪声点,计算时排除它们 mask = labels != -1 return silhouette_score(X_scaled[mask], labels[mask]).__round__(4)
示例:用该函数计算4种常见聚类算法的轮廓系数
以DBSCAN、层次聚类、Birch、OPTICS这4种算法为例:
from sklearn.cluster import DBSCAN, AgglomerativeClustering, Birch, OPTICS # 1. DBSCAN(基于密度的聚类) dbscan = DBSCAN(eps=0.5, min_samples=5).fit(X_scaled) print(f"DBSCAN 平均轮廓系数: {calculate_silhouette(dbscan, X_scaled)}") # 2. 层次聚类(AgglomerativeClustering) agg_clust = AgglomerativeClustering(n_clusters=3).fit(X_scaled) print(f"层次聚类 平均轮廓系数: {calculate_silhouette(agg_clust, X_scaled)}") # 3. Birch(基于树的聚类) birch = Birch(n_clusters=3).fit(X_scaled) print(f"Birch 平均轮廓系数: {calculate_silhouette(birch, X_scaled)}") # 4. OPTICS(改进的密度聚类) optics = OPTICS(min_samples=5).fit(X_scaled) print(f"OPTICS 平均轮廓系数: {calculate_silhouette(optics, X_scaled)}")
关键注意事项
- 所有聚类算法都需要基于标准化后的特征数据计算,因为大部分聚类算法对特征尺度敏感,尺度差异会直接影响聚类结果和轮廓系数。
- 对于DBSCAN、OPTICS这类密度聚类算法,可能会生成
-1标签代表噪声点,计算轮廓系数时必须排除这些点,否则会拉低整体分数的参考价值。 - 轮廓系数的取值范围是[-1,1],越接近1说明簇内样本相似度越高、簇间差异越明显,聚类效果越好。
内容的提问来源于stack exchange,提问作者Abdul Rehman
相关产品推荐
相关产品推荐

