K-means算法结果标准
K-means算法是一种常用的无监督学习算法,用于将数据集分成K个簇。评估K-means聚类结果的标准有很多,主要包括以下几种:
簇内误差平方和(Within-cluster Sum of Squares, WCSS):
- 也称为簇内平方和(Inertia),它是衡量簇内数据点与簇中心之间距离的总和。目标是使这个值最小化,表示簇内数据点彼此之间的距离尽可能近。
- 公式:$WCSS = \sum_{i=1}^{k} \sum_{x \in C_i} | x - \mu_i |^2$ 其中,$C_i$ 是第 $i$ 个簇,$\mu_i$ 是 $C_i$ 的质心,$x$ 是 $C_i$ 中的一个数据点。
在K-means算法中,通过手肘法确定最佳的K值通常需要以下步骤:
计算不同K值下的SSE(误差平方和):
- 对于每一个K值(从1到某个较大的值),运行K-means算法,并计算其对应的SSE。
绘制K值与SSE的关系图:
- 将不同K值对应的SSE绘制成图,观察曲线的形状。
寻找肘部位置:
- 观察图中的“肘部”位置,即SSE开始显著变平缓的点,对应的K值就是最佳的聚类数。
以下是一个Python代码示例,展示了如何使用手肘法确定K值:
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 生成示例数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# 定义要测试的K值范围
k_values = range(1, 11)
# 存储每个K值对应的SSE
sse = []
for k in k_values:
kmeans = KMeans(n_clusters=k, random_state=0)
kmeans.fit(X)
sse.append(kmeans.inertia_) # inertia_属性即为SSE
# 绘制K值与SSE的关系图
plt.figure(figsize=(8, 5))
plt.plot(k_values, sse, 'bo-', markersize=8)
plt.xlabel('Number of clusters (k)')
plt.ylabel('Sum of squared errors (SSE)')
plt.title('Elbow Method For Optimal k')
plt.show()
解释代码:
生成示例数据:
- 使用
make_blobs函数生成一个包含300个样本的示例数据集,假设有4个簇。
- 使用
定义要测试的K值范围:
- 这里我们测试从1到10的K值。
计算每个K值对应的SSE:
- 使用K-means算法对每个K值进行聚类,并记录其对应的SSE(通过
kmeans.inertia_获取)。
- 使用K-means算法对每个K值进行聚类,并记录其对应的SSE(通过
绘制K值与SSE的关系图:
- 使用Matplotlib绘制K值与SSE的关系图,观察曲线形状以确定肘部位置。
通过观察图中的“肘部”位置,即SSE显著变平缓的点,可以确定最佳的K值。通常,这个点对应的K值就是数据的真实聚类数。
轮廓系数(Silhouette Coefficient):
- 轮廓系数结合了簇内紧密度和簇间分离度。其值在-1到1之间,值越大表示聚类效果越好。
- 公式:$s(i) = \frac{b(i) - a(i)}{\max(a(i), b(i))}$ 其中,$a(i)$ 是数据点 $i$ 到其簇内其他点的平均距离,$b(i)$ 是数据点 $i$ 到最近簇的平均距离。
以下是如何使用轮廓系数法确定最佳聚类数的步骤:
- 计算不同K值下的轮廓系数:
- 对于每一个K值(从2到某个较大的值),运行K-means算法,并计算其对应的轮廓系数。
- 绘制K值与平均轮廓系数的关系图:
- 将不同K值对应的平均轮廓系数绘制成图,观察曲线的形状。
- 选择平均轮廓系数最大的K值:
- 平均轮廓系数最大的K值即为最佳聚类数。
以下是一个Python代码示例,展示了如何使用轮廓系数法确定最佳K值:
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.datasets import make_blobs
# 生成示例数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# 定义要测试的K值范围
k_values = range(2, 11)
# 存储每个K值对应的平均轮廓系数
silhouette_scores = []
for k in k_values:
kmeans = KMeans(n_clusters=k, random_state=0)
kmeans.fit(X)
labels = kmeans.labels_
silhouette_avg = silhouette_score(X, labels)
silhouette_scores.append(silhouette_avg)
# 绘制K值与平均轮廓系数的关系图
plt.figure(figsize=(8, 5))
plt.plot(k_values, silhouette_scores, 'bo-', markersize=8)
plt.xlabel('Number of clusters (k)')
plt.ylabel('Average Silhouette Score')
plt.title('Silhouette Method For Optimal k')
plt.show()
# 找到平均轮廓系数最大的K值
optimal_k = k_values[silhouette_scores.index(max(silhouette_scores))]
print(f'The optimal number of clusters is {optimal_k}')
解释代码:
生成示例数据:
- 使用
make_blobs函数生成一个包含300个样本的示例数据集,假设有4个簇。
- 使用
定义要测试的K值范围:
- 这里我们测试从2到10的K值(注意K值从2开始,因为K=1时轮廓系数没有意义)。
计算每个K值对应的平均轮廓系数:
- 使用K-means算法对每个K值进行聚类,获取每个样本的簇标签。
- 使用
silhouette_score函数计算每个K值对应的平均轮廓系数,并存储结果。
绘制K值与平均轮廓系数的关系图:
- 使用Matplotlib绘制K值与平均轮廓系数的关系图,观察曲线形状。
找到平均轮廓系数最大的K值:
- 通过查找平均轮廓系数最大的K值,确定最佳的聚类数。
通过这种方式,我们可以使用轮廓系数法确定最佳的K值,以获得更好的聚类效果。
Calinski-Harabasz指数(Calinski-Harabasz Index):
- 也称为方差比准则(Variance Ratio Criterion, VRC),其值越大表示聚类效果越好。
- 公式:$\text{CH} = \frac{B_k / (k-1)}{W_k / (n-k)}$ 其中,$B_k$ 是簇间离散度矩阵的迹,$W_k$ 是簇内离散度矩阵的迹,$n$ 是样本总数,$k$ 是簇的数量。
Davies-Bouldin指数(Davies-Bouldin Index):
- 该指数衡量的是簇之间的相似度,值越小表示聚类效果越好。
- 公式:$\text{DB} = \frac{1}{k} \sum_{i=1}^{k} \max_{j \ne i} \left( \frac{\sigma_i + \sigma_j}{d(c_i, c_j)} \right)$ 其中,$\sigma_i$ 是第 $i$ 个簇的平均距离,$d(c_i, c_j)$ 是簇 $i$ 和簇 $j$ 的质心之间的距离。
轮廓系数图(Elbow Method):
- 通过绘制不同K值对应的簇内误差平方和(WCSS)图,寻找"肘部"位置,以确定最佳的K值。肘部位置通常是曲线开始变平缓的点。
BIC(Bayesian Information Criterion)和AIC(Akaike Information Criterion):
- 这两种信息准则常用于模型选择,值越小表示模型越好。尽管它们更多用于有监督学习,但在某些情况下也可以用于K-means聚类。
实际应用中的可解释性:
- 聚类结果是否具有实际意义,是否能被领域专家解释和利用,也是一个重要的标准。
在实际应用中,通常会结合多个指标来综合评估K-means聚类的效果。
