《机器学习》—— K-means 聚类算法

一、什么是K-means 聚类算法?

  • K-Means 是 Python 中非常流行的一个聚类算法,它属于无监督学习算法的一种。在 scikit-learn(一个广泛使用的机器学习库)中,KMeans 类用于执行 K-均值聚类。K-均值聚类是一种将数据点分成 K 个簇的算法,其中每个簇由簇内数据点的均值(即“质心”)定义。
  • 基本原理
    • 初始化:首先,算法随机选择 K 个点作为初始的簇质心(如动图中的X点)。
    • 分配:然后,算法将每个数据点分配到最近的簇质心,形成 K 个簇。
      • 满足条件:所有的数据点到质心的距离(使用欧氏距离)之和是最小的
    • 更新:接着,算法重新计算每个簇的质心,即计算簇内所有点的均值
    • 迭代:重复分配和更新步骤,直到簇质心的位置不再发生显著变化,或者达到预设的迭代次数。
  • 动图解释
    在这里插入图片描述

二、聚类效果评价方式——轮廓系数

  • metrics.silhouette_score 是 Scikit-learn(一个流行的 Python 机器学习库)中用于评估聚类效果好坏的一个指标。它衡量了聚类内样本的相似度与聚类间样本的不相似度,其值范围从 -1 到 1。
  • 原理:
    • Silhouette Score(轮廓系数)结合了凝聚度分离度两种因素。对于单个样本,其轮廓系数定义为:
      在这里插入图片描述
      • a 是样本与同一聚类中其他样本的平均距离(即样本的凝聚度或内聚度)
      • b 是样本与最近聚类中所有样本的平均距离(即样本的分离度
  • 整个数据集的轮廓系数是所有样本轮廓系数的平均值
  • 如何判断聚类效果好坏:
    • 值接近 1 :表示样本远离其他聚类,且聚类内部紧密。这是聚类效果好的标志。
    • 值接近 0 :表示样本位于两个聚类之间
    • 值为负 :表示样本被分配到了错误的聚类中,因为该样本与其聚类内的平均距离大于它与最近聚类中样本的平均距离。

三、示例:代码实现

  • python中的 class sklearn.cluster.KMeans 方法用于实现K-means 聚类算法

  • 它有以下一些参数:

    class sklearn.cluster.KMeans(
    	n_clusters=8, init=’k-means++, n_init=10,
     	max_iter=300, tol=0.0001, precompute_distances=’auto’, 
     	verbose=0, random_state=None, copy_x=True, 
     	n_jobs=None, algorithm=’auto’)
    
  • 其中最重要的便是 n_clusters :

    • n_clusters: 类中心的个数,就是要聚成几类。(默认是8个)
  • 数据集介绍

    • 下面是一份含有20个不同的酒,且每瓶酒都有四个相同属性的数据
    • 通过对四个属性的模型训练,将这些酒进行聚类
    • 数据的第一行为列名,第一列为酒的名字
      在这里插入图片描述
  • 1、读取数据并获取训练数据

    import pandas as pd
    # 注意这里读取文本数据时,需要指定,数据之间是以什么进行分隔的
    data = pd.read_table('data.txt', sep=' ', encoding='utf8', engine='python')
    # 通过传入变量(列名)获取训练数据
    x = data[['calories', 'sodium', 'alcohol', 'cost']]
    
  • 2、循环找到合适的K值(簇数)

    • 循环不同的K值,通过比较轮廓系数的大小确定出最优K值
    from sklearn.cluster import KMeans
    from sklearn import metrics
    
    scores = []
    for k in range(2, 10):  # 寻找合适的k值(簇数)
        labels = KMeans(n_clusters=k).fit(x).labels_  # .labels_ 获取训练后各样本对应的分类标签
        score = metrics.silhouette_score(x, labels)  # 轮廓系数
        scores.append(score)  # 将每次循环得到的轮廓系数存放在scores列表中
    print(scores)
    
    import numpy as np
    
    best_k = range(2, 10)[np.argmax(scores)]  # 找到scores中最大的值对应的K值
    print("最优k值为:{}".format(best_k))
    
    • 结果:
      在这里插入图片描述
  • 3、可视化不同K值下,轮廓系数的大小

    import matplotlib.pyplot as plt
    
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
    # 为了坐标轴负号正常显示。matplotlib默认不支持中文,设置中文字体后,负号会显示异常。需要手动将坐标轴负号设为False才能正常显示负号。
    plt.rcParams['axes.unicode_minus'] = False
    
    plt.plot(list(range(2, 10)), scores)
    plt.xlabel('K值(簇数)')
    plt.ylabel('轮廓系数')
    plt.show()
    
    • 结果:在这里插入图片描述
  • 4、在最优K值下训练模型,并计算出轮廓系数

    from sklearn.cluster import KMeans
    from sklearn import metrics
    
    km = KMeans(n_clusters=2).fit(x)
    data['cluster'] = km.labels_   # 为原数据增加一个新列用于存放训练得出的每个样本的类标签
    score = metrics.silhouette_score(x, data.cluster) # 计算轮廓系数
    print(score)
    
    • 结果:
      在这里插入图片描述
    • 可以看出K-means 聚类算法的效果并不是太好,存在各种因素的影响,有待我们进一步的学习与思考

四、聚类算法的优缺点

  • 优点
    • 无监督学习,不需要事先标记的数据。
    • 能够发现数据中的隐藏模式和结构。
    • 适用于多种数据类型和领域。
  • 缺点
    • 需要选择合适的聚类算法和参数,这往往依赖于数据的特性和问题的需求。
    • 聚类结果可能受到初始条件(如K-means的初始质心选择)的影响。
    • 对于复杂形状和密度的簇,可能需要更复杂的聚类算法或参数调整。
  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值