一、聚类分析
聚类分析是根据在数据中发现的描述对象(数据)及其关系的信息,将数据划分成有意义或有用的组(簇)。其目标是:
- 组内的对象相互之间是相似的(相关的),而不同组中的对象是不同的(不相关的);
- 组内的相似性(同质性)越大,组间差别越大,聚类就越好。
聚类可以看作是一种分类,它用簇标号创建对象的标记。然而,只能从数据中导出这些标记,它与分类(例如分类决策树等)不同,分类是监督分类,即使用由类标号(标签数据)已知的对象开发的模型,对新的、无标记的对象赋予类标号。因此,聚类分析也称为非监督分类。
二、不同的聚类类型
不同类型的聚类主要包括:
- 层次的(嵌套的)与划分的(非嵌套的)
-
划分聚类:简单地将数据对象集划分成不重叠的子集(簇),是的每个数据对象恰在一个子集中
-
层次聚类:允许簇具有子簇;层次聚类是嵌套簇的集合,组成一棵树
- 互斥的、重叠的与模糊的
-
互斥的:每个对象都指派到单个簇
-
重叠的:一个对象同时属于多个簇
-
模糊的:每个对象以一个0(绝对不属于)和1(绝对属于)之间的值作为属于某个簇的权重(概率)
- 完全的与部分的
-
完全的:将每个对象指派到一个簇中
-
部分的:数据集中有些对象可能是噪声、离群点或“特定聚类任务不感兴趣的点”,这些对象可能不属于明确定义的簇。
三、不同的簇类型
- 明显分离的
- 簇是对象的集合,其中每个对象到同簇中的每个对象的距离比到不同簇中任意对象的距离都近(或更相似);
- 如图(1),不同组中的任意两点之间的距离都大于组内任意两点之间的距离
- 明显分离的簇可以是任意形状的。
- 基于原型的
- 簇是对象的集合,其中每个对象到定义该 簇的原型的距离比到其他簇的原型的距离更近(或更相似);
- 对于许多数据类型,原型可以视为最靠近中心的点,也称为“基于中心的簇”,如图(2);
- 这种簇趋向于呈球形状。
簇的原型:
- 指的是质心,即簇中所有点的平均值;
- 当数据具有分类属性时,质心没有意义,簇的原型就是中心点,即簇中最有代表性的点。
- 基于图的
- 如果数据用图来表示,其中结点为对象,而边代表对象之间的联系,则簇可以定义为连通分支,即互相连通但不与组外对象连通的对象组;
- 基于图的簇的一个重要例子是 基于邻近的簇 ,当两个对象的距离在指定的范围之内,这两个对象就是相连的;也就是说,每个对象到该簇某个对象的距离比到不同簇中任意点的距离更近;
- 如图(3),两个球形之间有数据连接,基于邻近的簇,就将其看作是同一个簇
- 这种簇,当数据具有噪声时可能出现问题,比如,图中连接两个球形簇的数据点是噪声点,此时就会由于噪声出现问题。
- 基于密度的
- 簇是对象的稠密区域,被低密度区域环绕;
- 如图(4),数字10,上的数据明显比其他地方稠密,低密度的区域被视为噪声点
- 这种簇可能会因为数据密度的不同出现问题。
- 共同性质的(概念簇)
- 如图(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=mi1x∈Ci∑x
其中, 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=1∑Kxi∈Ci∑dist(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
∂ck∂SSE=∂ck∂i=1∑Kxi∈Ci∑(ci−x)2
=
∑
x
∈
C
k
2
(
c
k
−
x
k
)
=
0
= \sum_{x \in C_k}2(c_k- x_k) = 0
=x∈Ck∑2(ck−xk)=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
x∈Ck∑2(ck−xk)=0→mkck=x∈Ck∑xk→ck=mk1x∈Ck∑xk
由上公式可知,簇的最小化 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-Means
和 K均值
都具有一些局限性。当簇具有非球形形状或具有不同尺寸或密度时,二分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 k−1 个聚类中心点的值)
- 容易受噪声点影响
\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 < r 1 D < r_1 D<r1,表示该节点属于该聚簇,添加到该聚簇列表中;
- 如果距离 D < r 2 D < r_2 D<r2,表示该节点不仅仅属于该聚簇,还表示和当前聚簇中心点非常近,所以将该聚簇的中心点设置为该簇中所有样本的中心点,并将P从列表L中删除;
- 如果距离 D > r 1 D > 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-Means
和 Mini 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=1∑kN(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=1∑kN(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]RI−E[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 U,V每个子集不相交, U , V U,V U,V 整个集合即 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)=N∣Ui∣,P(j)=N∣Vj∣
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=1∑RP(i)log P(i),H(V)=−j=1∑CP(j)log P(j),nij=∣Ui⋂Vj∣
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=1∑Rj=1∑CP(i,j)logP(i)P(j)P(i,j),P(i,j)=N∣Ui⋂Vj∣
- 轮廓系数
簇内不相似度:计算样本 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{bi1,bi2,...,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}bi−ai
s
i
=
{
1
−
a
i
b
i
,
a
i
<
b
i
0
,
a
i
=
b
i
b
i
a
i
−
1
,
a
i
>
b
i
s_i = \begin{cases} 1- \frac{a_i}{b_i}, & a_i < b_i \\ 0, & a_i = b_i \\ \frac{b_i}{a_i} - 1, & a_i > b_i \end{cases}
si=⎩⎪⎨⎪⎧1−biai,0,aibi−1,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
对包含离群点的数据进行聚类,也存在问题;