前言

对于刚接触机器学习聚类算法的小伙伴来说,K-Means(K 均值聚类) 是最经典的无监督学习算法之一。但很多新手都会遇到一个核心问题:怎么确定聚类的最优 K 值(簇的数量)?
本文用啤酒数据集作为实战案例,选择 K-Means 最优聚类数,代码全程可直接运行,有需要可自取。


一、环境准备

我们需要 3 个核心库,提前安装:

  • pandas:读取和处理数据

  • scikit-learn:实现 K-Means 聚类和轮廓系数计算

  • matplotlib:绘制评估曲线

pip install pandas scikit-learn matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple/

二、数据集说明

我们使用啤酒数据集(data.txt),数据格式是空格分隔,包含 4 个特征:

  • calories:热量

  • sodium:钠含量

  • alcohol:酒精度

  • cost:价格

数据文件data.txt需要和代码放在同一目录,直接用pandas读取即可。
数据集预览:
在这里插入图片描述

三、完整代码解析

完整代码如下:

import pandas as pd
from sklearn.cluster import KMeans
from sklearn import metrics

beer = pd.read_table('data.txt', sep = ' ',encoding = 'utf-8',engine='python')
X = beer[['calories','sodium','alcohol','cost']]

scores = []
for k in range(2,10):
    labels = KMeans(n_clusters=k).fit(X).labels_
    score = metrics.silhouette_score(X,labels)
    scores.append(score)
print(scores)

import matplotlib.pyplot as plt

plt.plot(list(range(2,10)),scores)
plt.xlabel("number of clusters initiailzed")
plt.ylabel('sihoustte score')
plt.show()

km = KMeans(n_clusters=2).fit(X)
beer['cluster'] = km.labels_
score = metrics.silhouette_score(X,beer.cluster)
print(score)

解析

首先导入所有需要的工具库:
导入pandas库,简写为pd,专门用来读取、处理表格数据;
从sklearn.cluster模块中导入KMeans算法,这是我们的聚类模型;
再从sklearn中导入metrics评估模块,用来计算轮廓系数,评估聚类效果;

import pandas as pd
from sklearn.cluster import KMeans
from sklearn import metrics

然后读取数据 + 提取聚类特征:
其中sep=’ ':指定数据分隔符为空格(数据里每列用空格分开),如果数据是被逗号分隔开的,用逗号替换空格就行。
从读取的beer数据中,提取4列作为聚类的特征数据
[[‘calories’,‘sodium’,‘alcohol’,‘cost’]] 双括号表示提取多列
再把提取好的特征数据赋值给 X,X是机器学习里固定的特征变量写法。

beer = pd.read_table('data.txt', sep = ' ',encoding = 'utf-8',engine='python')
X = beer[['calories','sodium','alcohol','cost']]

遍历不同 K 值,计算轮廓系数
首先创建一个空列表 scores,用来存储每个K值对应的轮廓系数;
然后进行for循环遍历,k从2到9遍历循环;
之后创建KMeans模型,用特征数据X训练模型,同时获取训练后每条数据的聚类标签,赋值给labels;
计算轮廓系数,并添加到先前创建的空列表。
循环结束后,打印所有k值对应的轮廓系数结果,轮廓系数范围[-1,1],数值越大,聚类效果越好。

scores = []
for k in range(2,10):
    labels = KMeans(n_clusters=k).fit(X).labels_
    score = metrics.silhouette_score(X,labels)
    scores.append(score)
print(scores)

导入matplotlib.pyplot库,简写为plt,用来绘制折线图可视化结果
X轴数据为k值:range(2,10)
Y轴数据为对应k值的轮廓系数scores。
附上标题,并显示折线图

import matplotlib.pyplot as plt

plt.plot(list(range(2,10)),scores)
plt.xlabel("number of clusters initiailzed")
plt.ylabel('sihoustte score')
plt.show()

根据折线图结果,得到最优k值为2,创建并训练KMeans模型,n_clusters=2:指定分成2类;
把聚类结果(0/1标签)添加到原始beer数据中,新增一列名为 cluster 的列,存储每条数据的类别;
最后计算最终聚类(k=2)的轮廓系数,验证效果并打印分数。

km = KMeans(n_clusters=2).fit(X)
beer['cluster'] = km.labels_
score = metrics.silhouette_score(X,beer.cluster)
print(score)

运行结果:

[0.6917656034079486, 0.6731775046455796, 0.5267665961530135, 0.39795307968774635, 0.4063314658707994, 0.3878463360806727, 0.38946337473125997, 0.3874759334160638]

运行折线图:
在这里插入图片描述


总结

K-means 聚类广泛应用于市场细分、图像分割、文档聚类等领域。例如,在市场营销中,可以将客户划分为不同的群体,以便进行更针对性的推广策略;在图像处理中,可以将图像分割成多个区域,以便进一步分析或压缩。但同时也拥有自己的优缺点。
优点:

  • 简单易实现。
  • 对大数据集具有较好的可扩展性。
  • 当簇的密度大致相同且簇间分离良好时,效果非常好。

缺点:

  • 需要预先指定 K 值,而 K 的选择通常不直观。
  • 结果可能受到初始质心选择的影响,可能导致局部最优解。
  • 对异常值(噪声)和簇的形状(非球形)敏感。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐