news 2026/7/25 8:07:42

机器学习入门(十九)聚类算法,聚类评估指标

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
机器学习入门(十九)聚类算法,聚类评估指标

聚类算法 – 概念

• 什么是聚类算法?

• 根据样本之间的相似性,将样本划分到不同的类别中;不同的相似度计算方法,会得到不同的聚类结果, 常用的相似度计算方法有欧式距离法。

• 聚类算法的目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式。

• 无监督学习算法

• 使用不同的聚类准则,产生的聚类结果不同

聚类算法在现实生活中的应用

聚类算法分类

1.根据聚类颗粒度分类

2.根据实现方法分类

• K-means:按照质心分类,主要介绍K-means,通用、普遍

• 层次聚类:对数据进行逐层划分,直到达到聚类的类别个数

• DBSCAN聚类(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法

• 谱聚类是一种基于图论的聚类算法

Calinski-Harabasz 分数(也称为方差比准则)是一种聚类效果评估指标。值越大聚类效果更好。

代码

from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.metrics import calinski_harabasz_score x, y = make_blobs( n_samples=1000, n_features=2, # 中心点是2维 centers=[[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=22 ) # plt.figure(figsize=(6, 6)) # plt.scatter(x[:, 0], x[:, 1], c=y, marker='+', cmap='viridis', s=20) # plt.show() print('x-->', x[:3, :]) y_pred = KMeans( n_init='auto', n_clusters=4, random_state=40 ).fit_predict(x) plt.figure(figsize=(6, 6)) plt.scatter(x[:, 0], x[:, 1], c=y_pred, marker='+', cmap='viridis', s=20) plt.show() print(calinski_harabasz_score(x, y_pred))

执行结果

x--> [[-1.61312858 -0.83800844] [-0.7967687 -0.57865695] [ 2.09177616 1.52088834]] 5813.864029456606

KMeans算法实现流程

1、事先确定常数K ,常数K意味着最终的聚类类别数

2、随机选择 K 个样本点作为初始聚类中心

3、计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别

4、根据每个类别中的样本点,重新计算出新的聚类中心点(平均值),如果计算得出的新中心点 与原中心点一样则停止聚类,否则重新进行第 2 步过程,直到聚类中心不再变化

数学计算流程:https://blog.csdn.net/qq_35496811/article/details/155610871?spm=1001.2014.3001.5502

误差平方和SSE (The sum of squares due to error)

“肘”方法 (Elbow method) - K值确定

• "肘" 方法通过 SSE 确定 n_clusters 的值

• 对于n个点的数据集,迭代计算 k (from 1 to n),每次聚类完成后计算 SSE

• SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。

• SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters值。

• 在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。

SC轮廓系数法(Silhouette Coefficient)

轮廓系数法考虑簇内的内聚程度(Cohesion),簇外的分离程度(Separation)。其计算过程如下

• 对计算每一个样本 i到同簇内其他样本的平均距离𝑎i,该值越小,说明簇内的相似程度越大

• 计算每一个样本 i到最近簇 j 内的所有样本的平均距离 bij,该值越大,说明该样本越不属于其他簇 j

• 根据下面公式计算该样本的轮廓系数:

• 计算所有样本的平均轮廓系数

• 轮廓系数的范围为:[-1, 1]

聚类效果评估 – CH轮廓系数法(Calinski-HarabaszIndex)

CH 系数考虑簇内的内聚程度、簇外的离散程度、质心的个数

•类别内部数据的距离平方和越小越好,类别之间的距离平方和越大越好。聚类的种类数越少越好

聚类效果评估 – 代码效果展示SSE误差平方和

from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.metrics import calinski_harabasz_score def dm01(): x, y = make_blobs( n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=40 ) sse_list = [] for clu_num in range(1, 100): my_kmeans = KMeans( n_init='auto', n_clusters=clu_num, max_iter=100, random_state=40 ) my_kmeans.fit(x) sse_list.append(my_kmeans.inertia_) # 误差平方和SSE plt.figure(figsize=(18, 8), dpi=100) plt.xticks(range(0, 100, 3), labels=range(0, 100, 3)) plt.grid() plt.title('sse') plt.plot(range(1, 100), sse_list, 'or-') plt.show() dm01()

聚类效果评估 – 代码效果展示 – SC系数

# 1.导入依赖包 from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.metrics import silhouette_score def dm01(): # 2.构建数据,产生数据random_state=22固定好 x, y = make_blobs( n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=22 ) # 3.模型训练及SC系数 tmp_list = [] for clu_num in range(2, 100): my_kmeans = KMeans( n_init='auto', n_clusters=clu_num, max_iter=100, random_state=0 ) my_kmeans.fit(x) ret = my_kmeans.predict(x) tmp_list.append(silhouette_score(x, ret)) # SC系数 # 4.效果展示 plt.figure(figsize=(18, 8), dpi=100) plt.xticks(range(0, 100, 3), labels=range(0, 100, 3)) plt.grid() plt.title('sc') plt.plot(range(2, 100), tmp_list, 'ob-') plt.show() dm01()

聚类效果评估 – 代码效果展示 – CH系数

# 1.导入依赖包 from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.metrics import calinski_harabasz_score def dm01(): # 2.构建数据,产生数据random_state=22固定好 x, y = make_blobs( n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=22 ) # 3.模型训练及CH tmp_list = [] for clu_num in range(2, 100): my_kmeans = KMeans( n_init='auto', n_clusters=clu_num, max_iter=100, random_state=0 ) my_kmeans.fit(x) ret = my_kmeans.predict(x) tmp_list.append(calinski_harabasz_score(x, ret)) # CH # 4.展示效果 plt.figure(figsize=(18, 8), dpi=100) plt.xticks(range(0, 100, 3), labels=range(0, 100, 3)) plt.grid() plt.title('ch') plt.plot(range(2, 100), tmp_list, 'og-') plt.show() dm01()

通过上述3个图片,当n_clusters=4 取到最大值;最佳值4

案例:顾客数据聚类分析

• 已知:客户性别、年龄、年收入、消费指数

• 需求:对客户进行分析,找到业务突破口,寻找黄金客户

• 客户分群效果展示:

• 代码:

# 1.导入依赖包 import pandas as pd from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.metrics import silhouette_score, calinski_harabasz_score # 聚类分析用户分群 def dm01(): # 2.数据读取及预处理 # 2.1 数据读取 dataset = pd.read_csv('data/customers.csv') print(dataset.head(2)) # 2.2 特征选择 X = dataset.iloc[:, [3, 4]] print('X -->\n', X) plt.figure(figsize=(8, 6)) plt.scatter(X.iloc[:, 0], X.iloc[:, 1], s=50, alpha=0.7, edgecolors='w') plt.title('Customer Data Scatter (Annual Income vs Spending Score)') plt.xlabel(X.columns[0]) # 'Annual Income (k$)' plt.ylabel(X.columns[1]) # 'Spending Score (1-100)' plt.grid(True, alpha=0.3) plt.show() # 3.模型训练,评估聚类个数K值选择 sse_list = [] sc_list = [] ch_list = [] for i in range(2, 20): my_kmeans = KMeans( n_init='auto', n_clusters=i, max_iter=100, random_state=0 ) my_kmeans.fit(X) ret = my_kmeans.predict(X) sse_list.append(my_kmeans.inertia_) # SSE inertia 簇内误差平方和 sc_list.append(silhouette_score(X, ret)) # SC系数 聚类需要1个以上的类别 ch_list.append(calinski_harabasz_score(X, ret)) # CH # 效果展示 plt.figure(figsize=(18, 8), dpi=100) plt.xticks(range(0, 20, 1), labels=range(0, 20, 1)) plt.plot(range(2, 20), sse_list, 'or-') plt.title('sse') plt.xlabel('number of clusters') plt.ylabel('sse') plt.grid() plt.show() plt.plot(range(2, 20), sc_list, 'ob-') plt.title('sc') plt.grid(True) plt.show() # 4.展示效果 plt.plot(range(2, 20), ch_list, 'og-') plt.title('ch') plt.grid() plt.show() dm01() def dm02(): # 2.读取数据及数据预处理 dataset = pd.read_csv('data/customers.csv') X = dataset.iloc[:, [3, 4]] # 3.模型训练及预测 mykeans = KMeans(n_clusters=5) mykeans.fit(X) y_kmeans = mykeans.predict(X) # 4.聚类效果展示 # 把类别是0的, 第0列数据,第1列数据, 作为x/y, 传给plt.scatter函数 plt.scatter(X.values[y_kmeans == 0, 0], X.values[y_kmeans == 0, 1], s=20, c='red', label='Standard') # 把类别是1的, 第0列数据,第1列数据, 作为x/y, 传给plt.scatter函数 plt.scatter(X.values[y_kmeans == 1, 0], X.values[y_kmeans == 1, 1], s=20, c='blue', label='Traditional') # 把类别是2的, 第0列数据,第1列数据, 作为x/y, 传给plt.scatter函数 plt.scatter(X.values[y_kmeans == 2, 0], X.values[y_kmeans == 2, 1], s=20, c='green', label='Normal') # 把类别是3的, 第0列数据,第1列数据, 作为x/y, 传给plt.scatter函数 plt.scatter(X.values[y_kmeans == 3, 0], X.values[y_kmeans == 3, 1], s=20, c='cyan', label='Youth') # 把类别是4的, 第0列数据,第1列数据, 作为x/y, 传给plt.scatter函数 plt.scatter(X.values[y_kmeans == 4, 0], X.values[y_kmeans == 4, 1], s=20, c='magenta', label='TA') # 每个簇的中心点 plt.scatter(mykeans.cluster_centers_[:, 0], mykeans.cluster_centers_[:, 1], s=300, c='black', label='Centroids') plt.title('Clusters of customers') plt.xlabel('Annual Income (k$)') plt.ylabel('Spending Score (1-100)') plt.legend() plt.show() dm02()

  • k 越大,簇内举例 (SSW) 越小(每个簇样本越少,越紧凑)
  • k 越大,簇间距离 (SSB) 也会变大(因为簇被分得更细,簇与簇之间距离可能被拉开)

当 k 继续增加时:

  • 如果数据本身没有那么多天然簇(比如 customers 数据可能只有 4–6 个真实群),强行分更多簇会导致:
    • 簇内距离继续下降(因为每个簇样本极少,甚至变成单点)
    • 簇间距离被“人为拉大”(分得越细,簇间平均距离越大)
  • 结果:CH 分数在某个点后会重新上升,形成“假高峰”。

结论:CH 分数后面变大,是过拟合的信号,说明 k 已经太大,算法开始把噪声当成簇了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 17:22:39

基于空间视频重构的仓储三维透视化管理与前向布控一体化技术方案

基于空间视频重构的仓储三维透视化管理与前向布控一体化技术方案 摘要 本技术方案面向高安全等级仓储场景,提出一套基于空间视频重构的仓储三维透视化管理与前向布控/空间围堵一体化系统。方案以“像素即坐标、视频即空间”为技术核心,通过多视角视频标…

作者头像 李华
网站建设 2026/7/22 14:43:36

从零开始参与开源:手把手教你提交第一个 PR

文章目录 前言一、 理解项目规范:许可证与核心文件二、 筛选任务:利用标签定位入门级 Issue三、 构建协作环境:Fork、Clone 与上游同步四、 规范化开发:分支策略与本地检查五、 提交代码:遵循 Conventional Commits 规…

作者头像 李华
网站建设 2026/7/19 11:01:45

RapidRAW(RAW图像编辑器)

链接:https://pan.quark.cn/s/f079b66b19f2 RapidRAW官方最新版是一款轻量级、高性能且基于GPU加速的RAW图像编辑器,不仅能够体积相对小巧,而且还针对RAW格式进行了专业的优化,此外简洁的界面也让用户可以快速上手。本次更新也是…

作者头像 李华
网站建设 2026/7/20 17:09:52

低代码爬虫利器结合Python Selenium,自动采集商品数据

说实话,现在跨境电商竞争之激烈,获客之难,早已不是搭个台子就能唱戏的阶段,需要各种竞品数据、用户评价数据监测分析,及时掌握哪些产品卖的好,卖的好的产品标题怎么写、用户情感反馈等等,相当的…

作者头像 李华
网站建设 2026/7/18 22:20:41

如何通过AI提升数据分析能力

如何通过AI提升数据分析能力关键词:AI、数据分析能力、数据挖掘、机器学习、深度学习、自动化分析、数据洞察摘要:本文旨在探讨如何借助AI技术提升数据分析能力。首先介绍了相关背景,包括目的范围、预期读者等内容。接着阐述了核心概念与联系…

作者头像 李华
网站建设 2026/7/22 0:52:13

springboot基于java的网上拍卖系统文献综述

目录基于Spring Boot的网上拍卖系统文献综述技术架构与框架选择核心功能模块设计安全与风控机制性能优化策略未来研究方向项目技术支持可定制开发之功能亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作基于Spring Boot的网上拍卖系统文献…

作者头像 李华