k-means聚类算法详解

这篇具有很好参考价值的文章主要介绍了k-means聚类算法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

K-means聚类算法

零. 说在前面:

什么是特征向量?
用来描述样本点的一组数据,要和我们数学中的向量区别一下,本质来说就是个数组,数组中的每个元素代表从不同角度描述样本点的值。

K-means 是我们最常用的基于欧式距离的聚类算法,其认为两个目标的距离越近,相似度越大。
聚类就是对大量末知标注的数据集,按照数据内部存在的数据特征将数据集划分为多个不同的类别,使类别内的数据比较相似,类别之间的数据相似度比较大,属于无监督学习。
聚类算法的本质就是使得簇类样本尽可能相似,簇于簇间尽可能不同

和分类算法的区别:
分类算法是先有分类在来数据。
聚类算法是先有数据在来分类。

一. 算法步骤

1、首先确定一个k值,即我们希望将数据集经过聚类得到k个集合。

2、从数据集中随机选择k个数据点作为质心。

3、对数据集中每一个点,计算其与每一个质心的距离(如欧式距离),离哪个质心近,就划分到那个质心所属的集合。

4、把所有数据归好集合后,一共有k个集合。然后重新计算每个集合的质心。

5、如果新计算出来的质心和原来的质心之间的距离小于某一个设置的阈值(表示重新计算的质心的位置变化不大,趋于稳定,或者说收敛),我们可以认为聚类已经达到期望的结果,算法终止。

6、如果新质心和原质心距离变化很大,需要迭代3~5步骤。
k-means聚类,聚类,算法,kmeans

二. 算法优缺点

优点:

1、原理比较简单,实现也是很容易,收敛速度快。

2、当结果簇是密集的,而簇与簇之间区别明显时, 它的效果较好。

3、主要需要调参的参数仅仅是簇数k。

缺点:

1、K值需要预先给定,很多情况下K值的估计是非常困难的。

2、K-Means算法对初始选取的质心点是敏感的,不同的随机种子点得到的聚类结果完全不同 ,对结果影响很大。

3、采用迭代方法,可能只能得到局部的最优解,而无法得到全局的最优解。

三. 算法实现

算法使用sklearn实现:

step 1 创建数据集合:

首先我们创建一个由500个样本构成的数据集合,我们首先将自定义划分为四类。

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
#自己创建一个大小为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()

k-means聚类,聚类,算法,kmeans

setp 2 基于分布进行聚类

首先,我们要猜测一下,这个数据中有几簇?
先猜测为3簇

from sklearn.cluster import KMeans
n_clusters = 3#首先测试的超参数
cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
y_pred = cluster.labels_
centroid = cluster.cluster_centers_

其中n_clusters代表我们聚类的簇数,y_pred代表对应元素聚类的类别,centroid代表每个类别的中心点。
现在我们打印一下聚类结果:

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=18
                ,c="white")#循环画质心的位置
plt.show()

k-means聚类,聚类,算法,kmeans
发现效果还不错!
但是我们最开始生成的是四类数据,同样的我们以四类来进行聚类试试?
并且我们顺便打印一下聚类效果

from sklearn.cluster import KMeans
n_clusters = 4#首先测试的超参数
cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
y_pred = cluster.labels_
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=18
                ,c="white")#循环画质心的位置
plt.show()

k-means聚类,聚类,算法,kmeans

和我们的原始数据比较一下:
k-means聚类,聚类,算法,kmeans
效果不错!
但是这样问题就来了
我们如何去衡量一个K值得选取是否合适呢?

四. 聚类效果测评

被分在同一个簇中的数据是有相似性的,而不同簇中的数据是不同的,当聚类完毕之后,我们就要分别去研究每个簇中的样本都有什么样的性质。
根据聚类效果,我们追求“簇内差异小,簇外差异大”。而这个“差异“,由样本点到其所在簇的质心的距离来衡量。
对于一个簇来说,所有样本点到质心的距离之和越小,我们就认为这个簇中的样本越相似,簇内差异就越小。而距离的衡量方法有多种,令 x x x表示簇中的一个样本点, μ \mu μ表示该簇中的质心, n n n表示每个样本点中的特征数目, i i i表示组成点 x x x的每个特征,则该样本点到质心的距离可以由以下距离来度量:

欧几里得距离

d ( x , μ ) = ∑ i = 1 n ( x i − μ i ) 2 d(x,\mu)=\sqrt{\sum^{n}_{i=1}(x_i-\mu_i)^2} d(x,μ)=i=1n(xiμi)2

采用欧几里得距离,则一个簇中所有样本到质心的距离平方和为:

C S S = ∑ j = 0 m ∑ i = 0 n ( x i − μ i ) 2 CSS = \sum^{m}_{j=0}\sum^{n}_{i=0}(x_i-\mu_i)^2 CSS=j=0mi=0n(xiμi)2

T o t a l C S S = ∑ l = 1 k C S S l Total CSS = \sum^{k}_{l=1}CSS_l TotalCSS=l=1kCSSl

其中, m m m为一个簇中样本的个数, j j j是每个样本的编号。这个公式被称为簇内平方和(cluster Sum of Square),又叫做 i n e r t i a inertia inertia。而将一个数据集中的所有簇的簇内平方和相加,就得到了整体平方和(Total Cluster Sum of Square),又叫做 T o t a l i n e r t i a Total inertia Totalinertia T o t a l I n e r t i a Total Inertia TotalInertia越小,代表着每个簇内样本越相似,聚类的效果就越好。因此K-Means追求的是,求解能够让 I n e r t i a Inertia Inertia最小化的质心。实际上,在质心不断变化不断迭代的过程中,总体平方和是越来越小的。我们可以使用数学来证明,当整体平方和最小的时候,质心就不再发生变化了。如此,K-Means的求解过程,就变成了一个最优化问题。

代码实现

inertia = cluster.inertia_

对,就这么简单
然后我们探究一下刚刚数据中k大小与这个 T o t a l I n e r t i a TotalInertia TotalInertia的关系

x_i,y_i=[],[]
for i in range(1,11):
    n_clusters = int(i)#首先测试的超参数\
    cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
    inertia = cluster.inertia_
    x_i.append(i)
    y_i.append(inertia)
plt.plot(y_i)

k-means聚类,聚类,算法,kmeans
由图可知当k取值3到4左右的时候 T o t a l I n e r t i a TotalInertia TotalInertia是比较小的。

并且我们可以发现k值越大, T o t a l I n e r t i a TotalInertia TotalInertia的值越小,也就是模型越好

而这样说明, T o t a l I n e r t i a TotalInertia TotalInertia最为评价K值选取的参数使用是不好的,不可能将样本分成任意多的簇

所以使用Inertia用来评估聚类的效果可以,但没必要因为这个指标的缺点太大。

并且使用Inertia作为评估指标,会让聚类算法在一些细长簇,环形簇,或者不规则形状的流形时表现不佳:
k-means聚类,聚类,算法,kmeans
所以研究者们往往会采用其他参数来对聚类效果进行衡量

五. 算法评估PLUS

一般我们使用聚类算法进行评估时往往有两种数据情况

1.当标签已知的时候

2.当标签未知的时候

1.当标签已知的时候(不做讨论)k-means聚类,聚类,算法,kmeans

2.当标签未知的时候

当标签未知的时候我们往往会采用轮廓系数进行衡量。

在99%的情况下,我们是对没有真实标签的数据进行探索,也就是对不知道真正答案的数据进行聚类。这样的聚类,是完全依赖于评价**簇内的稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)**来评估聚类的效果。

其中轮廓系数是最常用的聚类算法的评价指标

它是对每个样本来定义的:

1)样本与其自身所在的簇中的其他样本的相似度a,等于样本与同一簇中所有其他点之间的平均距离

2)样本与其他簇中的样本的相似度b,等于样本与下一个最近的簇中的所有点之间的平均距离

根据聚类的要求”簇内差异小,簇外差异大“,我们希望b永远大于a,并且大得越多越好。
轮廓系数计算方法如下:

s = b − a m a x ( a , b ) s = \frac{b-a}{max(a,b)} s=max(a,b)ba

由公式可知轮廓系数范围是(-1,1)。

其中值越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似。

当样本点与簇外的样本更相似的时候,轮廓系数就为负。

当轮廓系数为0时,则代表两个簇中的样本相似度一致,两个簇本应该是一个簇。

可以总结为轮廓系数越接近于1越好,负数则表示聚类效果非常差。越接近1越好;越接近-1越不好。

如果一个簇中的大多数样本具有比较高的轮廓系数,则簇会有较高的总轮廓系数,则整个数据集的平均轮廓系数越高,则聚类是合适的。如果许多样本点具有低轮廓系数甚至负值,则聚类是不合适的,聚类的超参数K可能设定得太大或者太小。

代码如下:

from sklearn.metrics import silhouette_score
x_i,y_i=[],[]
for n_clusters in range(2,11):
    clusterer = KMeans(n_clusters=n_clusters, random_state=10)
    cluster_labels = clusterer.fit_predict(X)
    silhouette_avg = silhouette_score(X, cluster_labels)
    x_i.append(n_clusters)
    y_i.append(silhouette_avg)
    print("For n_clusters =", n_clusters,
          "The average silhouette_score is :", silhouette_avg)
plt.plot(x_i, y_i)

结果如图:
k-means聚类,聚类,算法,kmeans
可见我们在k=4左右效果最好,我们数据集生成也是4个类别。可见使用轮廓系数作为k值选取的参考非常合理。

轮廓系数有很多优点,它在有限空间中取值,使得我们对模型的聚类效果有一个“参考”。

并且,轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好。但它在每个簇的分割比较清洗时表现最好。但轮廓系数也有缺陷,它在凸型的类上表现会虚高,比如基于密度进行的聚类,或通过DBSCAN获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数。

除了轮廓系数是最常用的,我们还有卡林斯基-哈拉巴斯指数(Calinski-Harabaz Index,简称CHI,也被称为方差比标准),戴维斯-布尔丁指数(Davies-Bouldin)以及权变矩阵(Contingency Matrix)可以使用。

六. Referance

[1]Ahmed M, Seraj R, Islam S M S. The k-means algorithm: A comprehensive survey and performance evaluation[J]. Electronics, 2020, 9(8): 1295.
[2]Hartigan J A, Wong M A. Algorithm AS 136: A k-means clustering algorithm[J]. Journal of the royal statistical society. series c (applied statistics), 1979, 28(1): 100-108.
[3]Likas A, Vlassis N, Verbeek J J. The global k-means clustering algorithm[J]. Pattern recognition, 2003, 36(2): 451-461.
[4]Krishna K, Murty M N. Genetic K-means algorithm[J]. IEEE Transactions on Systems, Man, and Cybernetics, Part B (Cybernetics), 1999, 29(3): 433-439.文章来源地址https://www.toymoban.com/news/detail-574629.html

到了这里,关于k-means聚类算法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习之K-means聚类算法

    目录 K-means聚类算法 算法流程 优点 缺点 随机点聚类 人脸聚类 旋转物体聚类 K-means聚类算法是一种无监督的学习方法,通过对样本数据进行分组来发现数据内在的结构。K-means的基本思想是将n个实例分成k个簇,使得同一簇内数据相似度高而不同簇之间数据相似度低。 K-means的

    2024年02月11日
    浏览(42)
  • 【详解算法流程+程序】DBSCAN基于密度的聚类算法+源码-用K-means和DBSCAN算法对银行数据进行聚类并完成用户画像数据分析课设源码资料包

    DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。 与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇, 并可在噪声的空间数据库中发现任意形状的聚类。         选

    2024年04月11日
    浏览(42)
  • K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比

      目录  一、概述 二、经典K-means算法 三、K-means++算法 四、ISODATA算法 六、数据集测试       在本篇文章中将对四种聚类算法(K-means,K-means++,ISODATA和Kernel K-means)进行详细介绍,并利用数据集来真实地反映这四种算法之间的区别。       首先需要明确的是上述四种算法都属

    2024年01月23日
    浏览(46)
  • K-means聚类算法及Python代码实现

    K-means聚类算法(事先数据并没有类别之分!所有的数据都是一样的) 1、概述 K-means算法是集简单和经典于一身的 基于距离的聚类算法 采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。 该算法认为类簇是由距离靠近的对象组成的,因此把得到

    2023年04月24日
    浏览(45)
  • 传统机器学习(三)聚类算法K-means(一)

    K-Means算法是无监督的聚类算法,它实现起来比较简单,聚类效果也不错,因此应用很广泛。K-Means基于欧式距离认为两个目标距离越近,相似度越大。 1.1.1 算法流程 (1)图a表达了初始的数据集, 假设k=2; (2)在图b中,随机选择两个k类的对应的类别质心,即图中的红色质

    2023年04月15日
    浏览(41)
  • K-means聚类算法(附Python实现代码)

    本文的代码与数据地址已上传至github:https://github.com/helloWorldchn/MachineLearning 1、基于划分的聚类 划分算法的思想是,将给定待挖掘数据集中的数据对象划分成K组(k≤N,N代表数据集中对象数目),每一组表示一个聚类的簇。并且要满足任何一个数据对象仅可以属于一个聚类,

    2024年02月07日
    浏览(43)
  • K-Means(K-均值)聚类算法理论和实战

    目录 K-Means 算法 K-Means 术语 K 值如何确定 K-Means 场景 美国总统大选摇争取摆选民 电商平台用户分层 给亚洲球队做聚类 ​编辑 其他场景 K-Means 工作流程 K-Means 开发流程 K-Means的底层代码实现 K-Means 的评价标准 对于 n 个样本点来说,根据距离公式(如欧式距离)去计 算它们的

    2024年02月11日
    浏览(36)
  • 【机器学习】K-means聚类算法:原理、应用与优化

    一、引言 1、简述聚类分析的重要性及其在机器学习中的应用   聚类分析,作为机器学习领域中的一种无监督学习方法,在数据探索与知识发现过程中扮演着举足轻重的角色。它能够在没有先验知识或标签信息的情况下,通过挖掘数据中的内在结构和规律,将数据对象自动

    2024年04月13日
    浏览(46)
  • K-means聚类算法原理、步骤、评价指标和实现

    1、聚类 聚类与分类不同,聚类分析分通过分析大量含有一定规律但杂乱数据,得到数据间内在的逻辑,将杂乱的数据按照所得的数据规律划分成不同的种类。K-measn、DBSCAN和层次是当前广泛使用的三种聚类方法。以下对三种方法进行分析,选择适合的聚类方法。 方法 K-means

    2024年02月07日
    浏览(56)
  • 【聚类算法】带你轻松搞懂K-means聚类(含代码以及详细解释)

    聚类是一个将数据集中 在某些方面相似的数据成员 进行分类组织的过程,聚类就是一种发现这种内在结构的技术,聚类技术经常被称为 无监督学习 。 k均值聚类是最著名的划分聚类算法,由于简洁和效率使得他成为所有聚类算法中最广泛使用的。给定一个数据点集合和需要

    2024年02月01日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包