【机器学习】K-Means算法及多种优化改进算法,聚类模型评估,附带案例代码

一、聚类分析

聚类分析是根据在数据中发现的描述对象(数据)及其关系的信息,将数据划分成有意义或有用的组(簇)。其目标是:

  • 组内的对象相互之间是相似的(相关的),而不同组中的对象是不同的(不相关的);
  • 组内的相似性(同质性)越大,组间差别越大,聚类就越好。

聚类可以看作是一种分类,它用簇标号创建对象的标记。然而,只能从数据中导出这些标记,它与分类(例如分类决策树等)不同,分类是监督分类,即使用由类标号(标签数据)已知的对象开发的模型,对新的、无标记的对象赋予类标号。因此,聚类分析也称为非监督分类

二、不同的聚类类型

不同类型的聚类主要包括:

  1. 层次的(嵌套的)与划分的(非嵌套的)
  • 划分聚类:简单地将数据对象集划分成不重叠的子集(簇),是的每个数据对象恰在一个子集中

  • 层次聚类:允许簇具有子簇;层次聚类是嵌套簇的集合,组成一棵树

  1. 互斥的、重叠的与模糊的
  • 互斥的:每个对象都指派到单个簇

  • 重叠的:一个对象同时属于多个簇

  • 模糊的:每个对象以一个0(绝对不属于)和1(绝对属于)之间的值作为属于某个簇的权重(概率)

  1. 完全的与部分的
  • 完全的:将每个对象指派到一个簇中

  • 部分的:数据集中有些对象可能是噪声、离群点或“特定聚类任务不感兴趣的点”,这些对象可能不属于明确定义的簇。

三、不同的簇类型

在这里插入图片描述

  1. 明显分离的
  • 簇是对象的集合,其中每个对象到同簇中的每个对象的距离比到不同簇中任意对象的距离都近(或更相似);
  • 如图(1),不同组中的任意两点之间的距离都大于组内任意两点之间的距离
  • 明显分离的簇可以是任意形状的。
  1. 基于原型的
  • 簇是对象的集合,其中每个对象到定义该 簇的原型的距离比到其他簇的原型的距离更近(或更相似);
  • 对于许多数据类型,原型可以视为最靠近中心的点,也称为“基于中心的簇”,如图(2);
  • 这种簇趋向于呈球形状。

簇的原型:

  • 指的是质心,即簇中所有点的平均值;
  • 当数据具有分类属性时,质心没有意义,簇的原型就是中心点,即簇中最有代表性的点。
  1. 基于图的
  • 如果数据用图来表示,其中结点为对象,而边代表对象之间的联系,则簇可以定义为连通分支,即互相连通但不与组外对象连通的对象组;
  • 基于图的簇的一个重要例子是 基于邻近的簇 ,当两个对象的距离在指定的范围之内,这两个对象就是相连的;也就是说,每个对象到该簇某个对象的距离比到不同簇中任意点的距离更近;
  • 如图(3),两个球形之间有数据连接,基于邻近的簇,就将其看作是同一个簇
  • 这种簇,当数据具有噪声时可能出现问题,比如,图中连接两个球形簇的数据点是噪声点,此时就会由于噪声出现问题。
  1. 基于密度的
  • 簇是对象的稠密区域,被低密度区域环绕;
  • 如图(4),数字10,上的数据明显比其他地方稠密,低密度的区域被视为噪声点
  • 这种簇可能会因为数据密度的不同出现问题。
  1. 共同性质的(概念簇)
  • 如图(5),由两个环组成,聚类算法需要通过非常具体的簇概念来成功检测这些簇,发现这样的簇的过程就称为概念簇。
  • 过于复杂的簇概念将会设计模式识别领域

以上便是聚类分析的一点基础知识,下面我们首先介绍简单、易于理解的 K-means (K均值),然后在此基础上进行改进来弥补K均值的一些缺点。

四、K-means 算法

K均值是基于原型的、划分的聚类技术,它试图发现用户指定个数 K K K 的簇;K均值 用质心定义原型,其中质心是一组点的均值。K均值 是一种使用广泛的最基础的聚类算法,作为学习聚类算法的开始非常适合。

1、 K均值 算法的一般步骤
  • 选择 K K K 个初始质心,其中 K K K 是用户指定的参数,即所期望的簇的个数;
  • 每个点指派到最近的质心,而指派到一个质心的点集为一个簇;
  • 然后,根据指派到簇的点,重新计算每个簇的质心
  • 重复指派和更新操作,直到簇不发生变化,或等价地,直到质心不在发生变化

在这里插入图片描述

图中红色的 “*” 表示质心,属于同一簇的对象具有同样的颜色;

  • 第1步,初始化质心,将点指派到初始最近的质心,这些质心都在点的较大组群中
  • 第2步,把点指派到最近的质心后,更新质心(质心向左右下的点群),再次将点指派到更新后的质心
  • 第3步,更新质心,将点指派到更新后的最近的质心
  • 第4步,更新质心,再次指派点到最近的质心,此后不再发生变化,算法停止

由于图是手动画的,所以每步的图有些差别,不过不影响理解

下面是 K均值 算法涉及的几个问题:

  • 选择初始质心

\quad\quad 当质心随机初始化时,K均值 的不同运行将产生不同的总 S S E SSE SSE,选择适当的初始化质心是基本 K K K 均值过程的关键步骤,常见的方法是随机地选择初始化质心,但是簇的质量常常很差。

在这里插入图片描述

不好的初始质心带来的效果:

  • 尽管所有的初始质心都在自然簇中,结果也找到了最小 S S E SSE SSE 聚类;
  • 但是仅得到了一个次最优聚类,具有较高的平方误差。

在这里插入图片描述

以上数据由两个簇组成,其中簇对(上下)中的簇更靠近,而离另一对中的簇较远
随机初始化的局限:

  • 处理选取初始质心问题的一种常用技术就是:多次运行,每次使用一组不同的随机初始质心,然后选取具有最小 S S E SSE SSE 的簇集;
  • 该策略虽然简单,但是效果可能不好,这取决于数据集和寻找的簇的个数;
  • 如果我们对每个簇对用两个初始质心,则即使两个质心在同一个簇中,质心也会自己重新分布,从而找到“真正的”簇;
  • 如果一个簇只用一个初始质心,而另一个使用三个质心,则两个真正的簇将合并,而一个真正的簇将分裂
  • 指派点到最近的质心

\quad\quad 为了将点指派到最近的质心,我们需要 邻近性度量 来量化所考虑的数据的“最近”的概念,通常,对于欧氏空间中的点使用欧几里得距离,对于文档数据使用余弦相似性。

  • 质心和目标函数

\quad\quad 由于质心可能随数据邻近性度量和聚类目标不同而改变,因此在指派点到最近的质心后需要重新计算每个簇的质心。

i i i 个质心(均值)由如下公式定义:
c i = 1 m i ∑ x ∈ C i x c_i = \frac{1}{m_i}\sum_{x \in C_i}x ci=mi1xCix
其中, C i C_i Ci 是第 i i i 个簇, x x x C i C_i Ci 中的点, c i c_i ci 是第 i i i 个簇的均值, m i m_i mi 是第 i i i 个簇中的对象的个数

\quad\quad 聚类的目标通常用一个目标函数表示,该函数依赖于点之间,或点到簇的质心的邻近性;例如:最小化每个点到最近质心的距离的平方。

考虑邻近性度量为欧几里得距离的数据,使用 误差的平方和(SSE) 作为度量聚类质量的目标函数,SSE称为散布。

  • 计算每个数据点的误差,即它到最近质心的欧几里得距离,然后计算误差的平方和,可用数学表达式表示为:
    S S E = ∑ i = 1 K ∑ x i ∈ C i d i s t ( c i , x ) 2 SSE=\sum_{i=1}^K\sum_{x_i \in C_i}dist(c_i, x)^2 SSE=i=1KxiCidist(ci,x)2

其中, d i s t dist dist 是欧几里得空间中两个对象之间的标准欧几里得距离( L 2 L_2 L2), K K K 为簇的个数

K均值 质心的数学推导:

对于上面的目标函数,需要考虑如何最好地更新簇质心,使得簇 S S E SSE SSE 最小化。我们可以对第 k k k 个质心 c k c_k ck 求解。

最小化目标函数,即对 S S E SSE SSE 求导,令导数等于0,并求解 c k c_k ck:

∂ ∂ c k S S E = ∂ ∂ c k ∑ i = 1 K ∑ x i ∈ C i ( c i − x ) 2 \frac{\partial}{\partial c_k} SSE = \frac{\partial}{\partial c_k} \sum_{i=1}^K\sum_{x_i \in C_i}(c_i- x)^2 ckSSE=cki=1KxiCi(cix)2
= ∑ x ∈ C k 2 ( c k − x k ) = 0 = \sum_{x \in C_k}2(c_k- x_k) = 0 =xCk2(ckxk)=0
∑ x ∈ C k 2 ( c k − x k ) = 0 → m k c k = ∑ x ∈ C k x k → c k = 1 m k ∑ x ∈ C k x k \sum_{x \in C_k}2(c_k- x_k) = 0 \rightarrow m_kc_k = \sum_{x \in C_k} x_k \rightarrow c_k = \frac{1}{m_k}\sum_{x \in C_k} x_k xCk2(ckxk)=0mkck=xCkxkck=mk1xCkxk

由上公式可知,簇的最小化 S S E SSE SSE 的最佳质心是簇中个点的均值

2、 K-means 算法思考

\quad\quad 根据以上三个问题的讨论可知,随机选择初始质心存在的问题即使重复运行多次也不能克服,因此常常使用其他技术进行初始化:

  • 一种有效的方法是取一个样本,并使用层次聚类技术对它聚类,从层次聚类中提取 K K K 个簇,并用这些簇的质心作为初始质心;
  • 另一种选择初始化质心的方法是随机地选择第一个点,或取所有点的质心作为第一个点,然后对于每个后继初始质心,选择离已经选取过的初始质心最远的点(使用这种方法既可以确保质心是随机的,而且是散开的)。但是这种方法可能选中离群点,并且求离当前初始质心集最远的点开销也非常大。

此外,还可以使用对初始化问题不太敏感的 K均值 的变种:二分 K K K 均值

3、 K-means 总结

(1)K-means算法在迭代的过程中使用所有点的均值作为新的质点(中心点),如果簇中存在异常点,将导致均值偏差比较严重

  • 例如一个簇中有 { 2 , 4 , 6 , 8 , 100 } \{2,4,6,8,100\} {2,4,6,8,100}五个数据,那么新的质心为24,显然这个质心离绝大多数点都比较远,在当前情况下,使用中位数6可能比使用均值的想法更好,使用中位数的聚类方法叫做K-Mediods聚类(K中值聚类)

(2) K-means 算法是初始质心敏感的,选择不同的初始质心可能导致不同的簇划分规则

  • 为了避免这种敏感性导致的最终结果异常性,可以采用初始化多套初始质心构造不同的分类规则,然后选择最优的构造规则

(3) K-means算法缺点:

  • K值是用户给定的,在进行数据处理前,K值是未知的,不同的K值得到的结果也不一样;
  • 对初始簇质心是敏感的
  • 不适合发现非凸形状的簇或者大小差别较大的簇
  • 特殊值(离群值)对模型的影响比较大

(4)K-means算法优点:

  • 理解容易,聚类效果不错
  • 处理大数据集的时候,该算法可以保证较好的伸缩性和高效率
  • 当簇近似高斯分布的时候,效果非常不错
4、K-means算法案例
  • 案例1: 手写实现 K-means 算法

本案例按照算法流程,使用欧氏距离实现 K-means 算法,并通过文本数据进行训练,具体内容可见代码注释。

testSet.txt 文本文件数据如下:(每行表示二维空间的一个点,便于画图)

1.658985	4.285136
-3.453687	3.424321
4.838138	-1.151539
-5.379713	-3.362104
0.972564	2.924086
-3.567919	1.531611
0.450614	-3.302219

在这里插入图片描述

代码可见 Github 目录下:01_K-means算法实现.py

  • 案例2: K-means 算法应用1

本案例使用 sklearn 库中自带的 KMeans 模型对模拟产生的数据进行聚类,API如下:

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 : int要形成的簇数以及要生成的质心数,默认为8
init:int初始化方法,默认为’k-means ++’ ;‘random’:从初始质心的数据中随机选择k个观测值(行);或者自定义的ndarray
max_iter:int单次运行的k-means算法的最大迭代次数,默认为300
precompute_distances:{‘auto’,True,False}预计算距离(更快但需要更多内存)
random_state确定质心初始化的随机数生成种子

代码可见:02_K-means算法应用1.py

  • 案例3:K-means 算法应用2

本案例实现不同数据分布对 KMeans 聚类的影响,主要有旋转后的数据、簇具有不同方差的数据、簇具有不同数目的数据

在这里插入图片描述

  • 可见 K-means 对明显分离的球状数据的效果很好;
  • 对有重叠的数据在重叠处效果不是很好;
  • 对于较少的数据,对聚类会产生不好影响,相当于噪声对聚类的影响

代码可见:03_K-means聚类应用2.py

至此,相信大家对 K-means 聚类已经有了很好的理解,下面就是要针对K-means 算法的一些缺陷进行改进,

五、二分 K均值

为了解决 K-Means 算法对 初始簇心比较敏感 的问题,二分K-Means 算法是一种弱化初始质心的一种算法,二分 K均值 不太受初始化问题的影响。

1、 二分K-Means的具体思路步骤如下:
  • 将所有样本数据作为一个簇放到一个队列中
  • 从队列中选择一个簇进行 K-means 算法划分,划分为两个子簇,并将子簇添加到队列中
  • 循环迭代第二步操作,直到中止条件达到(聚簇数量、最小平方误差、迭代次数等)
  • 队列中的簇就是最终的分类簇集合
2、从队列中选择划分聚簇的规则一般有两种方式:
  • 对所有簇计算误差和 SSE ( SSE 也可以认为是距离函数的一种变种),选择 SSE 最大的聚簇 进行划分操作(优选这种策略)
  • 选择 样本数据量最多的簇 进行划分操作

在这里插入图片描述

  • 迭代1找到两个簇对;
  • 迭代2分裂了最右边的簇对;
  • 迭代3分裂了最左边的簇对

执行多次二分试验,并选取具有最小 SSE 的试验结果,且每步只有两个质心

3、不同的簇类型带来的影响

\quad\quad 对于发现不同的簇类型,二分K-MeansK均值 都具有一些局限性。当簇具有非球形形状或具有不同尺寸或密度时,二分K-Means 很难检测到“自然的”簇。我们还是通过图来理解:

在这里插入图片描述

  • 上图,K均值 不能发现那三个自然簇,因为其中一个簇比其他两个大得多,因此较大的簇被分开,而一个较小的簇与较大的簇的一部分合并到一起;
  • 中图,两个较小的簇比较大的簇稠密的多;
  • 下图,两个自然簇不是球形形状

这三种情况的问题在于 K均值 的目标函数与我们试图发现的簇的类型不匹配,因为 K均值 目标函数是最小化等尺寸和等密度的球形簇,或者明显分离的簇。

4、 二分K-Means算法实现:

二分K-均值算法的伪代码:

将所有点看成一个簇
当簇数目小于k时
	对于每一个簇
		计算总误差
		在给定的簇上面进行K-均值聚类(k=2)
		计算将该簇一分为二之后的总误差
	选择使得误差最小的那个簇进行划分操作

在这里插入图片描述

具体分析可见代码注释,仔细研读代码。

代码可见:04_二分K-means算法实现.py

六、K-Means++K-Means|| 算法

\quad\quad 为了解决 K-Means 算法对初始簇心比较敏感的问题,K-Means++ 算法和 K-Means 算法的区别主要在于初始的K个中心点的选择方面,K-Means 算法使用随机给定的方式,K-Means++算法采用下列步骤给定K个初始质点:

  • 从数据集中 任选一个节点 作为第一个聚类中心;
  • 对数据集中的每个点 x x x ,计算 x x x 到所有已有聚类中心点的距离和 D ( X ) D(X) D(X),基于 D ( X ) D(X) D(X) 采用线性概率选择出下一个聚类中心点(距离较远的一个点成为新增的一个聚类中心点);
  • 重复步骤2直到找到 k k k 个聚类中心点。

缺点:

  • 由于聚类中心点选择过程中的 内在有序性,在扩展方面存在着性能方面的问题(第 k k k 个聚类中心点的选择依赖前 k − 1 k-1 k1 个聚类中心点的值)
  • 容易受噪声点影响

\quad\quad 为了解决 K-Means++ 算法性能缺陷,产生了 K-Means|| 算法,主要思想是改变每次遍历时候的取样规则,并非按照 K-Means++ 算法每次遍历只获取一个样本,而是每次获取 K 个样本,重复该取样操作 O ( l o g n ) O(logn) O(logn) 次,然后再将这些抽样出来的样本聚类出 K K K 个点,最后使用这 K K K 个点作为 K-Means 算法的初始聚簇中心点。

七、Canopy 算法

Canopy 算法属于一种“粗”聚类算法,执行速度较快,但精度较低,算法执行步骤如下:

  • 给定样本列表 L = x 1 , x 2 , . . . , x m L=x_1,x_2,...,x_m L=x1,x2,...,xm 以及先验值 r 1 r_1 r1 r 2 ( r 1 > r 2 ) r_2(r_1>r_2) r2(r1>r2)
  • 从列表L中获取一个节点P,计算P到所有聚簇中心点的距离(如果不存在聚簇中心,那么此时点P形成一个新的聚簇),并选择出最小距离 D ( P , a j ) D(P,a_j) D(P,aj)
  • 如果距离 D &lt; r 1 D &lt; r_1 D<r1,表示该节点属于该聚簇,添加到该聚簇列表中;
  • 如果距离 D &lt; r 2 D &lt; r_2 D<r2,表示该节点不仅仅属于该聚簇,还表示和当前聚簇中心点非常近,所以将该聚簇的中心点设置为该簇中所有样本的中心点,并将P从列表L中删除;
  • 如果距离 D &gt; r 1 D &gt; r_1 D>r1,那么节点P形成一个新的聚簇;
  • 直到列表L中的元素数据不再有变化或者元素数量为0的时候,结束循环操作。

Canopy 算法过程图形说明:

在这里插入图片描述

在这里插入图片描述

Canopy 算法得到的最终结果的值,聚簇之间是可能存在重叠的,但是不会存在某个对象不属于任何聚簇的情况

由于 K-Means 算法存在初始聚簇中心点敏感的问题,常用使用 Canopy + KMeans 算法混合形式进行模型构建:

  • 先使用 canopy 算法进行“粗”聚类得到 K K K 个聚类中心点
  • K-Means 算法使用 Canopy 算法得到的 K K K 个聚类中心点作为初始中心点,进行“细”聚类

优点:

  • 执行速度快(先进行了一次聚簇中心点选择的预处理)
  • 不需要给定 K K K 值,应用场景多
  • 能够缓解 K-Means 算法对于初始聚类中心点敏感的问题

八、Mini Batch K-Means 算法

\quad\quad Mini Batch K-Means 算法是 K-Means 算法的一种优化变种,采用 小规模的数据子集 (每次训练使用的数据集是在训练算法的时候随机抽取的数据子集) 减少计算时间,同时试图优化目标函数;Mini Batch K-Means 算法可以减少 K-Means 算法的收敛时间,而且产生的结果效果只是略差于标准K-Means 算法。

算法步骤如下:

  • 首先抽取部分数据集,使用 K-Means 算法构建出 K K K 个聚簇点的模型;
  • 继续抽取训练数据集中的部分数据集样本数据,并将其添加到模型中,分配给距离最近的聚簇中心点更新聚簇的中心点值;
  • 循环迭代第二步和第三步操作,直到中心点稳定或者达到迭代次数,停止计算操作。

案例:K-MeansMini Batch K-Means 算法比较

\quad\quad 本案例基于scikit 包中的创建模拟数据的 API 创建聚类数据,使用 K-means 算法和 Mini Batch K-Means 算法对数据进行分类操作,比较这两种算法的聚类效果以及聚类的消耗时间长度。

sklearn.cluster.MiniBatchKMeans(n_clusters = 8, init ='k-means ++', max_iter = 100,
	batch_size = 100, verbose = 0, compute_labels = True, random_state = None,
	tol = 0.0, max_no_improvement = 10, init_size = None,
	n_init = 3, reassignment_ratio = 0.01)

常用参数说明:

参数描述
n_clusters : int,optional,默认值:8要形成的簇数以及要生成的质心数
init : {‘k-means ++’,'random’或ndarray},默认:‘k-means ++’初始化方法,‘k-means ++’:以智能方式为k均值聚类选择初始聚类中心,以加速收敛;‘random’:从初始质心的数据中随机选择k个观测值;如果传递了ndarray,它应该是形状(n_clusters,n_features)并给出初始中心。
max_iter : int独立于任何早期停止标准启发式停止之前,完整数据集上的最大迭代次数
batch_size : int,optional,默认值:100批次的大小
random_state确定质心初始化和随机重新分配的随机数生成

在这里插入图片描述

上图可见,Mini Batch K-Means 算法比 K-Means 算法训练的时间大大减少,并且效果也差不多,只有少数数据点不同。

代码可见:05_K-means与小批次算法比较.py

九、聚类模型评估

  • 均一性:一个簇中只包含一个类别的样本,则满足均一性;其实也可以认为就是正确率(每个聚簇中正确分类的样本数占该聚簇总样本数的比例和)

p = 1 k ∑ i = 1 k N ( C i = = K i ) N ( K i ) p = \frac{1}{k}\sum_{i=1}^k \frac{N(C_i == K_i)}{N(K_i)} p=k1i=1kN(Ki)N(Ci==Ki)

  • 完整性:同类别样本被归类到相同簇中,则满足完整性;每个聚簇中正确分类的样本数占该
    类型的总样本数比例的和
    r = 1 k ∑ i = 1 k N ( C i = = K i ) N ( C i ) r = \frac{1}{k} \sum_{i=1}^k \frac{N(C_i == K_i)}{N(C_i)} r=k1i=1kN(Ci)N(Ci==Ki)

  • V-measure:均一性和完整性的加权平均
    V β = ( 1 + β 2 ) ⋅ p r β 2 ⋅ V_\beta = \frac{(1+\beta^2)\cdot pr}{\beta^2 \cdot } Vβ=β2(1+β2)pr

  • Rand index(兰德指数)(RI),RI取值范围为[0,1],值越大意味着聚类结果与真实情况越吻合
    R I = a + b C 2 n s a m p l e s RI = \frac{a+b}{C_2^{n_{samples}}} RI=C2nsamplesa+b

其中C表示实际类别信息,K表示聚类结果,a表示在C与K中都是同类别的元素对数,b表示在C与K中都是不同类别的元素对数, C 2 n s a m p l e s C_2^{n_{samples}} C2nsamples 表示数据集中可以组成的对数

  • 调整兰德系数(ARI,Adjusted Rnd Index),ARI取值范围[-1,1],值越大,表示聚类结果和真实情况越吻合。从广义的角度来将,ARI是衡量两个数据分布的吻合程度的
    A R I = R I − E [ R I ] m a x ( R I ) − E [ R I ] ARI = \frac{RI - E[RI]}{max(RI) - E[RI]} ARI=max(RI)E[RI]RIE[RI]

  • 调整互信息(AMI,Adjusted Mutual Information),类似ARI,内部使用信息熵
    A M I = M I ( U , V ) − E { M I ( U , V ) } m a x { H ( U ) , H ( V ) } − E { M I ( U , V ) } AMI = \frac{MI(U,V) - E\{MI(U,V)\}}{max\{H(U),H(V)\} -E\{MI(U,V)\} } AMI=max{H(U),H(V)}E{MI(U,V)}MI(U,V)E{MI(U,V)}

其中, S = { s 1 , s 2 , . . . , s N } , U = { U 1 , U 2 , . . . , U R } , V = { V 1 , V 2 , . . . , V C } S = \{s_1, s_2, ... , s_N\},U = \{U_1,U_2,...,U_R\},V = \{V_1, V_2, ...,V_C\} S={s1,s2,...,sN}U={U1,U2,...,UR}V={V1,V2,...,VC}
U , V U,V UV每个子集不相交, U , V U,V UV 整个集合即 S S S
P ( i ) = ∣ U i ∣ N , P ( j ) = ∣ V j ∣ N P(i) = \frac{|U_i|}{N},P(j) = \frac{|V_j|}{N} P(i)=NUiP(j)=NVj
H ( U ) = − ∑ i = 1 R P ( i ) l o g   P ( i ) , H ( V ) = − ∑ j = 1 C P ( j ) l o g   P ( j ) , n i j = ∣ U i ⋂ V j ∣ H(U) = -\sum_{i=1}^R P(i)log\ P(i),H(V) = -\sum_{j=1}^C P(j)log\ P(j),n_{ij} =|U_i \bigcap V_j| H(U)=i=1RP(i)log P(i)H(V)=j=1CP(j)log P(j)nij=UiVj
M I ( U , V ) = ∑ i = 1 R ∑ j = 1 C P ( i , j ) l o g P ( i , j ) P ( i ) P ( j ) , P ( i , j ) = ∣ U i ⋂ V j ∣ N MI(U,V)=\sum_{i=1}^R\sum_{j=1}^C P(i,j)log \frac{P(i,j)}{P(i)P(j)},P(i,j) = \frac{|U_i \bigcap V_j|}{N} MI(U,V)=i=1Rj=1CP(i,j)logP(i)P(j)P(i,j)P(i,j)=NUiVj

  • 轮廓系数

簇内不相似度:计算样本 i i i 到同簇其它样本的平均距离为 a i a_i ai a i a_i ai 越小,表示样本 i i i 越应该被聚类到该簇,簇C中的所有样本的 a i a_i ai 的均值被称为簇C的簇内不相似度。

簇间不相似度:计算样本 i i i 到其它簇 C j C_j Cj 的所有样本的平均距离 b i j b_{ij} bij b i = m i n { b i 1 , b i 2 , . . . , b i k } b_i = min\{b_{i1},b_{i2},...,b_{ik}\} bi=min{bi1bi2...bik} b i b_i bi 越大,表示样本 i i i 越不属于其他簇。

轮廓系数 s i s_i si 值越接近1表示样本 i i i 聚类越合理,越接近-1,表示样本i应该分类到另外的簇中,近似为0,表示样本 i i i 应该在边界上;所有样本的 s i s_i si 的均值被成为聚类结果的轮廓系数。

s i = b i − a i m a x { a i , b i } s_i = \frac{b_i - a_i}{max\{a_i, b_i\}} si=max{ai,bi}biai
s i = { 1 − a i b i , a i &lt; b i 0 , a i = b i b i a i − 1 , a i &gt; b i s_i = \begin{cases} 1- \frac{a_i}{b_i}, &amp; a_i &lt; b_i \\ 0, &amp; a_i = b_i \\ \frac{b_i}{a_i} - 1, &amp; a_i &gt; b_i \end{cases} si=1biai,0,aibi1,ai<biai=biai>bi

  • 实际工作中,我们假定聚类算法的模型都是比较可以,最多用轮廓系数或模型的score API返回值进行度量;
  • 其它的效果度量方式一般不用
  • 原因:其它度量方式需要给定数据的实际的Y值

====》当我给定Y值的时候,其实我可以直接使用分类算法了,不需要使用聚类

案例:K-means与Mini Batch K-means算法效果评估

运行结果:

# ARI:
K-Means算法:adjusted_rand_score评估函数计算结果值:0.72526;计算消耗时间:0.000s
Mini Batch K-Means算法:adjusted_rand_score评估函数计算结果值:0.72421;计算消耗时间:0.000s
# 均一性和完整性的加权平均:
K-Means算法:v_measure_score评估函数计算结果值:0.65754;计算消耗时间:0.000s
Mini Batch K-Means算法:v_measure_score评估函数计算结果值:0.65780;计算消耗时间:0.000s
# AMI:
K-Means算法:adjusted_mutual_info_score评估函数计算结果值:0.65726;计算消耗时间:0.000s
Mini Batch K-Means算法:adjusted_mutual_info_score评估函数计算结果值:0.65757;计算消耗时间:0.000s
# 互信息:
K-Means算法:mutual_info_score评估函数计算结果值:0.72231;计算消耗时间:0.000s
Mini Batch K-Means算法:mutual_info_score评估函数计算结果值:0.72264;计算消耗时间:0.000s

代码可见:06_K-means与Mini Batch K-means算法效果评估.py

十、总结

  • K-means 简单并且可以用于各种数据类型,它也相当有效,尽管常常多次运行;
  • K-means 的某些变种(包括二分K均值)甚至更有效,并且不太受初始化问题的影响;
  • K-means 并不适合所有的数据类型,它不能处理非球形,不同尺寸和不同密度的簇
  • K-means 对包含离群点的数据进行聚类,也存在问题;
  • 39
    点赞
  • 195
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: K-means聚类算法是一种基于距离度量的无监督学习算法。它将相似的数据点分为同一组,而将不同的数据点分为不同的组。以下是K-means聚类算法的一个应用实例: 假设我们有一个包含n个数据点的数据集,其中每个数据点都有两个属性值x和y。我们想要将这些数据点分为k个组。我们可以使用K-means聚类算法来实现这个目标。 步骤1:随机选择k个数据点作为初始质心。 步骤2:对于每个数据点,计算它与每个质心之间的距离,并将数据点分配到距离最近的质心所在的组。 步骤3:对于每个组,重新计算该组内所有数据点的平均值,并将该平均值作为新的质心。 步骤4:重复步骤2和步骤3,直到质心不再发生变化或达到预设的最大迭代次数。 以下是一个Python实现的示例代码: ```python import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans # 生成随机数据 np.random.seed(0) X = np.random.randn(100, 2) # 使用K-means聚类算法 kmeans = KMeans(n_clusters=3) kmeans.fit(X) # 可视化聚类结果 labels = kmeans.labels_ plt.scatter(X[:, 0], X[:, 1], c=labels) plt.title('K-means Clustering') plt.show() ``` 运行上述代码,将生成一个包含100个随机数据点的散点图,其中不同颜色的点表示不同的聚类组。 ### 回答2: K-means聚类算法是一种常用的无监督学习算法,可用于将数据集划分为不同的类别。以下是一个K-means聚类算法的应用实例。 假设我们有一个电商公司的销售数据集,包含了各个顾客的购买金额和购买频率两个特征。我们希望根据这两个特征将顾客分成不同的群体,以便更好地理解和管理顾客群体。 首先,我们先随机选择K个中心点作为初始的聚类中心。然后,通过计算所有数据点与这K个中心点的距离,将每个数据点分配到最近的中心点所属的类别。接下来,根据所有属于同一类别的数据点,重新计算该类别的中心点坐标。这样,我们就得到了新的K个中心点。 然后,我们再次将所有数据点与这新的K个中心点进行距离计算,重新分配每个数据点所属的类别,并重新计算每个类别的中心点。随着重复迭代的进行,直到每个数据点都不再改变类别,算法就收敛了。 最后,我们就可以根据最终的聚类结果得到不同的顾客群体。比如,我们可能得到了三个不同的类别,每个类别代表了具有相似购买金额和购买频率的顾客群体。这样,我们就可以对不同群体采取不同的营销策略,以提高销售业绩和顾客满意度。 总的来说,K-means聚类算法可以应用于各种领域,如市场分析、社交网络分析等。通过将数据集划分为不同的类别,可以帮助我们发现数据的内在结构,从而更好地进行数据分析和决策。 ### 回答3: K-means聚类算法是一种常用的无监督学习算法,常用于数据聚类分析。下面是一个应用实例: 假设我们有一批客户的相关数据,包括年龄、收入和购物金额。我们希望根据这些数据,将客户分为不同的群组,以便了解不同群组的特征和行为,从而制定相应的营销策略。 首先,我们随机选择k个初始聚类中心点,然后将所有客户根据与这些中心点的欧氏距离分配到最近的聚类中心。然后,根据当前分配的聚类结果,更新聚类中心点的位置。重复上述过程,直到聚类中心点不再发生变化或达到最大迭代次数。 通过K-means算法,我们可以将客户分为不同的群组。例如,某一群组的客户年龄较大,收入较高,购物金额较大;而另一群组的客户年龄较小,收入较低,购物金额较小。这样,我们可以根据这些群组的特征,针对不同消费群体制定相应的营销策略。 通过K-means算法,我们还可以发现一些异常值。例如,某个客户的收入很高,但购物金额却很低,与大多数客户的行为不同。这样的异常值可能是潜在的消费问题,可以引起我们的关注和进一步研究,以便改进我们的服务。 总之,K-means聚类算法是一个强大的分析工具,可以帮助我们理解数据集中的群组结构,发现不同群组的特征,优化营销策略,并发现异常值等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值