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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:57:31