机器学习:聚类算法

本文深入探讨了无监督学习中的聚类算法,重点讲解了K-means算法的原理和实现步骤。通过示例展示了K-means如何根据样本间的相似性进行分组,并使用SSE、轮廓系数和CH系数等方法评估聚类效果。同时,讨论了肘部法则在确定最佳簇数中的应用。
摘要由CSDN通过智能技术生成

1. 聚类概念

  一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。

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

  聚类算法和分类算法最大的区别是:聚类是无监督学习算法,而分类算法是监督学习算法

2. 聚类算法的实现流程

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

3. K-means算法

k-means其实包含两层内容:

  • K : 初始中心点个数(计划聚类数)
  • means:求中心点到其他数据点距离的平均值

通过下图解释实现流程:
在这里插入图片描述
代码实现:

# 1 导入模块和包
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabasz_score,silhouette_score

# 2 生成数据
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=9)

# 3 数据可视化
plt.figure(figsize=(20, 8),dpi=100)
plt.scatter(X[:,0],X[:, 1])
plt.show()

在这里插入图片描述
用K-means算法对模型进行训练,设置不同的中心点,查看输出结果

当n_clusters = 2 时:

# 1、模型训练
y_pre = KMeans(n_clusters = 2).fit_predict(X)

# 2、图形展示
plt.figure(figsize=(20, 8),dpi=100)
plt.scatter(X[:,0],X[:, 1],c=y_pre)
plt.show()

# 3、模型评估
calinski_harabasz_score(X, y_pre)
输出结果:3116.1706763322227

在这里插入图片描述
当n_clusters = 3 时:

# 1、模型训练
y_pre = KMeans(n_clusters = 3).fit_predict(X)

# 2、图形展示
plt.figure(figsize=(20, 8),dpi=100)
plt.scatter(X[:,0],X[:, 1],c=y_pre)
plt.show()

# 3、模型评估
calinski_harabasz_score(X, y_pre)
输出结果:2931.543778093064

在这里插入图片描述
当n_clusters = 4 时:

# 1、模型训练
y_pre = KMeans(n_clusters = 4).fit_predict(X)

# 2、图形展示
plt.figure(figsize=(20, 8),dpi=100)
plt.scatter(X[:,0],X[:, 1],c=y_pre)
plt.show()

# 3、模型评估
calinski_harabasz_score(X, y_pre)
输出结果:5924.050613480169

在这里插入图片描述

4 评估方法

4.1 聚类效果评估标准

  1. 簇内内聚程度如何
  2. 簇外分离程度如何
  3. 簇内越内聚,簇外越分散越好

4.2 误差平方和SSE

评估公式:
S S E = ∑ i = 1 k ∑ p ∈ C i ∣ p − m i ∣ 2 SSE=\sum_{i=1}^{\mathrm{k}} \sum_{p \in C_{i}}\left|p-m_{i}\right|^{2} SSE=i=1kpCipmi2

  • 考虑簇内的内聚程度
  • k 表示质心的个数
  • p 表示某个簇内的样本
  • m 表示质心点
  • SSE 的值越大说明聚类效果越不好

先计算一个簇内所有点到质心的距离平方和,再对所有簇距离平方和求和。

公式内各部分内容:

在这里插入图片描述
上图中: k=2

SSE图最终的结果,对图松散度的衡量:(eg: SSE(左图)<SSE(右图))

SSE随着聚类迭代,其值会越来越小,直到最后趋于稳定。

注意:SSE算法内质心的选取时随机的,因此,在质心选取时,当两个质心初始距离较近时,可能产生不好的结果,因此SSE最后的结果是局部内最优解,而不是全局最优解。如下图所示:
在这里插入图片描述

  • 如果质心的初始值选择不好,SSE只会达到一个不怎么好的局部最优解

在这里插入图片描述

代码实现:

# 1、创建空列表
sse_list = []

# 2、设置中心点个数,查看SSE的变化范围
for clu_num in range(1, 100):
    
    # 初始化迭代器一次的Kmeans
    my_kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=0)
    
    # 模型训练
    my_kmeans.fit(X)
    
    # 将SSE的每一次迭代结果添加到空列表内
    sse_list.append(my_kmeans.inertia_)
# 3、图像可视化
plt.figure(figsize=(20, 8), dpi=100)
plt.scatter(range(1, 100), sse_list)
plt.plot(range(1, 100), sse_list)
x_ticks = range(1, 100, 2)
plt.xticks(x_ticks)
plt.xlabel('中心点个数')
plt.ylabel('误差平方和')
plt.grid()
plt.show()

在这里插入图片描述
从上图可得: 当中心点个数为4时,SSE系数达到最大值,聚合效果最好

4.3 轮廓系数法(Silhouette Coefficient)

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

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

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

  3. 根据下面公式计算该样本的轮廓系数:
    s = b − a max ⁡ ( a , b ) s=\frac{b-a}{\max (a, b)} s=max(ab)ba

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

  5. 轮廓系数的范围为:[-1, 1],值越大聚类效果越好

在这里插入图片描述
代码实现:

# 1、创建空列表
sc_list = []

# 2、设置中心点个数,查看SC的变化范围
for clu_num in range(2, 100):
    
    # 初始化迭代器一次的Kmeans
    my_kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=0)
    
    # 模型训练
    my_kmeans.fit(X)
    
    # 将SC的每一次迭代结果添加到空列表内
    sc_list.append(silhouette_score(X, y_pre))
    
# 3、图像可视化
plt.figure(figsize=(20, 8), dpi=100)
plt.scatter(range(2, 100), sc_list)
plt.plot(range(2, 100), sc_list)
x_ticks = range(1, 100, 2)
plt.xticks(x_ticks)
plt.xlabel('中心点个数')
plt.ylabel('轮廓系数')
plt.grid()
plt.show()

在这里插入图片描述
从上图可得: 当中心点个数为4时,SC系数达到最大值,聚合效果最好

4.4 CH 系数

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

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

C H ( k ) = S S B S S W m − k k − 1 S S W = ∑ i = 1 m ∥ x i − C p i ∥ 2 S S B = ∑ j = 1 k n j ∥ C j − X ˉ ∥ 2 \begin{array}{l} \mathrm{CH}(\mathrm{k})=\frac{S S B}{S S W}\frac{m-k}{k-1} \\ \\ S S W=\sum_{i=1}^{m}\left\|x_{i}-C_{p i}\right\|^{2} \\ S S B=\sum_{j=1}^{k} n_{j}\left\|C_{j}-\bar{X}\right\|^{2} \end{array} CH(k)=SSWSSBk1mkSSW=i=1mxiCpi2SSB=j=1knjCjXˉ2
SSW 的含义:

  1. Cpi 表示质心
  2. xi 表示某个样本
  3. SSW 值是计算每个样本点到质心的距离,并累加起来
  4. SSW 表示表示簇内的内聚程度,越小越好

SSB 的含义:

  1. Cj 表示质心,X 表示质心与质心之间的中心点,nj 表示样本的个数
  2. SSB 表示簇与簇之间的分离程度,SSB 越大越好
  • m 表示样本数量

  • k 表示质心个数

  从以上公式可知:当质心越少,CH越大;SSB越大,说明簇与簇越分散,CH越大;SSW越小,簇内越聚集,CH越大。

代码实现:

# 1、创建空列表
CH_list = []

# 2、设置中心点个数,查看CH的变化规律
for clu_num in range(2, 100):

    # 初始化迭代器一次的Kmeans
    my_kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=0)
    
    # 模型训练
    y_pre = my_kmeans.fit_predict(X)
    
    # # 将CH的每一次迭代结果添加到空列表内
    CH_list.append(calinski_harabasz_score(X, y_pre))

# 3、图像可视化
plt.figure(figsize=(20, 8), dpi=100)
plt.scatter(range(2, 100), CH_list)
plt.plot(range(2, 100), CH_list)
x_ticks = range(1, 100, 2)
plt.xticks(x_ticks)
plt.xlabel('中心点个数')
plt.ylabel('CH系数')
plt.grid()
plt.show()

在这里插入图片描述
从上图可得: 当中心点个数为4时,CH系数达到最大值,聚合效果最好

4.5肘方法

“肘” 方法通过 SSE 确定 n_clusters 的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值