确定 K 值是 K-means 聚类分析的一个重要步骤。不同的 K 值可能会产生不同的聚类结果,因此选择合适的 K 值非常重要。
以下是一些常见的方法来选择 K 值:
- 手肘法:该方法基于绘制聚类内误差平方和(SSE)与 K 值之间的关系图。随着 K
值的增加,SSE会逐渐降低,但降低幅度逐渐减小。手肘法的目标就是找到 SSE 下降的速度开始变慢的“拐点”,这个点就是最佳的 K 值。 - 轮廓系数法:该方法基于每个数据点与它所属的聚类中心的距离和与它邻近的聚类中心的距离之间的比值计算出轮廓系数。对于一个合适的 K值,它的轮廓系数应该最大。
- Gap 统计量法:该方法比较聚类结果和一组随机数据集的聚类结果之间的差异。Gap 统计量越大,表示聚类结果越好。
- Silhouette 统计量法:该方法将每个数据点的轮廓系数加权平均,作为整个聚类的 Silhouette统计量。与轮廓系数法类似,Silhouette 统计量也应该最大化。
手肘法
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
# 导入数据集
X = np.loadtxt('wholesale_customers_data.csv', delimiter=',', skiprows=1)
# 定义 SSE 函数
def sse(X, k):
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
return kmeans.inertia_
# 定义 K 值的范围
k_range = range(1, 11)
# 计算每个 K 值对应的 SSE
sse_list = [sse(X, k) for k in k_range]
# 绘制 SSE 与 K 值之间的关系图
plt.plot(k_range, sse_list)
plt.xlabel('K')
plt.ylabel('SSE')
plt.show()
# 找到手肘点并将其打印出来
diffs = np.diff(sse_list)
elbow_point = k_range[np.argmax(diffs) + 1]
print(f"The elbow point is at K = {
elbow_point}")
1、X = np.loadtxt(‘wholesale_customers_data.csv’, delimiter=‘,’, skiprows=1)
使用 NumPy 库中的 loadtxt() 函数从 CSV 文件中加载数据集。具体来说,该函数将 CSV 文件中的每一行视为一个样本,每一列视为一个特征,并将它们存储在一个 NumPy 数组中。
该函数的参数包括:
- fname: 要加载的文件名。
- delimiter: 文件中列之间的分隔符。在这个例子中,我们将逗号作为分隔符。
- skiprows: 要跳过的行数。在这个例子中,我们将跳过文件的第一行,因为第一行是标题行,而不是数据行。
因此,X = np.loadtxt(‘wholesale_customers_data.csv’, - delimiter=‘,’, skiprows=1) 这行代码的作用是将 Wholesale customers 数据集从 CSV 文件中加载到名为 X 的 NumPy 数组中,以便用于后续的聚类分析。
kmeans.inertia_
kmeans.inertia_ 是 KMeans 聚类算法中的一个属性,它表示聚类模型的 SSE(Sum of Squared Errors,平方误差和),即所有数据点到其所属簇质心的距离平方和。SSE 是一个衡量聚类效果的指标,其值越小表示聚类效果越好。
在 KMeans 聚类算法中,我们的目标是找到 SSE 最小的聚类方案。kmeans.inertia_ 属性返回当前聚类方案的 SSE 值,因此我们可以通过计算不同 K 值下的 SSE 值来选择最佳的 K 值,以达到最优的聚类效果。
diffs = np.diff(sse_list)
np.diff() 函数是 NumPy 库中的一个函数,用于计算一个数组中相邻元素之间的差异。具体来说,该函数返回一个新数组,其中每个元素是原始数组中相邻元素之间的差值。
在聚类分析中,我们通常会使用 SSE(Sum of Squared Errors,平方误差和)指标来衡量聚类质量。在手肘法中,我们需要找到一个 K 值,使得 SSE 在这个 K 值之后的下降速度开始变慢,形成一个“手肘”状的曲线。因此,我们需要计算不同 K 值下的 SSE,然后找到相邻 SSE 之间的差异,以便找到手肘点的位置。
在这个代码行中,np.diff(sse_list) 的作用是计算 SSE 列表中相邻元素之间的差异,将它们存储在一个新数组 diffs 中。然后,我们将 diffs 用于找到手肘点的位置,即 SSE 减少速度开始变慢的位置。
elbow_point = k_range[np.argmax(diffs) + 1]
k_range 是一个包含了我们尝试的 K 值的列表,diffs 是一个包含相邻 SSE 差异的列表。我们需要找到一个 K 值,使得 SSE 下降的速度开始变慢,也就是在这个 K 值之后,SSE 减少的程度变小。因此,我们需要找到 diffs 中最大值的位置,然后将其加 1,就能得到手肘点的位置。
具体来说,np.argmax(diffs) 返回 diffs 数组中最大值的索引,也就是 SSE 下降速度开始变慢的位置。我们将它加 1 的原因是,由于 diffs 是通过计算相邻 SSE 之间的差异得到的&#