ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

聚类算法笔记

2022-02-07 12:04:25  阅读:318  来源: 互联网

标签:clusters 样本 笔记 平方和 cluster 算法 聚类 质心


聚类算法-Kmeans

1.无监督学习与聚类算法

  • 有监督学习模型算法,模型需要的样本数据即需要有特征矩阵X,也需要有真实的标签y。
  • 无监督学习是指模型只需要使用特征矩阵X即可,不需要真实的标签y,聚类算法是无监督学习中的代表之一。
  • 聚类算法
    • 聚类算法其目的是将数据划分成有意义或有用的组(或簇)。这种划分可以基于我们的业务需求或建模需求来完成。也可以单纯地帮助我们探索数据自然结构和分布。比如在商业中,有大量的当前和潜在客户的信息,我们可以使用聚类将客户划分为若干组,一遍进一步分析和开展营销和活动

2.聚类算法和分类的区别

在这里插入图片描述
在这里插入图片描述

3.Kmeans算法原理阐述

  • 簇:Kmeans算法将一组N个样本的特征矩阵X划分为K个无交集的簇,直观上看来簇是一个又一个聚集一起的数据,在一个簇中的数据就认为是同一类,簇就是聚类的结果表现

  • 质心:簇中所有数据的均值u通常被称为这个簇的"质心"

    • 在一个二维平面中,一簇数据点的质心的横坐标就是这一簇数据点的横坐标的均值,质心的纵坐标就是这一簇数据点的纵坐标的均值。同理可以推广到高维空间
  • 质心的个数与聚类后的类别数一致

  • Kmeans算法中,簇的个数k是一个超参数,需要人为输入来确定。Kmeans的核心任务就是根据我们设好的k,找出k个最优的质心,并将离这些质心最近的数据分别分配到这些质心代表的簇中去,具体过程如下:

在这里插入图片描述

  • 当我们找到一个质心,在每次迭代中被分配到这个质心上的样本都是一致的,即每次新生成的簇都是一致的,所有的样本点都不会再从一个簇转移到另一个簇,质心就不会变化了

  • 如图所示【将数据分成4簇,白色x代表质心】

在这里插入图片描述

4.簇内误差表示

  • 被分在同一个簇中的数据是有相似性的,而不同簇中的数据是不同的,当聚类完毕之后,就要分别去研究每个簇中的样本都有什么性质,根据业务需求制定不同的策略

  • 聚类算法追求"簇内差异小,簇外差异大"【差异:由样本点到其所在簇的质心的距离来衡量】

  • 对于一个簇,所有样本点到质心的距离之和越小,就认为这个簇中的样本越相似,簇内差异就越小。样本点到质心的距离可由距离来衡量:

    • x:簇中的一个样本点
    • u:簇中的质心
    • n:每个样本点中的特征数目
    • i:组成点的每个特征

在这里插入图片描述

  • 簇内平方和

    • 采用欧几里得距离,则一个簇中所有样本点到质心的距离的平方和为簇内平方和。簇内平方和可以表示簇内差异的大小
  • 整体平方和

    • 将一个数据集中所有簇的簇内平方和相加,得到整体平方和(Total Cluster Sum of Square),又叫做total inertiaTotal Inertia越小,代表每个簇内样本越相似,聚类效果就越好

5.Kmeans有损失函数吗?

  • 有,Kmeans追求的是,求解能够让簇内平方和最小化的质心。在质心不断变化不断迭代的过程中,整体平方和是越来越小的,当整体平方和最小的时候,质心就不再发生变化了,即求解问题,变成了最优化问题

    • Kmeans中,在一个固定的簇数k下,最小化整体平方和来求解最佳质心,并基于质心的存在去进行聚类,并且,整体距离平方和的最小值可以使用梯度下降来求解,因此有人认为:簇内平方和或整体平方和是Kmeans的损失函数
  • 没有

    • 损失函数本质是用来衡量模型的拟合效果(损失越小,模拟的拟合效果越好),只有有求解参数需求的算法,才会有损失函数,Kmeans不求解参数,它的本质也不是在拟合数据,而是对数据进行一种探索。所以有些人认为:Kmeans不存在损失函数,整体平方和更像是Kmeans的模型评估指标,而非损失函数

6.kmeans对结果的预测

  • Kmeans算法通常不需要预测结果,因为该算法本质上是在对未知分类数据的探索,但是在某些情况下我们可以使用predict进行预测操作
  • 当数据太大的时候预测
    • 不必使用所有的数据寻找质心,少量的数据就可以帮助我们确定质心
    • 数据量非常大时,可以使用部分数据确认质心
    • 剩下的数据的聚类结果,使用predict来调用
  • 当我们不要求那么精确,或者我们的数据量实在太大,可以使用predict方法。如果数据量还行,直接使用fit后调用labels_查看聚类结果

7.API

  • class sklearn.cluster.KMeans(n_clusters=8,init='k-means++',n_init=10,max_iter=300,tol=0.0001,precompute_distances='auto',verbase=0,random_state=None,copy_x=True,n_jobs=None,algorthm='auto')
  • 参数
    • n_clusters:是KMeans中的k,表示模型要分几类,必填参数,默认为8类,通常的聚类结果会是一个小于8的结果,在聚类之前,不知道n_clusters是多少,即要对它进行探索
    • random_state:初始化质心的生成器
  • 属性
    • labels_:查看聚好的类别,每个样本所对应的类
    • cluster_centers_:查看质心坐标
    • intertia_:查看总距离平方和

8.Kmeans探索

  • 拿到一个数据集,我们希望能够通过绘图先观察一下这个数据集的数据分布,以此来为我们聚类时输入的n_clusters做一个参考,自己创建一个数据集make_blobs,自己创建的,有标签

    from sklearn.datasets import make_blobs
    import matplotlib.pyplot as plt
    #自己创建数据集,特征维度为2,质心为4,分4类,500个样本
    X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
    color=['red','pink','orange','gray']
    fig,ax1=plt.subplots(1)
    for i in range(4):
        ax1.scatter(
            X[y==i,0],
            X[y==i,1],
            marker='o',#点的形状
            s=8,#点的大小
            c=color[i]  #颜色
        )
        
    plt.show()
    

在这里插入图片描述

  • 基于这个分布,使用kmeans,假设数据有3簇

    #假设为3簇
    from sklearn.cluster import KMeans
    from sklearn.datasets import make_blobs
    #自己创建数据集,特征维度为2,质心为4,分4类,500个样本
    X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
    n_clusters = 3
    cluster = KMeans(n_clusters=n_clusters,random_state=0).fit(X)
    y_pred=cluster.labels_  #重要属性,查看聚好的类别,每个样本所对应的类
    centroid=cluster.cluster_centers_   #重要属性查看质心
    # array([[-8.0807047 , -3.50729701],
    #        [-1.54234022,  4.43517599],
    #        [-7.11207261, -8.09458846]])
    
    inertia=cluster.inertia_  #重要属性,查看总距离平方和
    # 1903.4503741659223
    
  • 画图,显示质心

    from sklearn.cluster import KMeans
    from sklearn.datasets import make_blobs
    #自己创建数据集,特征维度为2,质心为4,分4类,500个样本
    X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
    n_clusters = 3
    cluster = KMeans(n_clusters=n_clusters,random_state=0).fit(X)
    centroid=cluster.cluster_centers_   #重要属性查看质心
    color=['red','pink','orange','gray']
    fig,ax1=plt.subplots(1)
    for i in range(n_clusters):
        ax1.scatter(X[y_pred==i,0],X[y_pred==i,1],marker='o',s=8,c=color[i])
    ax1.scatter(centroid[:,0],centroid[:,1],marker='x',s=15,c='black')
    plt.show()
    

在这里插入图片描述

  • 使用部分数据

    from sklearn.cluster import KMeans
    from sklearn.datasets import make_blobs
    X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
    n_clusters=3
    cluster=KMeans(n_clusters=n_clusters,random_state=0).fit(X)
    y_pred=cluster.labels_  #重要属性,查看聚好的类别,每个样本所对应的类
    cluster_smallsub=KMeans(n_clusters=n_clusters,random_state=0).fit(X[:200])
    #使用模型对X进行分类预测
    y_pred_ = cluster_smallsub.predict(X)
    (y_pred==y_pred_).sum()
    

9.模型评价指标

  • 【面试题】如何衡量聚类算法的效果?

    • 聚类算法的结果不是某种标签输出,并且聚类的结果是不确定的,其优劣有业务的需求或者算法需求来决定,并没有正确答案
  • 簇内平方和(inertia)的缺点

    • 首先,它不是有界的,只知道inertia越小越好,是0最好。但是我们不知道,一个较小的inertia有没有达到模型的极限,能否继续提高

    • 计算太容易受到特征的数目的影响,数据维度很大时,interia的计算量会爆炸,不适合用来一次次评估模型

    • 会受到超参数k的影响,随着k越大,interia会越来越小,但不代表模型的效果越来越好

    • 使用inertia作为指标,会让聚类算法在一些细长簇,环形簇,或者不规则形状的聚类时,效果不佳:

在这里插入图片描述

9.1轮廓系数

  • 轮廓系数【轮廓系数是最常用的聚类算法的评价指标】

    • 在99%的情况下,是对没有真实标签的数据进行探索,即对不知道真正答案的数据进行聚类。这种聚类,是完全依赖于评价簇内的稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)来评估评估聚类的效果,轮廓系数是最常用的聚类算法的评价指标。它是对每个样本来定义的,能同时衡量:

      • 1.样本与其自身所在的簇中的其他样本的相似度a,等于样本与同一簇中所有其他点之间的平均距离
      • 2.样本与其他簇中的样本的相似度b,等于样本与下一个最近的簇中的所有点之间的平均距离,根据聚类要求"簇内差异小,簇外差异大",希望b永远大于a,并且越大越好
    • 单个轮廓系数计算为:

在这里插入图片描述

  • 轮廓系数范围是(-1,1):

    • 值越接近1表示样本与自己所在的簇中的样本很相似,并且与其它簇中的样本不相似,当样本与簇外的样本更相似时,轮廓系数为负
    • 当轮廓系数为0时,代表两个簇中的样本相似度一致,两个簇应该是一个簇。
    • 即,轮廓系数越接近于1越好,负数则表示聚类效果非常差
  • 如果一个簇中的大多数样本具有较高的轮廓系数,则簇会有较高的总轮廓系数,则整个数据集的平均轮廓系数越高,即聚类是合适的

  • 如果许多样本点具有低轮廓系数甚至负数,则聚类不合适,聚类的超参数k可能设定的太大或太小

  • 轮廓系数的计算

    • silhouette_score
      • from sklearn.metrics import silbouette_score,返回一个数据集中所有样本的轮廓系数的均值
    • silhouette_sample
      • from sklearn.metrics import silhouetet_samples,返回数据集中每个样本自己的轮廓系数
    from sklearn.cluster import KMeans
    from sklearn.datasets import make_blobs
    from sklearn.metrics import silhouette_score
    from sklearn.metrics import silhouette_samples
    X,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
    n_clusters=3
    cluster=KMeans(n_clusters=n_clusters,random_state=0).fit(X)
    y_pred=cluster.labels_ 
    silhouette_score(X,y_pred)  #0.5882004012129721
    silhouette_samples(X,y_pred)
    

标签:clusters,样本,笔记,平方和,cluster,算法,聚类,质心
来源: https://blog.csdn.net/m0_46926492/article/details/122806787

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有