当前位置: 首页 > ai >正文

机器学习-----K-means算法介绍

一、为什么需要 K-Means?

在监督学习中,我们总把数据写成
(x, y),让模型学习 x → y 的映射。
但现实中很多数据根本没有标签 y,例如:

  • 啤酒:热量、钠含量、酒精度、价格

  • 用户:访问时长、点击次数、消费金额

我们只想知道“这些样本天然能分成几类?”
这就是无监督学习——聚类。
K-Means 就是最经典、最易懂、跑得最快的聚类算法之一。

二、K-Means 的思想

随机撒 k 个“种子”当类中心,
把每个样本分给最近的种子,
再把种子移到新类的中心,
重复直到种子不再动。

三、算法流程图解

  1. 选 k:先决定想聚几类。

  2. 初始化:随机或 k-means++ 选 k 个质心。

  3. 分配:每个样本找最近的质心,形成 k 个簇。

  4. 更新:把每个簇的均值当成新质心。

  5. 收敛:质心移动小于阈值或达到最大迭代次数。

四、Python 实战:啤酒聚类

项目目的:

在没有人工标签的情况下,把 20 种啤酒自动分成若干类别,并告诉你到底分几类最合适

1. 数据准备

我们有一份啤酒数据,只有 4 个数值特征:

表格

啤酒热量(cal)钠(mg)酒精(%)价格($)
A150154.52.3
B100103.01.8
2.读取 & 选特征
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as pltdata = pd.read_table("data.txt", sep=r'\s+', engine='python')
x = data[['calories', 'sodium', 'alcohol', 'cost']]
3.选 k:轮廓系数法

轮廓系数 (Silhouette Coefficient)

  • 每个样本计算:

    • a:到同簇其它点的平均距离

    • b:到最近外簇的平均距离

    • s = (b - a) / max(a, b)

  • 取值范围:[-1, 1]

    • ≈ 1:聚得紧凑且远离它簇

    • ≈ 0:边界模糊

    • < 0:可能分错了簇

用平均轮廓系数挑 k

# 1. 准备一个空列表,用来存放不同 k 值对应的轮廓系数
scores = []# 2. 依次尝试 k=2,3,...,9,看看聚成几类效果最好
for k in range(2, 10):# 2-1 用当前 k 值做 K-Means 聚类#     random_state=42 保证结果可重复labels = KMeans(n_clusters=k, random_state=42).fit(x).labels_# 2-2 计算聚类结果的平均轮廓系数(-1~1,越大越紧凑)scores.append(silhouette_score(x, labels))# 3. 把 k 与对应的轮廓系数画成折线图,方便肉眼找“峰值”
plt.plot(range(2, 10), scores, marker='o')# 4. 给图加上坐标轴和标题
plt.xlabel("k")                    # 横轴:聚类个数
plt.ylabel("Silhouette Score")     # 纵轴:平均轮廓系数
plt.title("选择最佳 k")             # 图标题
plt.show()                         # 显示图形

规则:选“峰值”对应的 k。

k=2  → 0.69  ← 最高 
k=3  → 0.67   
k=4  → 0.65

那么 k=2 最合适。

④ 正式聚类 & 结果保存

k-means算法中的重要参数:

参数作用常用值
n_clusters类个数根据业务或轮廓系数
init质心初始化'k-means++'(默认)更快更稳
n_init随机初始化跑几次10(默认)
random_state复现实验任意整数
best_k = 2
km = KMeans(n_clusters=best_k, init='k-means++', n_init=10, random_state=42)
data['cluster'] = km.fit_predict(x)
print(data.head())

现在每一行都了一个标签 cluster = 0 1后续可以做市场细分、推荐策略等。

具体如图所示:

20种啤酒被聚类成 0,1两类

http://www.xdnf.cn/news/17451.html

相关文章:

  • 数据类型全解析
  • PostgreSQL因为A/B switch以及group表过多导致WAL full的情况讨论
  • 冒泡排序实现以及优化
  • django基于Python的设计师作品平台的数据可视化系统设计与实现
  • 数字图像处理2——图像增强
  • Java设计模式之开闭原则介绍与说明
  • TypeScript中的type和interface的区别是什么?
  • 红楼梦文本数据分析
  • LeetCode 869.重新排序得到 2 的幂:哈希表+排序(一次初始化)
  • 前端开发的奇技淫巧 --- 持续更新中
  • 使用线性降维方法进行数据降维
  • 使用tcp ntrip 协议 接收数据报错 java.net.SocketException: Connection reset
  • MariaDB 数据库管理与web服务器
  • 变量详解:创建初始化与内存管理
  • 【数据结构入门】栈和队列的OJ题
  • Virtio 驱动关键结构体与函数详解
  • RabbitMQ面试精讲 Day 18:内存与磁盘优化配置
  • 01.【面试题】在SpringBoot中如何实现多数据源配置
  • UNet改进(31):基于Adaptive Attention的UNet设计与实践
  • 智慧社区(十一)——Spring Boot 实现 Excel 导出、上传与数据导入全流程详解
  • 【永磁同步电机数学模型全程推导】【7 转矩方程】
  • IntelliJ IDEA 2025.2 重磅发布
  • 移动端音频处理实践:59MB变声应用的技术实现分析
  • 【GPT入门】第43课 使用LlamaFactory微调Llama3
  • GitLab 零基础入门指南:从安装到项目管理全流程
  • 复杂项目即时通讯从android 5升级android x后遗症之解决 ANR: Input dispatching timed out 问题 -优雅草卓伊凡
  • Android Intent 解析
  • 绕过文件上传漏洞并利用文件包含漏洞获取系统信息的技术分析
  • GPT OSS深度解析:OpenAI时隔6年的开源模型,AI民主化的新里程碑?
  • ubuntu 安装内核模块驱动 DKMS 介绍