首页 > 编程语言 >带你从入门到精通——机器学习(九. 聚类算法)

带你从入门到精通——机器学习(九. 聚类算法)

时间:2025-01-04 20:30:21浏览次数:3  
标签:入门 样本 KMeans 算法 聚类 SSE 质心

建议先阅读我之前的博客,掌握一定的机器学习前置知识后再阅读本文,链接如下:

带你从入门到精通——机器学习(一. 机器学习概述)-CSDN博客

带你从入门到精通——机器学习(二. KNN算法)-CSDN博客

带你从入门到精通——机器学习(三. 线性回归)-CSDN博客

带你从入门到精通——机器学习(四. 逻辑回归)-CSDN博客

带你从入门到精通——机器学习(五. 决策树)-CSDN博客

带你从入门到精通——机器学习(六. 集成学习)-CSDN博客

带你从入门到精通——机器学习(七. 特征降维)-CSDN博客

带你从入门到精通——机器学习(八. 朴素贝叶斯算法)-CSDN博客

目录

九. 聚类算法

9.1 聚类算法的概念

9.2 聚类算法的分类

9.2 KMeans算法

9.3 聚类的评估指标

9.3.1 误差平方和

9.3.2 肘方法

9.3.3 轮廓系数

9.3.4 Calinski-Harabasz指数

9.4 KMeans算法聚类实例


九. 聚类算法

9.1 聚类算法的概念

        聚类算法是一种无监督学习算法,其目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式,然后根据样本之间的相似性,将样本划分到不同的类别中,而不同的相似度计算方法(聚类准则),也会得到不同的聚类结果,常用的相似度计算方法有欧式距离法、余弦相似度法等等。

9.2 聚类算法的分类

        聚类算法根据聚类颗粒度可以分为以下两类:

        粗粒度聚类:这种聚类方法生成的簇较大,包含较多的数据点,适用于需要快速识别大类别的场景,但可能会丢失一些细粒度的信息。

        细粒度聚类:这种聚类方法生成的簇较小,包含较少的数据点,适用于需要详细区分数据子类别的场景,但可能会产生过多的簇,增加计算复杂度。

        两种聚类方式具体表现形式如下图:

        根据实现方法分类:

        Kmeans:按照质心分类(质心数即为聚类的簇数),下文会详细介绍K-means,K-means也是一种比较通用、普遍的聚类算法。

        层次聚类:分为凝聚层次聚类(Agglomerative Hierarchical Clustering)分裂层次聚类(Divisive Hierarchical Clustering)两种方法。在凝聚层次聚类中,初始会将每个数据点被视为一个单独的簇,然后逐步将最相似的簇合并,直到所有数据点合并成一个簇达到预定的簇数;在分裂层次聚类中,初始会将所有数据点被视为一个簇,然后逐步将簇分裂成更小的簇,直到每个数据点成为一个单独的簇达到预定的簇数

        高斯混合模型聚类(Gaussian Mixture Model,GMM):高斯混合模型是由多个高斯分布混合而成的模型,其数学表达式如下:

        高斯混合模型聚类是假设数据的分布是由多个高斯分布的混合而成,并使用期望最大化(Expectation Maximization,EM)算法计算每个点的后验概率,即每个数据点属于每个高斯分布的概率,通常最后会选择后验概率最大的高斯分布作为该数据点的簇标签

9.2 KMeans算法

        KMeans算法的实现流程如下:

        1. 事先确定常数K ,常数K意味着最终的聚类类别数(也是质心的个数)。

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

        3. 计算每个样本到K个中心的距离,选择距离最近的聚类中心点作为该样本的簇标签。

        4. 根据每个簇中的样本点,重新计算出新的聚类中心点(通常是求簇中样本点的平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第3步的过程,直到聚类中心不再变化(即质心不再移动)或达到最大迭代次数。

9.3 聚类的评估指标

9.3.1 误差平方和

        误差平方和(The sum of squares due to error,SSE)是衡量聚类效果的一个常用指标,主要考虑了簇内的内聚程度,其数学表达式如下:

        其中Ci表示各个簇,k表示聚类中心的个数(簇数),p表示某个簇内的样本,mi表示各个簇的质心点(聚类中心点),SSE计算了每个样本点到质心的欧式距离的平方和,并累加起来,SSE越小,表示数据点越接近它们的中心,聚类效果越好

9.3.2 肘方法

        使用肘方法(Elbow method)可以帮助我们寻找KMeans的最佳K值,具体流程如下:

        1. 对于n个点的数据集,取不同的K值(K值的取值范围为1到n)使用KMeans算法进行聚类,并依次计算不同K值下的SSE。

        2. 以各个SSE为y轴,对应的K值为x轴绘制一个折线图,随着K值的增大,SSE是会逐渐变小的,而SSE在变化过程中会出现一个拐点,即下降率突然变缓的点,此时对应的K值即可认为是最佳的K值

        示意图如下:

9.3.3 轮廓系数

        轮廓系数(Silhouette Coefficient,SC)考虑了簇内的内聚程度(Cohesion)以及簇外的分离程度(Separation)

        SC的值越大,表示聚类效果越好,其计算过程如下

        1. 对计算一个样本i到同簇内其他样本的平均距离ai,该值越小,说明簇内的相似程度越大,簇内的内聚程度越大,常用的距离度量方法有欧氏距离、曼哈顿距离等。

        2. 计算一个样本i到所以其他簇j内的所有样本的平均距离bij,该值越大,说明该样本越不属于其他簇j,簇外的分离程度越大,最后取bij的最小值作为bi。

        3. 根据下面公式计算单个样本i的轮廓系数

        4. 计算所有样本的平均轮廓系数,注意:轮廓系数的范围为[-1, 1]

        计算SC的图示如下:

9.3.4 Calinski-Harabasz指数

        Calinski-Harabasz指数(Calinski-Harabasz Index),简称CH指数,CH指数考虑了簇内的内聚程度以及簇外的离散程度的同时还考虑了质心的个数(即簇的个数、聚类的类别个数),使用CH指数评估聚类效果能够到达用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果

        CH指数的值越大,表示聚类效果越好,其计算方式如下:

        上式中m表示样本数量,k表示质心个数。

        SSW表示组内平方和(Sum of Squares Within Treatment),相当于SSE,表示了簇内距离,该值越小越好,计算公式如下:

        其中xi表示某个样本,Cpi表示样本i所属的质心,SSW值计算了每个样本点到质心的欧式距离的平方和。

        SSB表示组间平方和(Sum of Squares Between Groups),表示了簇间距离该值越大越好,计算公式如下:

        其中Cj表示质心,表示数据集的中心点,nj表示属于Cj的样本个数,SSB值计算了各个质心到数据集中心的欧式距离的平方乘以该簇内的样本个数,并累加起来。

        由于CH指数的计算公式前有一个系数,在m一定的情况下,k越小,该系数越大,最终的CH指数也就越大,所以聚类的簇数越少越好

9.4 KMeans算法聚类实例

        使用KMeans算法进行聚类的具体实现代码如下:

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.metrics import calinski_harabasz_score, silhouette_score

# 生成1000个二维数据,指定了5个中心点,每个中心点有100个样本,并指定了每个中心点的方差
# x是二维数据,_是标签(聚类算法为无监督学习不使用标签),都为数组类型
x, _ = make_blobs(n_samples=1000, n_features=2,
                  centers=[[0, 0], [-1, -1], [2, 2], [3, 3], [4, 4]],
                  cluster_std=[0.2, 0.5, 0.1, 0.3, 0.1],
                  random_state=66)

# 使用肘方法确定最佳聚类中心个数
sse_list, sc_list, ch_list = [], [], []
for k in range(2, 10):
    # 创建KMeans模型
    k_means = KMeans(n_clusters=k)
    # 训练并进行聚类预测
    y_pred = k_means.fit_predict(x) # y_pred为每个样本的聚类类别,类型为数组
    print(y_pred, type(y_pred))
    sse_list.append(k_means.inertia_) #  inertia_属性即为误差平方和(SSE),也就是每个样本点到质心的距离的平方和
    sc_list.append(silhouette_score(x, y_pred))
    ch_list.append(calinski_harabasz_score(x, y_pred))

# 绘制SSE,SC,CH指数与k值的折线图
# 创建一个大小为20x30的图形对象
fig = plt.figure(figsize=(20, 30))
# 添加第一个子图,用于展示SSE(误差平方和)随k值变化的情况
ax1 = fig.add_subplot(3, 1, 1)
# 绘制SSE变化曲线,x轴为k值范围(2到10),y轴为SSE值列表
ax1.plot(range(2, 10), sse_list)
# 设置子图标题为'SSE'
ax1.set_title('SSE')
# 设置x轴标签为'k'
ax1.set_xlabel = 'k'

# 添加第二个子图,用于展示轮廓系数随k值变化的情况
ax2 = fig.add_subplot(3, 1, 2)
# 绘制轮廓系数变化曲线,x轴为k值范围(2到10),y轴为轮廓系数列表
ax2.plot(range(2, 10), sc_list)
# 设置子图标题为'Silhouette Coefficient'
ax2.set_title('Silhouette Coefficient')
# 设置x轴标签为'k'
ax2.set_xlabel = 'k'

# 添加第三个子图,用于展示Calinski Harabasz指数随k值变化的情况
ax3 = fig.add_subplot(3, 1, 3)
# 绘制Calinski Harabasz指数变化曲线,x轴为k值范围(2到10),y轴为CH指数列表
ax3.plot(range(2, 10), ch_list)
# 设置子图标题为'Calinski Harabasz Index'
ax3.set_title('Calinski Harabasz Index')
# 设置x轴标签为'k'
ax3.set_xlabel = 'k'
# 显示整个图形
plt.show()

# 使用肘方法确定了最佳的K值为5,创建KMeans模型,指定聚类中心个数为5
k_means = KMeans(n_clusters=5)
# 模型训练
k_means.fit(x)
# 模型聚类预测
y_pred = k_means.predict(x)
# 绘制聚类结果
# x[:, 0] 和 x[:, 1] 分别表示数据点的横坐标和纵坐标
# 参数c=y_pred,表示根据 y_pred 的值为每个点分配颜色。
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()
# 输出CH指数
print(calinski_harabasz_score(x, y_pred))

标签:入门,样本,KMeans,算法,聚类,SSE,质心
From: https://blog.csdn.net/2401_86480334/article/details/144932894

相关文章

  • MyBatis-Plus快速入门
    MyBatis-Plus快速入门一、简介二、入门案例1、开发环境2、创建数据库和表3、创建SpringBoot工程4、引入依赖5、配置application.yml6、创建User实体类、UseMapper接口、MybatisPlusTest测试类三、基本功能1、【增、删、改、查】示例2、自定义功能测试3、持久层接口......
  • Spark职位信息推荐系统 协同过滤推荐算法 Echarts可视化 Django框架 简历投递 大数据
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......
  • 学习《ROS2机器人开发从入门到实践》Day2
    文章目录前言一、将.sh普通文件变成可执行文件1.创建一个zxx.sh的普通文件2.给该文件添加可执行权限二、Linux环境变量1.查看ROS版本号2.查看ROS发行版本3.查看系统所有环境变量三、环境变量作用1.ros2run命令解释2.查看ROS2存放路径3.直接执行turtlesim_node4.环境变......
  • Java学习教程,从入门到精通,Java Lambda 表达式语法知识点及案例代码(79)
    JavaLambda表达式语法知识点及案例代码Lambda表达式是Java8引入的一项重要特性,它允许我们将代码当作数据来传递,从而使代码更加简洁和易读。1.什么是Lambda表达式?Lambda表达式是一种匿名函数,它没有类和方法名,可以直接作为参数传递给方法或存储在变量中。2.Lambda表......
  • 基于SpringBoot Vue协同过滤算法美食推荐小程序的设计与实现
    1.引言在当今的软件开发领域,企业级应用的开发和部署速度直接影响着业务的竞争力。SpringBoot以其轻量级、快速启动和强大的集成能力,成为构建现代企业级应用的首选框架。本文将带您深入了解SpringBoot框架的核心特性,并展示如何利用它构建一个高效、可扩展的系统。2.开发......
  • 【强化学习】Double DQN(Double Deep Q-Network)算法
            ......
  • 【强化学习】双延迟深度确定性策略梯度算法(TD3)详解
            ......
  • LeetCode算法题 (二叉树的直径)Day11!!!C/C++
    https://leetcode.cn/problems/diameter-of-binary-tree/description/一、题目描述给你一棵二叉树的根节点,返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它......
  • 素数入门笔记
    试除法从\(2\)枚举到\(\lfloor\sqrtn\rfloor\)判断能否整除。朴素筛法从小到大枚举每个数,将范围内它的倍数全部标记为合数。时间复杂度显然就是调和级数\(O(n\logn)\)。埃氏筛观察到一个合数必定可以通过某个质数乘上某个数得到。从小到大枚举每个质数,将范围内它的......
  • 程序员如何自己赚钱?零基础入门到精通,收藏这篇就够了
    看了很多案例,独立开发者有哪些赚钱的路子呢?第一种是开发和销售软件产品,开发软件,网站,APP,小程序,卖授权服务赚钱,独立开发者可以创建软件或应用程序,并通过各种平台销售。例如:开发移动应用程序,通过应用商店(如AppStore或GooglePlay)出售,或通过应用内广告和订阅模式盈利。桌面......