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

一、聚类算法

概念

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

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

分类

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

按实现方法分为: 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

相关推荐
_Coin_-4 小时前
算法训练营DAY58 第十一章:图论part08
数据结构·算法·图论
scx201310044 小时前
P13929 [蓝桥杯 2022 省 Java B] 山 题解
c++·算法·蓝桥杯·洛谷
YC运维4 小时前
Ansible题目全解析与答案
java·算法·ansible
jie*4 小时前
小杰机器学习(two)——导数、损失函数、斜率极值最值、微分规则、切平面与偏导数、梯度。
人工智能·机器学习
小欣加油5 小时前
leetcode 912 排序数组(归并排序)
数据结构·c++·算法·leetcode·排序算法
山河君6 小时前
webrtc之高通滤波——HighPassFilter源码及原理分析
算法·音视频·webrtc·信号处理
星辰大海的精灵6 小时前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
data myth6 小时前
力扣1210. 穿过迷宫的最少移动次数 详解
算法·leetcode·职场和发展
惯导马工6 小时前
【论文导读】AI-Assisted Fatigue and Stamina Control for Performance Sports on IMU-Gene
深度学习·算法