机器学习——K-Means(啤酒数据集挖掘)

前言:学习记录

K-Means 是最经典的无监督聚类算法,不需要标签,仅依靠样本特征之间的距离,自动把相似样本划分成若干簇。本文结合啤酒真实数据集,完整复现 K‑Means 全流程:数据读取、特征标准化、肘部法则选 K、模型训练、轮廓系数评估、结果可视化,同时记录踩坑细节,适合机器学习入门学习。

环境:Python3.11 + scikit‑learn + pandas + matplotlib

一、K‑Means 算法原理

核心思想

1.预先指定聚类数量 K;

2.随机初始化 K 个聚类中心点;

3.分配:计算每个样本到 K 个中心点的欧式距离,样本划分给距离最近的中心点,形成 K 个簇;

4.更新:每个簇内部所有样本求均值,作为该簇新的聚类中心;

5.迭代重复分配‑更新,直到聚类中心几乎不再变化,达到收敛条件,算法结束。

关键概念

1.簇内误差平方和 (inertia):每个样本到所属簇中心的距离平方总和。K 越大,inertia 一定越小。肘部法则依靠 inertia 寻找拐点确定 K。

2.欧式距离:衡量样本相似度,特征量纲会直接影响距离结果,因此 K‑Means 必须做特征标准化。

3.轮廓系数:取值 -1,1,越接近 1,簇内越紧密、簇与簇之间区分越明显。

优缺点

优点:原理简单,计算速度快,适合大规模数据;

缺点:需要手动指定 K;对初始质心敏感;对离群点敏感;只能发现球形分布簇。

附件【参数

n_clusters: 类中心的个数,就是要聚成几类。【默认是8个】

init 参初始化的方法,默认为'k-means++'

(1)'k-means++': 用一种特殊的方法选定初始质心从而能加速迭代过程的收敛.

(2) 'random': 随机从训练数据中选取初始质心。

(3) 如果传递的是一个ndarray,则应该形如 (n_clusters, n_features) 并给出初始质心。

n_init: 整形,缺省值=10

用不同的质心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果。

max_iter :

执行一次k-means算法所进行的最大迭代数。

Tol: 与inertia结合来确定收敛条件。

precompute_distances :三个可选值,'auto',True 或者 False。

预计算距离,计算速度更快但占用更多内存。

(1)'auto':如果 样本数乘以聚类数大于 12million 的话则不预计算距离。

(2)True:总是预先计算距离。

(3)False:永远不预先计算距离。

verbose :整形,默认值=0

random_state : 随机状态

copy_x: 布尔型,默认值=True

当我们precomputing distances时,将数据中心化会得到更准确的结果。如果把此参数值设为True,则原始数据不会被改变。如果是False,则会直接在原始数据 上做修改并在函数返回值时将其还原。但是在计算过程中由于有对数据均值的加减运算,所以数据返回后,原始数据和计算前可能会有细小差别。

algorithm: 'auto','full' or 'elkan'.默认为'auto'

full:采用经典的EM算法

elkan:通过使用三角不等式从而更有效,但不支持稀疏数据

auto:数据稀疏选择full模式,数据稠密选择elkan模式

附件【属性】

cluster_centers_: 一个n-clusters*n_features的矩阵,表示聚类中心的坐标

Labels_:

每个点的分类标签。

inertia_: float形

每个点到其簇的质心的距离之和。

n_iter_ : int

迭代次数。

二、数据集介绍

数据集data.txt,啤酒数据集,一共 20 条样本。

字段:

name:啤酒名称(文本,不参与聚类)

calories:热量

sodium:钠含量

alcohol:酒精度

cost:单价

三、完整代码实现

一、库导入与绘图环境配置

  1. 导入matplotlib绘图库,设置后端TkAgg,解决 PyCharm 画布渲染报错;配置中文字体SimHei、负号正常显示,防止图表中文方框乱码。

  2. 导入pandas用于读取、处理 txt 表格数据。

  3. 导入KMeans聚类模型、StandardScaler标准化工具、silhouette_score轮廓系数评估指标。

二、数据集读取与特征筛选

  1. 使用pd.read_csv读取本地data.txt,通过sep=r"\s+"匹配多空格分隔符,适配啤酒数据集原始空格格式,打印前 5 行查看原始数据。

  2. 筛选 4 个数值特征:热量、钠含量、酒精度、单价;啤酒名称name为文本标识,不参与距离计算与聚类。

  3. 实例化标准化器StandardScaler,对特征矩阵执行标准化,消除各特征量纲差异(热量数值上百、价格仅零点几,量级差距会干扰欧式距离计算),输出标准化后特征矩阵X_scaled

三、肘部法则循环,确定最优聚类数 K

  1. 定义空列表存储每一个 K 对应的簇内误差平方和inertia,遍历 K=2~10。

  2. 循环内创建临时 KMeans 模型,参数严格遵循官方 API:

    • n_clusters=k:当前循环聚类数量;

    • init="k-means++":智能初始化聚类中心,避免局部最优;

    • n_init=10:10 组不同初始中心运行,选取误差最小结果;

    • max_iter=300:单次迭代上限;tol=0.0001:收敛阈值;

    • algorithm="lloyd":标准 K-Means 算法;固定随机种子保证复现。

  3. 训练临时模型,将inertia_(簇内总误差)存入列表。

  4. 绘制 K 与 inertia 的折线图并保存图片,通过曲线拐点判断最佳聚类数量,本实验拐点为 K=3。

四、正式训练 K-Means 聚类模型

  1. n_clusters=3创建正式聚类模型,其余参数与循环内保持统一。

  2. 调用fit()在标准化特征上完成迭代训练,完整 K-Means 迭代逻辑: 1)分配样本至距离最近聚类中心; 2)更新每个簇的中心点为簇内均值; 3)重复分配更新,直至中心变化小于阈值或达到最大迭代次数。

  3. 打印模型内置核心属性:

    • cluster_centers_:3 个聚类中心标准化坐标;

    • labels_:每条啤酒样本所属类别标签(0/1/2);

    • inertia_:全部样本到对应中心距离平方总和;

    • n_iter_:算法实际迭代次数。

  4. 将聚类标签合并到原始数据表,打印啤酒名称与对应分组,直观查看分类结果。

五、模型效果量化评估

调用silhouette_score计算轮廓系数,取值范围 -1,1,数值越接近 1 代表簇内样本越紧凑、簇间区分越清晰,量化评价本次聚类质量。

六、聚类结果可视化

  1. 选取热量、酒精度两个特征作为横纵坐标绘制散点图;

  2. 不同颜色区分 3 个聚类,红色叉号标记聚类中心点;

  3. 添加坐标轴标签、图表标题、图例与网格,保存可视化图片,直观展示样本分布与聚类边界。

七、程序收尾

控制台输出提示,告知程序运行完成,已生成肘部曲线图、聚类散点图两张可视化文件。

python 复制代码
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score

# 1、读取本地txt数据集,空格分隔
df = pd.read_csv("data.txt", sep=r"\s+", engine="python")
print("原始数据预览:")
print(df.head())

# 选取参与聚类的数值特征
feature_cols = ["calories", "sodium", "alcohol", "cost"]
X = df[feature_cols]

# 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 2、肘部法则,寻找最优K
inertia_list = []
k_range = range(2, 11)
for k in k_range:
    km_temp = KMeans(
        n_clusters=k,
        init="k-means++",
        n_init=10,
        max_iter=300,
        tol=0.0001,
        algorithm="lloyd",
        random_state=1
    )
    km_temp.fit(X_scaled)
    inertia_list.append(km_temp.inertia_)

# 绘制肘部曲线
plt.figure(figsize=(8, 4))
plt.plot(k_range, inertia_list, "o-", color="#2E86AB")
plt.xlabel("聚类数量 K")
plt.ylabel("簇内误差平方和 Inertia")
plt.title("肘部法则选择最优K值(啤酒数据集)")
plt.grid(alpha=0.3)
plt.savefig("KMeans_啤酒_肘部曲线.png", bbox_inches="tight", dpi=120)
plt.close()

# 3、训练K‑Means模型,选定K=3
kmeans = KMeans(
    n_clusters=3,
    init="k-means++",
    n_init=10,
    max_iter=300,
    tol=0.0001,
    algorithm="lloyd",
    random_state=1
)
kmeans.fit(X_scaled)

# 输出模型关键属性
print("\n=====KMeans模型输出结果=====")
print("聚类中心点坐标:\n", kmeans.cluster_centers_)
print("每个样本聚类标签:\n", kmeans.labels_)
print("簇内总误差inertia:", kmeans.inertia_)
print("迭代次数:", kmeans.n_iter_)

# 将聚类标签合并回原始数据表
df["cluster_label"] = kmeans.labels_
print("\n啤酒聚类分组结果:")
print(df[["name", "cluster_label"]])

# 4、轮廓系数评估聚类效果
sil_score = silhouette_score(X_scaled, kmeans.labels_)
print(f"\n轮廓系数:{sil_score:.4f}")

# 5、聚类结果可视化,选取热量、酒精度两个维度绘图
plt.figure(figsize=(8, 6))
plt.scatter(X_scaled[:, 0], X_scaled[:, 2], c=kmeans.labels_, cmap="coolwarm", alpha=0.7)
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 2], c="red", marker="X", s=200, label="聚类中心")
plt.xlabel("标准化热量 calories")
plt.ylabel("标准化酒精度 alcohol")
plt.title("啤酒KMeans聚类可视化(K=3)")
plt.legend()
plt.grid(alpha=0.3)
plt.savefig("KMeans_啤酒_聚类散点图.png", bbox_inches="tight", dpi=120)
plt.close()

print("\n程序运行结束,已生成肘部曲线、聚类散点图")

四、实验结果分析

  1. 肘部法则确定 K 值

观察肘部曲线,随着 K 增大,簇内误差平方和持续下降;当K=3的时候出现明显拐点。

K 大于 3 之后,inertia 下降变得平缓,增加聚类数量带来的收益很小,因此选择K=3作为本次实验聚类数。

  1. 轮廓系数

本次实验轮廓系数为 0.4578。

轮廓系数区间 -1,1

接近 1:簇内样本紧密,簇间差距大,聚类效果优秀

0 左右:簇存在重叠,边界模糊

负数:聚类划分混乱

0.4578 属于中等效果。数据集只有 20 条样本,部分啤酒特征本身很接近,簇边界模糊,属于真实数据集正常现象。

  1. 聚类分组解读

模型自动将啤酒分为 3 类:

类别 0:低热量、低酒精度,大多属于淡啤;

类别 1:中等热量,中等酒精度;

类别 2:高热量、高酒精度啤酒。

从散点图可以看到红色 X 标记的 3 个聚类中心,不同颜色散点代表不同簇,样本围绕各自簇中心分布。

相关推荐
听你说321 小时前
常青课堂同步HR系统考勤休假二百余项升级 万古科技智能排班系统赋能用户精细化用工
大数据·人工智能·科技
小趴蔡ha1 小时前
03 NumPy 入门:机器学习中的数组和矩阵
python·线性代数·机器学习·numpy
小白说大模型1 小时前
从0开始学计算机网络:HTTP 协议的进化史
人工智能·网络协议·计算机网络·http
triplemeng1 小时前
AI正在改变“真实”的含义:从《黑客帝国》、鲍德里亚到生成式人工智能
人工智能·深度学习·神经网络·生成式·黑客帝国·鲍德里亚·后真相
创世宇图1 小时前
从 Cantus 看 AI Coding 新趋势:当模型不再追求“通用榜单第一”
人工智能
bittersuite1 小时前
文本预处理,语言模型
人工智能·深度学习·机器学习
听你说321 小时前
AI 浪潮席卷 2026 ChinaJoy,KTC 移动屏解锁移动智能显示全新交互形态
人工智能·智能家居
宇宙第一小趴菜1 小时前
七、机器学习建模流程
人工智能·机器学习