Day23_【机器学习—聚类算法—K-Means聚类 及评估指标SSE、SC、CH】

发布于:2025-09-09 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、聚类算法

概念

        属于无监督学习算法,即有特征无标签,根据样本之间的相似性,将样本划分到不同的类别中。

所谓相似性可以理解为欧氏距离、曼哈顿距离、切比雪夫距离... 。

分类

按颗粒度分为:粗聚类、细聚类。

按实现方法分为: K-means聚类、层次聚类、 DBSCAN聚类、谱聚类

二、K-Means聚类

        K-Means 是机器学习中最经典、最常用的聚类算法之一

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

        适用场景:一般大厂,项目初期在没有 先备知识的情况下的大厂

实现流程 ​​​​

                

  1. 事先确定常数K ,常数K意味着最终的聚类类别数
  2. 随机选择 K 个样本点作为初始聚类中心
  3. 计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别
  4. 根据每个类别中的样本点,重新计算出新的聚类中心点(平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第 3 步过程,直到聚类中心不再变化

实现API

sklearn.cluster.KMeans

# 1.导入工具包
import os
os.environ['OMP_NUM_THREADS']='4'
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs #数据生成器
from sklearn.metrics import calinski_harabasz_score  # 评估指标,值越大聚类效果越好
# 2 创建数据集 1000个样本,每个样本2个特征,4个质心蔟,数据标准差[0.4, 0.2, 0.2, 0.2],随机种子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)
# x[:, 0]:横坐标(第一个特征)
# x[:, 1]:纵坐标(第二个特征)
print(x) #坐标
print(y) #标签
# 参1:横坐标,参2:纵坐标
plt.scatter(x[:, 0], x[:, 1])
plt.show()
# 3 使用k-means进行聚类, 并使用CH方法评估
es = KMeans(n_clusters=4, random_state=22)
y_pre=es.fit_predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_pre)
plt.show()
# 4 模型评估
print(calinski_harabasz_score(x, y_pre))

三、聚类算法的评估指标

1. SSE + 肘部法

SSE
  • 概述:所有的簇 的所有样本到该簇质心的 误差的平方和
  • 特点:随着K值增加,SSE值逐渐减少
  •  目标:  SSE越小,簇内样本越聚集,内聚程度越高

        

肘部法—K值确定
  • 对于n个点的数据集,迭代计算 k from 1 to n,每次聚类完成后计算 SSE
  • SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。
  • SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值
  • 在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。

                        

K值增大,SSE值会随之减小,下降梯度突然变换的时候,那个K的值,就是我们要寻找得最佳值

API实现
#导包
import os
os.environ['OMP_NUM_THREADS']='4'
#导包
from sklearn.cluster import KMeans  #聚类API  采用指定 质心 分簇
import matplotlib.pyplot as plt
from sklearn.datasets import  make_blobs  # 默认会按照高斯分布(正态分布)生成数据集 ,只需要 指定 均值 ,标准差


#1、定义函数 演示:SSE+肘部法
def dm01_sse():
    #0、定义SSE列表 ,目的:每个K值的SSE值
    sse_list = []
    #1、获取数据
    #参1:样本数量  参2:特征数量 参3:4个簇的质点  参4:std标准差  参5:固定随机种子
    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=23
    )

    #2、for训练  训练   获取每个K值,对应的SSE值
    for k in range(1,100):
        #2.1创建模型
        #参1:簇的数量
        #参2:最大迭代次数
        #参3:固定随机种子
        es=KMeans(n_clusters=k,max_iter=100,random_state=23)
        #2.2 训练模型
        es.fit(x)
        #2.3获取每个簇的sse值
        sse_value=es.inertia_
        #2.4将每个K值对应的SSE值,添加到sse_list
        sse_list.append(sse_value)

    #3.绘制SSE曲线 -》数据可视化
    # print(sse_list)
    #3.1创建画布
    plt.figure(figsize=(20,10))
    #3.2设置标题
    plt.title("sse value")
    #3.3设置x轴
    plt.xticks(range(0,100,3))
    #参1:K值  参2:该K值所对应的SSE值
    # o  圆点样式
    # r 红色
    # - 连接数据点的样式  实线
    # color='r'   marker='o'  linestyle='-'
    plt.plot(range(1,100),sse_list,'or-')
    plt.xlabel("k")
    plt.ylabel("sse")
    plt.grid()
    plt.show()

if __name__ == '__main__':
    dm01_sse()

 聚类效果评估 – 代码效果展示SSE误差平方和,x轴为k值,y轴为SSE值

        

通过图像可观察到 n_clusters=4 sse开始下降趋缓, 最佳值4

2. SC轮廓系数法—高内聚低耦合

轮廓系数法考虑簇内的内聚程度(Cohesion),簇外的分离程度(Separation)

  • 对计算每一个样本 i 到同簇内其他样本的平均距离 ai,该值越小,说明簇内的相似程度越大
  • 计算每一个样本 i 到最近簇 j 内的所有样本的平均距离 bij,该值越大,说明该样本越不属于其他簇 j
  • 根据下面公式计算该样本的轮廓系数:S = b −a/max⁡(a, b)
  • 计算所有样本的平均轮廓系数
  • 轮廓系数的范围为:[-1, 1],SC值越大聚类效果越好

                

API实现
#导包
import os
os.environ['OMP_NUM_THREADS']='4'
#导包
from sklearn.cluster import KMeans  #聚类API  采用指定 质心 分簇
import matplotlib.pyplot as plt
from sklearn.datasets import  make_blobs  # 默认会按照高斯分布(正态分布)生成数据集 ,只需要 指定 均值 ,标准差
from sklearn.metrics import silhouette_score,calinski_harabasz_score  #silhouette_score :sc   calinski_harabasz_score:ch


def dm02_sc轮廓系数法():
    #0、定义sc列表 ,目的:每个K值的SSE值
    sc_list = []
    #1、获取数据
    #参1:样本数量  参2:特征数量 参3:4个簇的质点  参4:std标准差  参5:固定随机种子
    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=23
    )


    #3、遍历for循环  获取每个K值 ,计算对应SC值  ,并添加到sc_list列表中
    for k in range(2,100): #考虑簇外 至少2簇
        es=KMeans(n_clusters=k,max_iter=100,random_state=23)
        es.fit(x)
        y_pre=es.predict(x)
        sc_value=silhouette_score(x,y_pre)
        sc_list.append(sc_value)


    #绘制sc曲线-》数据可视化
    plt.figure(figsize=(20,10))
    plt.title("sc value")
    plt.xticks(range(0,100,3))
    plt.xlabel("k")
    plt.ylabel("sc")
    plt.grid()
    # 注意  sc 值从2开始
    plt.plot(range(2,100),sc_list,'or-')
    plt.show()
if __name__ == '__main__':
    dm02_sc轮廓系数法()

代码效果展示 – SC系数

        

                通过图像可观察到 n_clusters=4 取到最大值; 最佳值4

3.CH轮廓系数法—高内聚低耦合加质心

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

CH系数越大越好

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

                

SSW 的含义:相当于SSE,簇内距离

SSB 的含义:簇间距离

API实现

#导包
import os
os.environ['OMP_NUM_THREADS']='4'
#导包
from sklearn.cluster import KMeans  #聚类API  采用指定 质心 分簇
import matplotlib.pyplot as plt
from sklearn.datasets import  make_blobs  # 默认会按照高斯分布(正态分布)生成数据集 ,只需要 指定 均值 ,标准差
from sklearn.metrics import silhouette_score,calinski_harabasz_score  #silhouette_score :sc   calinski_harabasz_score:ch


def dm03_CH系数():
    #0、定义sc列表 ,目的:每个K值的SSE值
    ch_list = []
    #1、获取数据
    #参1:样本数量  参2:特征数量 参3:4个簇的质点  参4:std标准差  参5:固定随机种子
    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=23
    )


    #3、遍历for循环  获取每个K值 ,计算对应SC值  ,并添加到sc_list列表中
    for k in range(2,100): #考虑簇外 至少2簇
        es=KMeans(n_clusters=k,max_iter=100,random_state=23)
        es.fit(x)
        y_pre=es.predict(x)
        sc_value=calinski_harabasz_score(x,y_pre)
        ch_list.append(sc_value)


    #绘制sc曲线-》数据可视化
    plt.figure(figsize=(20,10))
    plt.title("ch value")
    plt.xticks(range(0,100,3))
    plt.xlabel("k")
    plt.ylabel("ch")
    plt.grid()
    # 注意  sc 值从2开始
    plt.plot(range(2,100),ch_list,'or-')
    plt.show()
if __name__ == '__main__':
    dm03_CH系数()

代码效果展示 – CH系数

        

通过图像可观察到 n_clusters=4 取到最大值; 最佳值4


网站公告

今日签到

点亮在社区的每一天
去签到