精华内容
下载资源
问答
  • 创建它是为了在大型1D阵列上高效地执行聚类。 没有一维的特殊情况,因为在这种情况下计算全距离矩阵是浪费的。 最好简单地对输入数组进行排序并执行有效的二等分以找到最接近的点要好得多。 这是运行软件包附带的...
  • DBSCAN聚类算法matlab代码,内包含测试数据,下载可以直接运行。
  • 使用matlab对输入的二维数据进行k-means聚类。可以直接输入数据坐标或者黑白图像,包含一张数据输入图像例子。
  • 聚类概念 聚类是把相似的东西分到一组,它是一个无监督问题,没有标签使用 难点: 对于有标签的有监督学习问题,标签可以便于我们来评估模型,无监督学习问题在评估上比较难一点 对于不同的参数组合,得到的学习结果...
  • DBSCAN聚类算法

    2018-11-21 11:07:30
    底层用C++写的,放在CPPcode文件夹里的是源码。通过matlab生成100个2d高斯点,存放为“points.txt”,然后调用exe程序读取、处理、输出分类结果为out.txt,matlab读取该文件并画出分类结果
  • 采用DBSCAN聚类的散乱点云特征提取方法
  • 基于DBSCAN聚类和双边滤波点云去噪方法,曲金博,王岩,在三维激光点云数据获取时,由于距离不同,点云数据的密度也不同,很难保证不同密度的点云数据能够有效去噪和光顺。为此,提出了
  • DBSCAN聚类算法C++代码实现,附上了测试数据,以及该测试数据对应的输出结果,下载可直接运行。
  • Dbscan算法做如下改进:(1)对于核心对象 ,其邻域不再做进一步考查 ,而是将其归为某个簇 。 该簇有可能是核心对象所在簇 ,也有可能是与其他簇合并过的簇 。 (2)对于边界对象 ,进一步考查其邻域中是否存在...
  • 自己写的DBSCAN的实现,实现语言为C++,适合数据挖掘的人员使用
  • 本篇文章是对使用C++实现DBSCAN聚类算法的方法进行了详细的分析介绍,需要的朋友参考下
  • DBSCAN聚类算法的参数配置方法研究.pdf
  • DBSCAN聚类算法matlab代码,内包含测试数据,下载可以直接运行。 DBSCAN聚类算法matlab代码,内包含测试数据,下载可以直接运行。
  • 基于自适应蜂群优化的DBSCAN聚类算法.pdf
  • 一种提高DBSCAN聚类算法质量的新方法.pdf
  • 现有的基于共享最近邻密度的聚类(SNND)算法的增量扩展无法处理数据集的删除,并且一次只能处理一个插入点。 我们提出了一种增量算法来克服这两个瓶颈,方法是在以批处理模式处理数据集的更新时,通过有效地识别...
  • DBSCAN_matlab Matlab中DBSCAN聚类分析算法的实现
  • DBSCAN聚类

    2020-03-14 22:19:40
    DBSCAN进行密度聚类

      物以类聚,人以群分,平常我们把人和物进行分类,今天来讲一讲如何通过DBSCAN用数据把样本进行聚类。
     

    1. DBSCAN 定义

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

    2. DBSCAN 的原理
    2.1 DBSCAN中几个常见的定义

    Ε邻域: 以某个点为中心,半径为E画圆,围成的区域称为该点的E邻域

    核心对象: 如果某点E邻域内的样本点数大于等于MinPts(一般为自己设定大于1的正整数),则该点为核心对象

    直接密度可达: 如果p为核心对象, q在p的E邻域中,称q从对象p直接密度可达,注意p不一定从对象q直接密度可达,除非q也是核心对象。

    密度可达: 对于样本集合D,给定一串样本点{p1,p2….pn},p= p1,q= pn,假如对象pi从pi-1直接密度可达,那么对象q从对象p密度可达。

    密度相连: 存在样本集合D中的一点o,如果对象o到对象p和对象q都是密度可达的,那么p和q密度相联。

    图1 模拟DBSCAN算法生成的三个簇

      
      在图1中,设定MinPts=4,图中蓝色的点是核心对象(这些点E邻域中点的个数大于等于4), 黑色的点是非核心对象,灰色的点是孤立点。在同一个圈(E邻域)中的点,黑色的点从蓝色点直接密度可达。从图1中可以看出DBSCAN把所有样本分成了四类,其中三类分别在不同的簇中。每一个簇中蓝色的点(核心对象)之间是密度可达的,蓝色的点和黑色的点之间是密度相连的。还有一类为异常值(灰色的点),所以DBSCAN不仅可以做聚类分析,还可以做异常值检测。

    2.2 DBSCAN 算法描述

      假设要对样本集X进行DBSCAN聚类,其实就是把X中密度相连的点的最大集合作为一个簇,直到找出所有的簇即完成了聚类。下面描述具体的步骤:

    (1) 检测样本集中尚未检查过的样本p,如果p未被归为某个簇或者标记位噪声(异常值),则检测其Ε邻域,若邻域内包含的样本数不少于MinPts,则建立新簇C,将邻域内的所有点加入候选集N;

    (2) 对候选集N中所有尚未被处理的样本q,检测其E邻域,若邻域内包含样本数不少于MinPts的样本点,则将这些样本点加入N。如果q未归入任何一个簇,则将q加入C;

    (3) 重复步骤2,继续检测N中未处理的样本,直到当前候选集N为空;

    (4) 重复步骤1~3,直到所有样本都归入了某个簇或被标记为噪声。
     

    3. DBSCAN 优缺点
    3.1 优点

    (1) 相比于K-Means之类的聚类算法只适用于凸样本集,DBSCAN既适用于凸样本集,也适用于非凸样本集,并且可以对任意形状的稠密数据集进行聚类(可参见下文图2)。

    (2) 聚类结果不依赖初始值,结果没有偏倚。

    (3) DBSCAN不仅可以做聚类分析,还可以做异常值检测,算法对数据集中的异常点不敏感。

    3.2 缺点

    (1) 对数据要求较高,如果样本集密度不均匀、聚类间差距较大时,DBSCAN的结果较差,最好在聚类之前对数据进行标准化处理。

    (2) 距离阈值eps(E邻域的半径)和邻域内包含样本数MinPts参数较难确定,并且对结果影响较大。

    (3) 如果样本集较大时,聚类收敛的时间较长。

    实例:用DBSCAN对笑脸数据聚类

    图2 用DBSCAN对笑脸数据进行聚类

      
      动图素材来源(感兴趣的可以去该网址调整一下参数感受DBSCAN的聚类过程):https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
      

    4. DBSCAN 在Python中实现代码
    from sklearn.cluster import DBSCAN   #加载库
    result=DBSCAN(eps=0.5, min_samples=5, metric=’euclidean’, algorithm=’auto’, leaf_size=30, p=None).fit(X)
    

    主要参数解析:

    eps: E邻域的距离阈值,默认值0.5;

    min_samples: 样本点要成为核心对象所需的E邻域样本数阈值,即前文提到的MinPts;

    metric: 最近邻距离度量参数,可选欧式距离、曼哈顿距离、切比雪夫距离、马氏距离、闵可夫斯基距离、带权重闵可夫斯基距离等,默认采用欧式距离;

    algorithm: 最近邻搜索算法参数,算法包括三种——蛮力实现(brute)、KD树实现(kd_tree)、球树实现(ball_tree), 如果选择auto会在上面三种算法中做权衡,选择一个拟合最优的算法;

    leaf_size: 当最近邻搜索算法参数为KD树或球树时, 设定的值为停止建子树的叶子节点数量的阈值,默认值30;

    p: 当最近邻距离度量参数为闵可夫斯基距离和带权重闵可夫斯基距离时,设定p=1为曼哈顿距离, p=2为欧式距离,采用默认值欧式距离时这个值为None;
      

    5. 项目实战

      背景介绍: 商户mcc在录入的时候可能由于录入人员不小心录错,或者商户故意错填mcc,以掩盖自己虚假经营的事实,导致和实际交易的mcc不符。本文用DBSCAN算法通过分析商户的交易数据,找出和实际不符的mcc,从而纠正mcc。

    step1:加载数据
    import pandas as pd 
    import numpy as np 
    mcc_dm = pd.read_csv('mcc_dm.csv')
    
    step2:挑选变量
    coulmns_dm = [
    'all_avg_tran_amt_30d',
    'all_tran_cnt_suc_pct_30d',
    'card_tran_cnt_cre_pct_30d',
    'all_tran_cnt_m5k_suc_pct_30d',
    'tran_cnt_100int_f5_suc_pct_30d',
    'ms_deb_card_cnt_pct_30d'
      ]
    
    step3: 使用DBSCAN进行聚类并寻找异常样本点
    #标准化处理
    from sklearn import preprocessing  
    X_dm = mcc_dm[columns_dm]
    X_dm_1 = preprocessint.scale(X_dm)
    #DBSCAN聚类
    from sklearn.cluster import DBSCAN
    dm_scale_dbscan = DBSCAN(eps=2, min_samples=10).fit(X_dm_1)  
    X_dm['pred_scale_dbscan'] = dm_scale_dbscan.labels_
    

    代码解析:

    X_dm: 生成待入模的特征标签;

    X_dm_1: 标准化处理数据,减少样本集密度不均匀对算法的影响。我在分析的时候发现,如果数据不进行标准化处理,由于实际的数据很可能密度不均匀,导致DBSCAN的结果很差,最好先处理一下数据再做DBSCAN聚类;

    dm_scale_dbscan =: 用处理好的数据训练模型,eps的值取2,min_samples的值取10,这两个参数要根据最后结果的分析进行多次调整;

    X_dm[‘pred_scale_dbscan’]: 把聚类的标签放到原始数据中 ,其中-1代表异常值;
      

    step4: DBSCAN结果分析
    X_dm['pred_scale_dbscan'].value_counts().sort_index()   #看下落在每一组的数据分布情况
    

    结果:

      -1   16
       0   9832
       1   160
       2   52
       3   23

      最后通过排查发现落在-1这一组的16个商户中有15个商户的mcc存在录入错误,需要纠正mcc,验证了DBSCAN算法在实际应用中的可行性。而且落在1、2、3这些组中的商户和该mcc大部分的商户(落在0中)存在差别,可以进一步分析原因,可以先用下面的脚本从数据层面进行分析,如果想进一步确定,可以下发监控运营进行批量排查,找出差别。

    X_dm.groupby('pred_scale_dbscan').mean()
    

      本文是本人使用DBSCAN后的一些见解,如有不当之处恳请指正。如果对文章还有不理解的地方,可以在公众号中进行咨询。

      
    参考文献:

    1. https://baike.so.com/doc/3105468-3273248.html
    2. https://www.cnblogs.com/pinard/p/6208966.html

      

    猜你感兴趣
    孤立森林
    风控建模整体流程
    用Python绘制皮卡丘
    用Python绘制词云图
    Python入门干货经验(免费提供资料)
    用Python绘制杨紫作品集动态二维码

      

    -end-
    长按(扫一扫)识别上方二维码学习更多Python和建模知识
    展开全文
  • DBSCAN聚类算法讲稿.ppt

    2020-03-26 18:12:49
    凸型的聚类簇基于距离的聚类因为算法的原因最后实现的聚类通常是类圆形的一旦面对具有复杂形状的簇的时候此类方法通常会无法得到满意的结果这种时候基于密度的聚类方法就能有效地避免这种窘境? 与K-means比较起来你...
  • 基于DBSCAN聚类的西部城区服务业空间布局特征研究——以西宁市城西区为例.pdf
  • 是一种数据挖掘算法,能够把有特征的数据从大量数据中挖掘出来,C++,可以运行
  • 针对传统的DBSCAN(Density-Based Spatial Clustering of Application with Noise,DBSCAN聚类算法全局参数设置不合理、参数选取困难、无法识别重叠模块的问题,以及人工蜂群优化算法(Artificial Bees Colony,...
  • DBSCAN聚类结果分析

    2021-03-23 20:54:44
    使用DBSCAN聚类时,我的MinPoints(min_samples)的数目选择10,但是聚类的结果,很多类里面都是只有两个元素,根据我对于原理的理解,不应该要半径eps的范围内有超过...
  • DBSCAN聚类算法,初步实现,功能比较简单,数据集比较简单
  • 一、前言二、DBSCAN聚类算法三、参数选择四、DBSCAN算法迭代可视化展示五、常用的评估方法:轮廓系数六、用Python实现DBSCAN聚类算法一、前言去年学聚类算法的R语言的时候,有层次聚类、系统聚类、K-means聚类、K...

    一、前言

    二、DBSCAN聚类算法

    三、参数选择

    四、DBSCAN算法迭代可视化展示

    五、常用的评估方法:轮廓系数

    六、用Python实现DBSCAN聚类算法

    一、前言

    去年学聚类算法的R语言的时候,有层次聚类、系统聚类、K-means聚类、K中心聚类,最后呢,被DBSCAN聚类算法迷上了,为什么呢,首先它可以发现任何形状的簇,其次我认为它的理论也是比较简单易懂的。今年在python这门语言上我打算好好弄弄DBSCAN。下面贴上它的官方解释:

    DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。 该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。

    二、DBSCAN聚类算法

    文字看不懂看下面这个图。下面这些点是分布在样本空间的众多样本,现在我们的目标是把这些在样本空间中距离相近的聚成一类。我们发现A点附近的点密度较大,红色的圆圈根据一定的规则在这里滚啊滚,最终收纳了A附近的5个点,标记为红色也就是定为同一个簇。其它没有被收纳的根据一样的规则成簇。(形象来说,我们可以认为这是系统在众多样本点中随机选中一个,围绕这个被选中的样本点画一个圆,规定这个圆的半径以及圆内最少包含的样本点,如果在指定半径内有足够多的样本点在内,那么这个圆圈的圆心就转移到这个内部样本点,继续去圈附近其它的样本点,类似传销一样,继续去发展下线。等到这个滚来滚去的圈发现所圈住的样本点数量少于预先指定的值,就停止了。那么我们称最开始那个点为核心点,如A,停下来的那个点为边界点,如B、C,没得滚的那个点为离群点,如N)。

    1b45f7a38e4b6e30cf3ba7e43aedbca3.png

    基于密度这点有什么好处呢,我们知道kmeans聚类算法只能处理球形的簇,也就是一个聚成实心的团(这是因为算法本身计算平均距离的局限)。但往往现实中还会有各种形状,比如下面两张图,环形和不规则形,这个时候,那些传统的聚类算法显然就悲剧了。于是就思考,样本密度大的成一类呗。呐这就是DBSCAN聚类算法。

    b2903d84cf9103b3b0752d8cc31cfffe.png

    三、参数选择

    上面提到了红色圆圈滚啊滚的过程,这个过程就包括了DBSCAN算法的两个参数,这两个参数比较难指定,公认的指定方法简单说一下:

    半径:半径是最难指定的 ,大了,圈住的就多了,簇的个数就少了;反之,簇的个数就多了,这对我们最后的结果是有影响的。我们这个时候K距离可以帮助我们来设定半径r,也就是要找到突变点,比如:

    52c80f5d7738be3c66fef41b04e3db17.png

    以上虽然是一个可取的方式,但是有时候比较麻烦 ,大部分还是都试一试进行观察,用k距离需要做大量实验来观察,很难一次性把这些值都选准。

    MinPts:这个参数就是圈住的点的个数,也相当于是一个密度,一般这个值都是偏小一些,然后进行多次尝试

    四、DBSCAN算法迭代可视化展示

    48cb3c5c86d80c354ef122fe645d1c0c.png

    它可以把我们DBSCAN的迭代过程动态图画出来

    a1f2965f3fef94018ecedf57e5951ead.png

    设置好参数,点击GO! 就开始聚类了!

    c18cd467ac149c2241f3594db4e26324.png

    直接跳到最后看一下DBSCAN的聚类结果,如下:

    4c3ac4c48d41af4af8272099fcfff91f.png

    如果minPoints参数设置再大一点,那么这个笑脸可能会更好看。没有颜色标注的就是圈不到的样本点,也就是离群点,DBSCAN聚类算法在检测离群点的任务上也有较好的效果。如果是传统的Kmeans聚类,我们也来看一下效果:

    fa8961b142926ef344cfff6186c063cf.png

    是不是好丑,这完美的体现出来DBSCAN算法基于密度聚类的优势了啊.

    五、常用的评估方法:轮廓系数

    这里提一下聚类算法中最常用的评估方法——轮廓系数(Silhouette Coefficient):

    e727878d9b758eeeed6ff7410b13c976.pngji

    计算样本i到同簇其它样本到平均距离ai。ai越小,说明样本i越应该被聚类到该簇(将ai称为样本i到簇内不相似度)。

    计算样本i到其它某簇Cj的所有样本的平均距离bij,称为样本i与簇Cj的不相似度。定义为样本i的簇间不相似度:bi=min(bi1,bi2,...,bik2)

    si接近1,则说明样本i聚类合理

    si接近-1,则说明样本i更应该分类到另外的簇

    若si近似为0,则说明样本i在两个簇的边界上

    六、用Python实现DBSCAN聚类算法

    importpandas as pd#导入数据

    beer = pd.read_csv('data.txt', sep=' ')print(beer)

    输出结果:

    9fec3ba372c3dcfd653b57f307a63de9.png

    from sklearn.cluster importDBSCAN

    X= beer[["calories","sodium","alcohol","cost"]]#设置半径为10,最小样本量为2,建模

    db = DBSCAN(eps=10, min_samples=2).fit(X)

    labels=db.labels_

    beer['cluster_db'] = labels #在数据集最后一列加上经过DBSCAN聚类后的结果

    beer.sort_values('cluster_db')#注:cluster列是kmeans聚成3类的结果;cluster2列是kmeans聚类成2类的结果;scaled_cluster列是kmeans聚类成3类的结果(经过了数据标准化)

    输出结果:

    235d21a0cffc79114e5182afda47774c.png

    #查看根据DBSCAN聚类后的分组统计结果(均值)

    print(beer.groupby('cluster_db').mean())

    d5d2f8f3e04006dc5e4d2187d4b16403.png

    #画出在不同两个指标下样本的分布情况

    print(pd.scatter_matrix(X, c=colors[beer.cluster_db], figsize=(10,10), s=100))

    ee71a224143098ce6e52429871d97d0e.png

    #我们可以从上面这个图里观察聚类效果的好坏,但是当数据量很大,或者指标很多的时候,观察起来就会非常麻烦。

    from sklearn importmetrics#就是下面这个函数可以计算轮廓系数(sklearn真是一个强大的包)

    score =metrics.silhouette_score(X,beer.cluster_db)print(score)

    展开全文
  • 详解DBSCAN聚类

    千次阅读 多人点赞 2020-08-16 08:08:42
    ​ **基于密度的噪声应用空间聚类(DBSCAN)**是一种无监督的ML聚类算法。无监督的意思是它不使用预先标记的目标来聚类数据点。聚类是指试图将相似的数据点分组到人工确定的组或簇中。它可以替代KMeans和层次聚类等...

    使用DBSCAN标识为员工分组

    ​ **基于密度的噪声应用空间聚类(DBSCAN)**是一种无监督的ML聚类算法。无监督的意思是它不使用预先标记的目标来聚类数据点。聚类是指试图将相似的数据点分组到人工确定的组或簇中。它可以替代KMeans和层次聚类等流行的聚类算法。

    ​ 在我们的示例中,我们将检查一个包含15,000名员工的人力资源数据集。数据集包含员工的工作特征,如工作满意度、绩效评分、工作量、任职年限、事故、升职次数。

    KMeans vs DBSCAN

    ​ KMeans尤其容易受到异常值的影响。当算法遍历质心时,在达到稳定性和收敛性之前,离群值对质心的移动方式有显著的影响。此外,KMeans在集群大小和密度不同的情况下还存在数据精确聚类的问题。K-Means只能应用球形簇,如果数据不是球形的,它的准确性就会受到影响。最后,KMeans要求我们首先选择希望找到的集群的数量。下面是KMeans和DBSCAN如何聚类同一个数据集的示例。

    ​ 另一方面,DBSCAN不要求我们指定集群的数量,避免了异常值,并且在任意形状和大小的集群中工作得非常好。它没有质心,聚类簇是通过将相邻的点连接在一起的过程形成的。

    DBSCAN是如何实现的呢?

    ​ 首先,让我们定义Epsilon和最小点、应用DBSCAN算法时需要的两个参数以及一些额外的参数。

    1. **Epsilon (ɛ):**社区的最大半径。如果数据点的相互距离小于或等于指定的epsilon,那么它们将是同一类的。换句话说,它是DBSCAN用来确定两个点是否相似和属于同一类的距离。更大的epsilon将产生更大的簇(包含更多的数据点),更小的epsilon将构建更小的簇。一般来说,我们喜欢较小的值是因为我们只需要很小一部分的数据点在彼此之间的距离内。但是如果太小,您会将集群分割的越来越小。

    2. **最小点(minPts):**在一个邻域的半径内minPts数的邻域被认为是一个簇。请记住,初始点包含在minPts中。一个较低的minPts帮助算法建立更多的集群与更多的噪声或离群值。较高的minPts将确保更健壮的集群,但如果集群太大,较小的集群将被合并到较大的集群中。

    如果“最小点”= 4,则在彼此距离内的任意4个或4个以上的点都被认为是一个簇。

    其他参数

    **核心点:**核心数据点在其近邻距离内至少有的最小的数据点个数。

    我一直认为DBSCAN需要一个名为“core_min”的第三个参数,它将确定一个邻域点簇被认为是聚类簇之前的最小核心点数量。

    **边界点:**边界数据点位于郊区,就像它们属于近邻点一样。(比如w/在epsilon距离内的核心点),但需要小于minPts。

    **离群点:**这些点不是近邻点,也不是边界点。这些点位于低密度地区。

    ​ 首先,选择一个在其半径内至少有minPts的随机点。然后对核心点的邻域内的每个点进行评估,以确定它是否在epsilon距离内有minPts (minPts包括点本身)。如果该点满足minPts标准,它将成为另一个核心点,集群将扩展。如果一个点不满足minPts标准,它成为边界点。随着过程的继续,算法开始发展成为核心点“a”是“b”的邻居,而“b”又是“c”的邻居,以此类推。当集群被边界点包围时,这个聚类簇已经搜索完全,因为在距离内没有更多的点。选择一个新的随机点,并重复该过程以识别下一个簇。

    如何确定最优的Epsilon值

    ​ 估计最优值的一种方法是使用k近邻算法。如果您还记得的话,这是一种有监督的ML聚类算法,它根据新数据点与其他“已知”数据点的距离来聚类。我们在带标记的训练数据上训练一个KNN模型,以确定哪些数据点属于哪个聚类。当我们将模型应用到新数据时,算法根据与训练过的聚类的距离来确定新数据点属于哪一个聚类。我们必须确定“k”参数,它指定在将新数据点分配给一个集群之前,模型将考虑多少个最邻近点。

    ​ 为了确定最佳的epsilon值,我们计算每个点与其最近/最近邻居之间的平均距离。然后我们绘制一个k距离,并选择在图的“肘部”处的epsilon值。在y轴上,我们绘制平均距离,在x轴上绘制数据集中的所有数据点。

    ​ 如果选取的epsilon太小,很大一部分数据将不会被聚类,而一个大的epsilon值将导致聚类簇被合并,大部分数据点将会在同一个簇中。一般来说,较小的值比较合适,并且作为一个经验法则,只有一小部分的点应该在这个距离内。

    如何确定最佳minPts

    ​ 通常,我们应该将minPts设置为大于或等于数据集的维数。也就是说,我们经常看到人们用特征的维度数乘以2来确定它们的minPts值。

    ​ 就像用来确定最佳的epsilon值的“肘部方法”一样,minPts的这种确定方法并不是100%正确的。

    DBSCAN聚类的评价方式

    **影像法:**该技术测量集群之间的可分离性。首先,找出每个点与集群中所有其他点之间的平均距离。然后测量每个点和其他簇中的每个点之间的距离。我们将两个平均值相减,再除以更大的那个平均值。

    ​ 我们最终想要的是一种较高(比如最接近1)的分数,表明存在较小的簇内平均距离(紧密簇)和较大的簇间平均距离(簇间分离良好)。

    **集群可视化解释:**获得集群之后,解释每个集群非常重要。这通常是通过合并原始数据集和集群并可视化每个集群来完成的。每个集群越清晰越独特越好。我们将在下面实现这个过程。

    DBSCAN的优点

    • 不需要像KMeans那样预先确定集群的数量
    • 对异常值不敏感
    • 能将高密度数据分离成小集群
    • 可以聚类非线性关系(聚类为任意形状)

    DBSCAN的缺点

    • 很难在不同密度的数据中识别集群
    • 难以聚类高维数据
    • 对极小点的参数非常敏感

    让我们尝试一下

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    import plotly.offline as pyo
    pyo.init_notebook_mode()
    import plotly.graph_objs as go
    from plotly import tools
    from plotly.subplots import make_subplots
    import plotly.offline as py
    import plotly.express as px
    from sklearn.cluster import DBSCAN
    from sklearn.neighbors import NearestNeighbors
    from sklearn.metrics import silhouette_score
    from sklearn.preprocessing import StandardScaler
    from sklearn.decomposition import PCAplt.style.use('fivethirtyeight')
    from warnings import filterwarnings
    filterwarnings('ignore')
    with open('HR_data.csv') as f:
        df =  pd.read_csv(f, usecols=['satisfaction_level', 'last_evaluation', 'number_project',
           'average_montly_hours', 'time_spend_company', 'Work_accident',
           'promotion_last_5years'])
    f.close()
    

    1. 标准化

    ​ 由于数据集中的特特征不在相同的范围内,所以我们需要对整个数据集进行标准化。换句话说,我们数据集中的每个特征对于它们的数据都有独特的大小和范围。满意度水平增加一分并不等于最后评价增加一分,反之亦然。由于DBSCAN利用点之间的距离(欧几里得)来确定相似性,未缩放的数据会产生问题。如果某一特征在其数据中具有较高的可变性,则距离计算受该特征的影响较大。通过缩放特征,我们将所有特征对齐到均值为0,标准差为1。

    scaler = StandardScaler()
    scaler.fit(df)
    X_scale = scaler.transform(df)df_scale = pd.DataFrame(X_scale, columns=df.columns)
    df_scale.head()
    

    2. 特征降维

    ​ 在一些算法如KMeans中,如果数据集的特征维度太大,就很难精确地构建聚类。高维数并不一定意味着成百上千维度的特征。甚至10个维度的特征也会造成准确性问题。

    ​ 特征降维背后的理论是将原始特征集转换为更少的人工派生特征,这些特征仍然保留了原始特征中包含的大部分信息。

    ​ 最流行的特征降维技术之一是主成分分析(PCA)。PCA将原始数据集缩减为指定数量的特征,并将这些特征称为主成分。我们必须选择我们希望看到的主成分的数量。我们在我关于KMeans集群的文章中讨论了减少特性,我强烈建议您看一看(链接)。

    ​ 首先,我们需要确定适当的主成分数量。3个主成分似乎占了大约75%的方差。

    pca = PCA(n_components=7)
    pca.fit(df_scale)
    variance = pca.explained_variance_ratio_ var=np.cumsum(np.round(variance, 3)*100)
    plt.figure(figsize=(12,6))
    plt.ylabel('% Variance Explained')
    plt.xlabel('# of Features')
    plt.title('PCA Analysis')
    plt.ylim(0,100.5)plt.plot(var)
    

    ​ 现在我们知道了维持一个特定百分比的方差所需的主成分的数量,让我们对原始数据集应用一个3成分的主成分分析。请注意,第一个主成分占到与原始数据集方差的26%。在本文的其余部分中,我们将使用“pca_df”数据框架。

    pca = PCA(n_components=3)
    pca.fit(df_scale)
    pca_scale = pca.transform(df_scale)pca_df = pd.DataFrame(pca_scale, columns=['pc1', 'pc2', 'pc3'])
    print(pca.explained_variance_ratio_)
    

    ​ 在3D空间中绘制数据,可以看到DBSCAN存在一些潜在的问题。DBSCAN的一个主要缺点就是它不能准确地对不同密度的数据进行聚类,从下面的图中,我们可以看到两个不同密度的单独集群。在应用DBSCAN算法时,我们可能能够在数据点较少的聚类结果中找到不错的聚类方式,但在数据点较多的聚类中的许多数据点可能被归类为离群值/噪声。这当然取决于我们对epsilon和最小点值的选择。

    Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(colorscale='Greys', opacity=0.3, size = 10, ))
    layout = go.Layout(margin=dict(l=0,r=0),scene = Scene, height = 1000,width = 1000)
    data = [trace]
    fig = go.Figure(data = data, layout = layout)
    fig.show()
    

    3.DBSCAN聚类

    方法1

    ​ 在应用聚类算法之前,我们必须使用前面讨论过的“肘形法”来确定合适的epsilon级别。看起来最佳的值在0.2左右。最后,由于我们的数据有3个主成分,我们将把最小点标准设置为6。

    plt.figure(figsize=(10,5))
    nn = NearestNeighbors(n_neighbors=5).fit(pca_df)
    distances, idx = nn.kneighbors(pca_df)
    distances = np.sort(distances, axis=0)
    distances = distances[:,1]
    plt.plot(distances)
    plt.show()
    

    ​ 将epsilon设置为0.2,将min_samples设置为6,得到了53个集群,影像分数为-0.521,以及超过1500个被认为是离群值/噪声的数据点。在某些研究领域,53个集群可能被认为是有用的,但我们有一个15000名员工的数据集。从业务的角度来看,我们需要一些可管理的集群(即3-5个),以便更好地分配工作场所。此外,剪影得分-0.521表明数据点是不正确的聚集。

    ​ 看看下面的3D图,我们可以看到一个包含了大多数数据点的集群。出现了一个较小但很重要的聚类簇,但剩下52个聚类簇的规模要小得多。从业务角度来看,这些集群提供的信息不是很多,因为大多数员工只属于两个集群。组织希望看到几个大的集群,以确定它们的有效性,但也能够从事一些针对集群员工的组织主动性工作(例如。增加培训、薪酬变化等)。

    db = DBSCAN(eps=0.2, min_samples=6).fit(pca_df)
    labels = db.labels_# Number of clusters in labels, ignoring noise if present.
    n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
    n_noise_ = list(labels).count(-1)print('Estimated number of clusters: %d' % n_clusters_)
    print('Estimated number of noise points: %d' % n_noise_)
    print("Silhouette Coefficient: %0.3f" % metrics.silhouette_score(pca_df, labels))
    

    Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))labels = db.labels_trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color = labels, colorscale='Viridis', size = 10, line = dict(color = 'gray',width = 5)))
    layout = go.Layout(scene = Scene, height = 1000,width = 1000)
    data = [trace]
    fig = go.Figure(data = data, layout = layout)fig.update_layout(title='DBSCAN clusters (53) Derived from PCA', font=dict(size=12,))
    fig.show()
    
    Image for post
    

    方法2

    ​ 我们不使用“肘部方法”和最小值启发式方法,而是使用迭代方法来微调我们的DBSCAN模型。在对数据应用DBSCAN算法时,我们将迭代一系列的epsilon和最小点值。

    ​ 在我们的例子中,我们将迭代0.5到1.5之间的epsilon值和2-7之间的minPts。for循环将使用这组值运行DBSCAN算法,并为每次迭代生成集群数量和影像分数。请记住,您需要根据数据调整参数。您可能会在一组参数上运行此代码,并发现产生的最佳影像分数是0.30。为了将更多的点包含到一个集群中,您可能需要增加值。

    pca_eps_values = np.arange(0.2,1.5,0.1) 
    pca_min_samples = np.arange(2,5) 
    pca_dbscan_params = list(product(pca_eps_values, pca_min_samples))pca_no_of_clusters = []
    pca_sil_score = []
    pca_epsvalues = []
    pca_min_samp = []for p in pca_dbscan_params:
        pca_dbscan_cluster = DBSCAN(eps=p[0], min_samples=p[1]).fit(pca_df)
        pca_epsvalues.append(p[0])
        pca_min_samp.append(p[1])pca_no_of_clusters.append(
    len(np.unique(pca_dbscan_cluster.labels_)))
        pca_sil_score.append(silhouette_score(pca_df, pca_dbscan_cluster.labels_))pca_eps_min = list(zip(pca_no_of_clusters, pca_sil_score, pca_epsvalues, pca_min_samp))pca_eps_min_df = pd.DataFrame(pca_eps_min, columns=['no_of_clusters', 'silhouette_score', 'epsilon_values', 'minimum_points'])pca_ep_min_df
    

    ​ 我们可以看到,通过我们的epsilon和minPts的迭代,我们已经获得了很大范围的簇数和影像分数。0.9到1.1之间的epsilon分数开始产生可管理的集群数量。将epsilon增加到1.2或更高会导致集群数量太少,无法在商业上发挥作用。此外,其中一些集群可能只是噪音。我们稍后会讲到。

    ​ 增加的epsilon会减少集群的数量,但每个集群也会开始包含更多的离群点/噪声数据点,这一点也可以理解为有一定程度的收益递减。

    ​ 为了简单起见,让我们选择7个集群并检查集群分布情况。(epsilon: 1.0和minPts: 4)。

    ​ 同样重要的是,运行此代码串时肯定会遇到的一个常见错误。有时,当你设置的参数不合适,for循环最终会变成eps_values和min_samples的组合,这只会产生一个集群。但是,silhouette ette_score函数至少需要定义两个集群。您需要限制参数以避免此问题。

    ​ 在上面的示例中,如果我们将epsilon参数的范围设置为0.2到2.5,那么很可能会生成一个集群并最终导致错误。

    ​ 你可能会问自己“我们不是应该获得7个集群吗?”答案是肯定的,如果我们看一下独特的标签/集群,我们看到每个数据点有7个标签。根据Sklearn文档,标签“-1”等同于一个“嘈杂的”数据点,它还没有被聚集到6个高密度的集群中。我们自然不希望将任何“-1”标签考虑为一个集群,因此,它们将从计算中删除。

    db = DBSCAN(eps=1.0, min_samples=4).fit(pca_df)
    labels = db.labels_# Number of clusters in labels, ignoring noise if present.
    n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
    n_noise_ = list(labels).count(-1)print('Estimated number of clusters: %d' % n_clusters_)
    print('Estimated number of noise points: %d' % n_noise_)
    print("Silhouette Coefficient: %0.3f" % silhouette_score(pca_df, labels))
    

    set(labels)
    

    ​ 从6个DBSCAN派生集群的3D图中可以看出,尽管密度较小,但位于图顶端的密度较小的集群对DBSCAN并没有造成太大影响。如果您还记得的话,DBSCAN很难正确地集群各种密度的数据。顶部的集群和更大的底部集群之间的距离很可能大于1.0的epsilon值。

    ​ 也就是说,数据集包含额外的高密度集群,但是我们的epsilon和minPts太大了。底部的聚类簇包含至少两个高密度的聚类簇,然而,由于底部聚类簇的高密度降低了epsilon和minPts,只会产生许多更小的聚类簇。这也是DBSCAN的主要缺点。我一直认为DBSCAN需要第三个参数“min_core”,它将确定一个集群可以被视为有效集群之前的最小核心点数量。

    Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))# model.labels_ is nothing but the predicted clusters i.e y_clusters
    labels = db.labels_trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color = labels, colorscale='Viridis', size = 10, line = dict(color = 'gray',width = 5)))
    layout = go.Layout(scene = Scene, height = 1000,width = 1000)
    data = [trace]
    fig = go.Figure(data = data, layout = layout)fig.update_layout(title="'DBSCAN Clusters (6) Derived from PCA'", font=dict(size=12,))
    fig.show()
    

    ​ 在我们开始之前,让我们快速了解一下每个集群中的员工数量。似乎cluster 0包含了大部分信息不太丰富的数据点。事实上,如果我们使用0.5的epsilon值和5的minPts运行算法,就会产生63个集群,集群0仍然会包含99%的员工人口。

    np.unique(labels, return_counts=True)
    

    小结

    ​ DBSCAN,一种密度聚类算法,常用于非线性或非球面数据集。epsilon和minPts是两个必需的参数。epsilon是附近数据点的半径,这些数据点需要被认为是足够“相似”才能开始聚类。最后,minPts是需要在半径内的数据点的最小数目。

    ​ 在我们的示例中,我们试图根据工作特征对包含15,000名员工的数据集进行聚类。我们首先标准化了数据集以缩放特征。接下来,我们应用主成分分析将维度/特征的数量减少到3个主成分。使用“肘部法”,我们估计了0.2的epsilon值和6的minPts。使用这些参数,我们能够获得53个集群,1500个离群值和-0.52的影响分数。不用说,结果并不是很理想。

    ​ 接下来,我们尝试了一种迭代的方法来微调epsilon和minPts。我们已经确定了epsilon值为1.0和minPts值为4。该算法返回6个有效的集群(一个-1集群),只有7个异常值,以及0.46的可观影像分数。然而,在绘制派生集群时,发现第一个集群包含99%的员工。从业务的角度来看,我们希望我们的集群能够更加均衡地分布,从而为我们提供关于员工的良好见解。

    ​ DBSCAN似乎不是这个特定数据集的最佳聚类算法。

    作者:Kamil Mysiak

    deephub翻译组:孟翔杰

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,764
精华内容 3,905
关键字:

dbscan聚类