K均值聚类和DBSCAN介绍
K均值(K-means)聚类
问题定义:给定数据$\vec{x}_1,\vec{x}_2,\cdots,\vec{x}_n$,将它们分到不同的$K$个簇(cluster)中。定义$\vec{c}=(c_1,c_2,\cdots,c_n),\text{ }c_i\in\{1,2,\cdots,K\}$,$c_i=k$表示$\vec{x}_i$被分到了第$k$个簇中。定义$\vec{\mu}_k$为第$k$个簇的中心(centroid),$k=1,2,\cdots,K$。K-means是一种基于距离的聚类算法,它的目标函数可以写为$$argmin_{\vec{c},\vec{\mu}_1,\cdots,\vec{\mu}_K}\sum\limits_{i=1}^n\sum\limits_{k=1}^KI(c_i=k)\lVert{\vec{x}_i-\vec{\mu}_k}\rVert_2^2$$
求解:使用坐标下降(Coordinate Descent)方法进行求解,将待求解的参数分为两个集合:$\vec{c}$以及$(\vec{\mu}_1,\cdots,\vec{\mu}_K)$。
- 随机初始化$K$个簇的中心$(\vec{\mu}_1,\cdots,\vec{\mu}_K)$
- 固定$(\vec{\mu}_1,\cdots,\vec{\mu}_K)$,找到最优的$c_i,i=1,2,\cdots,n$:$c_i=argmin_{k\in\{1,2,\cdots,K\}}\lVert{\vec{x}_i-\vec{\mu}_k}\rVert_2^2$
- 固定$\vec{c}$,找到最优的$(\vec{\mu}_1,\cdots,\vec{\mu}_K)$:$\vec{\mu}_k=\frac{1}{\sum\limits_{i=1}^nI(c_i=k)}\sum\limits_{i=1}^nI(c_i=k)\vec{x}_i$
- 不断迭代第2步和第3步,直到收敛为止
由于目标函数是非凸的,因此最后的结果可能是局部最优值,实际应用时一般会运行多次上述求解过程(即对$(\vec{\mu}_1,\cdots,\vec{\mu}_K)$进行多次随机初始化),并选择使最终目标函数最小的那个结果。
DBSCAN
DBSCAN是一种基于密度的聚类方法,它不需要预先指定簇的个数,但需要给定两个参数:MinPts以及eps,具体算法如下:
import numpy
def MyDBSCAN(D, eps, MinPts):
"""
Cluster the dataset `D` using the DBSCAN algorithm. It will return a list of cluster labels. The label -1 means noise, and then
the clusters are numbered starting from 1.
"""
labels = [0]*len(D) #Initially all labels are 0, 0 means the point hasn't been considered yet
C = 0 #C is the ID of the current cluster.
### This outer loop is just responsible for picking new seed points--a point
### from which to grow a new cluster.
for P in range(0, len(D)):
if not (labels[P] == 0): continue
NeighborPts = regionQuery(D, P, eps) #Find all of P's neighboring points.
if len(NeighborPts) < MinPts:
labels[P] = -1
else:
C += 1
labels[P] = C #the label to our seed point.
growCluster(D, labels, P, C, eps, MinPts) #Grow the cluster from the seed point.
return labels def growCluster(D, labels, P, C, eps, MinPts):
"""
Grow a new cluster with label `C` from the seed point `P`. This function searches through the dataset to find all points that belong
to this new cluster. When this function returns, cluster `C` is complete.
"""
### SearchQueue is a FIFO queue of points to evaluate. It will only ever
### contain points which belong to cluster C
SearchQueue = [P]
i = 0
while i < len(SearchQueue):
P = SearchQueue[i]
NeighborPts = regionQuery(D, P, eps) #Find all the neighbors of P
### If the number of neighbors is below the minimum, then
### move to the next point in the queue.
if len(NeighborPts) < MinPts:
i += 1
continue
### Otherwise, For each of the neighbors...
for Pn in NeighborPts:
### If Pn was labelled NOISE, claim it as part of cluster C
if labels[Pn] == -1:
labels[Pn] = C #Add Pn to cluster C
### Otherwise, if Pn hasn't been considered yet, claim it as part of
### C and add it to the search queue.
elif labels[Pn] == 0:
labels[Pn] = C #Add Pn to cluster C
SearchQueue.append(Pn) #Add Pn to the SearchQueue
i += 1 #Advance to the next point in the queue.
return def regionQuery(D, P, eps):
"""
Find all points in dataset `D` within distance `eps` of point `P`. This function calculates the distance between a point P and every other
point in the dataset, and then returns only those points which are within a
threshold distance `eps`.
"""
neighbors = []
for Pn in range(0, len(D)):
if numpy.linalg.norm(D[P] - D[Pn]) < eps:
neighbors.append(Pn)
return neighbors
代码部分主要参考了文章DBSCAN Clustering Tutorial。若最终有数据点未被分到任何簇中(噪音点),则可将这些点视为异常点。下图分别是K均值算法以及DBSCAN算法对一个数据集的聚类结果,可以看出相比于K均值算法,DBSCAN算法可以有任意形状的簇,并且找到了数据中的异常点(右图中的空心点)。在实际应用中应对MinPts以及eps这两个参数仔细加以调试,特别是eps在不同的数据集中变化较大,具有较大的调试难度。
DBSCAN的一个改进算法为HDBSCAN,它也是一种基于密度的聚类方法,主要有两个参数$k$(也可记为$min\_samples$)以及$min\_cluster\_size$。DBSCAN通过一个数据点$\vec{x}$的半径为eps的邻域内是否有至少MinPts个点来判定该点是局地稠密还是稀疏的;而HDBSCAN通过一个数据点$\vec{x}$距它的第$k$个近邻点的距离$core_k(\vec{x})$来定量表征该点的局地密度,显然距离越大局地密度越小,在此基础上定义两个数据点之间的距离为:$$d(\vec{x}_1,\vec{x}_2)=\max{(core_k(\vec{x}_1),core_k(\vec{x}_2),\lVert{\vec{x}_1-\vec{x}_2}\rVert_2)}$$
- 以该距离为基础,建立如下面左图所示的Dendrogram树状结构图。该图等价于层次聚类中的single-linkage,即两个簇$X$和$Y$之间的距离可以表示为$d(X,Y)=\min\limits_{\vec{x}\in{X},\text{ }\vec{y}\in{Y}}d(\vec{x},\vec{y})$。
- 为了得到更稳健的聚类结果,HDBSCAN规定若每次分裂分出的两个新簇中有一个簇中的数据点个数小于$min\_cluster\_size$,则不进行这次分裂,只是将不满足要求的新簇中的点从之前的簇中移出,直到分裂出的两个新簇中的数据点个数均大于$min\_cluster\_size$再进行分裂,得到的结果如下图中的右图所示(簇的宽度表示簇中数据点的个数,簇的长度表征簇的存在周期。纵坐标$\lambda$定义为距离的倒数,即$\frac{1}{distance}$)。
- 对任一个簇,将该簇的重要性定义为该簇在右图中所占面积。定义$\lambda_{birth}$为该簇生成时对应的$\lambda$,$\lambda_p$为该簇中的点$p$最后停留在该簇(即分裂到新簇之前或者被移出去之前)时对应的$\lambda$,则该簇的重要性用数学公式可表示为$\sum\limits_{p\in{cluster}}(\lambda_p-\lambda_{birth})$。
- 接下来还剩最后一个要解决的问题,即如何从右图的树状结构中选择最终的簇(右图中圈出的簇为最终选择的簇)。选择最终的簇的过程类似于决策树中的剪枝过程,从最底端开始,若两个子簇的重要性之和大于它们上一级的簇的重要性,则用这两个子簇以及它们的重要性之和代替它们上一级的簇以及上一级簇的重要性,否则删除这两个子簇,重复此过程直到最顶层,最终剩下的簇即为算法最终选择的簇。
- 同DBSCAN类似,最终未被分配到任何簇中的点可视为数据集中的异常点。HDBSCAN算法的主页为The HDBSCAN Clustering Library,一个较为详细的介绍视频链接为HDBSCAN, Fast Density Based Clustering, the How and the Why。
K均值聚类和DBSCAN介绍的更多相关文章
- 【转】算法杂货铺——k均值聚类(K-means)
k均值聚类(K-means) 4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时 ...
- ML: 聚类算法-K均值聚类
基于划分方法聚类算法R包: K-均值聚类(K-means) stats::kmeans().fpc::kmeansruns() K-中心点聚类(K-Medoids) ...
- SciPy k均值聚类
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- 5-Spark高级数据分析-第五章 基于K均值聚类的网络流量异常检测
据我们所知,有‘已知的已知’,有些事,我们知道我们知道:我们也知道,有 ‘已知的未知’,也就是说,有些事,我们现在知道我们不知道.但是,同样存在‘不知的不知’——有些事,我们不知道我们不知道. 上一章 ...
- 机器学习实战5:k-means聚类:二分k均值聚类+地理位置聚簇实例
k-均值聚类是非监督学习的一种,输入必须指定聚簇中心个数k.k均值是基于相似度的聚类,为没有标签的一簇实例分为一类. 一 经典的k-均值聚类 思路: 1 随机创建k个质心(k必须指定,二维的很容易确定 ...
- Python实现kMeans(k均值聚类)
Python实现kMeans(k均值聚类) 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) 计算过程 st=>start: 开始 e=> ...
- 机器学习理论与实战(十)K均值聚类和二分K均值聚类
接下来就要说下无监督机器学习方法,所谓无监督机器学习前面也说过,就是没有标签的情况,对样本数据进行聚类分析.关联性分析等.主要包括K均值聚类(K-means clustering)和关联分析,这两大类 ...
- 第十篇:K均值聚类(KMeans)
前言 本文讲解如何使用R语言进行 KMeans 均值聚类分析,并以一个关于人口出生率死亡率的实例演示具体分析步骤. 聚类分析总体流程 1. 载入并了解数据集:2. 调用聚类函数进行聚类:3. 查看聚类 ...
- K均值聚类的失效性分析
K均值聚类是一种应用广泛的聚类技术,特别是它不依赖于任何对数据所做的假设,比如说,给定一个数据集合及对应的类数目,就可以运用K均值方法,通过最小化均方误差,来进行聚类分析. 因此,K均值实际上是一个最 ...
随机推荐
- [Qt插件]-01Qt插件&&提升部件(自定义控件)
本篇的文档为:How to Create Qt Plugins https://doc.qt.io/qt-5/plugins-howto.html 前言 Qt插件(Qt Plugin)就是一个共享 ...
- P1536 村村通(洛谷)并查集
隔壁的dgdger带我看了看老师的LCA教程,我因为学习数学太累了(就是懒),去水了一下,感觉很简单的样子,于是我也来写(水)个博客吧. 题目描述 某市调查城镇交通状况,得到现有城镇道路统计表.表中列 ...
- 少儿编程:python趣味编程第一课
本文仅针对8-16岁的青少年,所以流程是按如何去教好中小学生走的,并不适合成人找工作学习,因为进度也是按照青少年走的 大家好,我是C大叔,从事少儿编程行业三年有余(2016年从事少儿编程行业,少儿编程 ...
- IDEA命令行缩短器助你解决此问题:Command line is too long. Shorten command line...
生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...
- vue : 使用stylus less (包括sublime插件支持)
版本: vue 2.5.2 webpack 3.6.0 先说stylus. 用npm装个包. npm install stylus stylus-loader --save-dev 然后在.vue文件 ...
- layui 魔改:富文本编辑器添加上传视频功能
甲方又整新需求了:富文本编辑器需要可以传视频. layui本身的富文本编辑器没有传视频的功能,所以,又到了咱们魔改的时候了. 友情提醒,富文本编辑器 layedit 只有layui的V1版有,V2版没 ...
- 在ShareX里添加流浪图床
这里以咱流浪图床为例哈:-D 上传目标类型:图像.文件 请求方法:POST 请求URL:https://p.sda1.dev/api/v1/upload_external_noform URL参数:名 ...
- 动态DP,ddp
动态DP?动态动态规划? 个人理解:动态DP,就是普通DP加修改操作,然后就变成了个毒瘤题. 直接就着例题写吧. 例题 P4719 [模板]"动态 DP"&动态树分治 求树 ...
- 题解 CF613D 【Kingdom and its Cities】
考虑树形\(DP\),设\(num_x\)记录的为当\(1\)为根时,以\(x\)为子树中重要城市的个数. 那么进行分类讨论: ① 当\(num_x≠0\)时,则需将其所有满足\(num_y≠0\)的 ...
- Kafka 入门(二)--数据日志、副本机制和消费策略
一.Kafka 数据日志 1.主题 Topic Topic 是逻辑概念. 主题类似于分类,也可以理解为一个消息的集合.每一条发送到 Kafka 的消息都会带上一个主题信息,表明属于哪个主题. Kafk ...