DBSCAN密度聚类

1. 密度聚类概念

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种很典型的密度聚类算法,和K-Means,BIRCH这些一般只适用于凸样本集的聚类相比,DBSCAN既可以适用于凸样本集,也可以适用于非凸样本集。

2. 密度聚类步骤

DBSCAN算法描述:

输入: 包含n个对象的数据库,半径e,最少数目MinPts;

输出:所有生成的簇,达到密度要求。

(1)Repeat

(2)从数据库中抽出一个未处理的点;

(3)IF抽出的点是核心点 THEN 找出所有从该点密度可达的对象,形成一个簇;

(4)ELSE 抽出的点是边缘点(非核心对象),跳出本次循环,寻找下一个点;

(5)UNTIL 所有的点都被处理。

DBSCAN对用户定义的参数很敏感,细微的不同都可能导致差别很大的结果,而参数的选择无规律可循,只能靠经验确定。

这个算法的关键是理解几个概念:

  • 直接密度可达
  • 密度可达
  • 核心点
  • 边界点
  • 噪声点

理解这些概念的一个资料:ppt

3. python实现

思路:首先找出所有核心点,核心点就是那些在半径e以内的邻域中有>=MinPts个点的点。注意:核心点以内的所有点都与核心点为同一类!  所以如果某两类点集中有一个点为重复,那他们应该合并为一类!举例:类别1:[1,2,4,6,8],类别2:[3,6,7,9,10,99]。这两个集合最初是两个类别,但是因为有共同点6,那么他俩应当合并为1类。所以这个算法就很简单了,代码步骤如下:

1)求出所有点的距离矩阵dis=[n,n], n为数据的个数。

2)如果e取值为3,那么dis的每一行中>3的所有点个数的和只要>MinPts,则为1个类别。

3)所有这些类别进行重复检查,只要有重复值则合并,直到没有重复。

4)这些没有重复的类别就是最终形成的类别。

简单说明:

代码:

# coding:utf-8
"""
@author = LPS
"""
import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt(‘moon.txt‘)
n,m = data.shape
all_index = np.arange(n)
dis = np.zeros([n,n])
data = np.delete(data, m-1, axis=1)

def dis_vec(a,b):    # 计算两个向量的距离

    if len(a)!=len(b):
        return Exception
    else:
        return np.sqrt(np.sum(np.square(a-b)))

for i in range(n):   # 计算距离矩阵
    for j in range(i):
        dis[i,j] = dis_vec(data[i],data[j])
        dis[j,i] = dis[i,j]

def dbscan(s, minpts):   # 密度聚类

    center_points = []   # 存放最终的聚类结果
    k = 0  # 检验是否进行了合并过程

    for i in range(n):
        if sum(dis[i] <= s) >= minpts:   # 查看距离矩阵的第i行是否满足条件
            if len(center_points) == 0:  # 如果列表长为0,则直接将生成的列表加入
                center_points.append(list(all_index[dis[i] <= s]))
            else:
                for j in range(len(center_points)):   # 查找是否有重复的元素
                    if set(all_index[dis[i] <= s]) & set(center_points[j]):
                        center_points[j].extend(list(all_index[dis[i] <= s]))
                        k=1   # 执行了合并操作
                if k==0 :
                    center_points.append(list(all_index[dis[i] <= s]))  # 没有执行合并说明这个类别单独加入
                k=0

    lenc =  len(center_points)

    # 以下这段代码是进一步查重,center_points中所有的列表并非完全独立,还有很多重复
    # 那么为何上面代码已经查重了,这里还需查重,其实可以将上面的步骤统一放到这里,但是时空复杂的太高
    # 经过第一步查重后,center_points中的元素数目大大减少,此时进行查重更快!
    k = 0
    for i in range(lenc-1):
        for j in range(i+1, lenc):
            if set(center_points[i]) & set(center_points[j]):
                center_points[j].extend(center_points[i])
                center_points[j] = list(set(center_points[j]))
                k=1

        if k == 1:
            center_points[i] = []   # 合并后的列表置空
        k = 0

    center_points = [s for s in center_points if s != []]   # 删掉空列表即为最终结果

    return center_points

if __name__ == ‘__main__‘:
    center_points = dbscan(0.2,10)  # 半径和元素数目
    c_n = center_points.__len__()   # 聚类完成后的类别数目
    print (c_n)
    ct_point = []
    color = [‘g‘,‘r‘,‘b‘,‘m‘,‘k‘]
    noise_point = np.arange(n)      # 没有参与聚类的点即为噪声点
    for i in range(c_n):
        ct_point = list(set(center_points[i]))
        noise_point = set(noise_point)- set(center_points[i])
        print (ct_point.__len__())   # 输出每一类的点个数
        print (ct_point)             # 输出每一类的点
        print ("**********")

    noise_point = list(noise_point)

    for i in range(c_n):
        ct_point = list(set(center_points[i]))
        plt.scatter(data[ct_point,0], data[ct_point,1], color=color[i])       # 画出不同类别的点
    plt.scatter(data[noise_point,0], data[noise_point,1], color=color[c_n], marker=‘h‘, linewidths=0.1)   # 画噪声点
    plt.show() 

DBSCAN的主要优点有:

    1) 可以对任意形状的稠密数据集进行聚类,相对的,K-Means之类的聚类算法一般只适用于凸数据集。

    2) 可以在聚类的同时发现异常点,对数据集中的异常点不敏感。

    3) 聚类结果没有偏倚,相对的,K-Means之类的聚类算法初始值对聚类结果有很大影响。

DBSCAN的主要缺点有:

    1)如果样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合。

    2) 如果样本集较大时,聚类收敛时间较长,此时可以对搜索最近邻时建立的KD树或者球树进行规模限制来改进。

    3) 调参相对于传统的K-Means之类的聚类算法稍复杂,不同的参数组合对最后的聚类效果有较大影响。

实验:

原图                                                   square4  e=0.85  minpts = 13                                            square4-sklearn e=0.9 minpts=15

                       

原图                                                                                                                         结果图

  

原图                                                                       square1 1.185,8                                                                square1   0.85 15

         

原图                                                                                            结果图

       

原图                                                                                                                   结果图

实验过程中:前几幅图由于分布比较密集,参数调整要很多次,后几张图因为分布比较分散,所以参数基本一次设置成功。

结果和资料已上传,下载~~~

时间: 2024-11-13 12:51:15

DBSCAN密度聚类的相关文章

DBSCAN密度聚类算法

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种很典型的密度聚类算法,和K-Means,BIRCH这些一般只适用于凸样本集的聚类相比,DBSCAN既可以适用于凸样本集,也可以适用于非凸样本集.下面我们就对DBSCAN算法的原理做一个总结. 1. 密度聚类原理 DBSCAN是一种基于密度的聚类算法,这类密度聚类算法一般假定类别可以通过样本分布的紧密程度决定.同一类别的样本,他们

数据挖掘导论:2、密度聚类

密度聚类知识介绍:参见了这篇文章http://blog.csdn.net/uestcfrog/article/details/6876360 定义: 1.      对于空间中的一个对象,如果它在给定半径e的邻域中的对象个数大于密度阀值MinPts,则该对象被称为核心对象,否则称为边界对象. 2.      如果p是一个核心对象,q属于p的邻域,那么称p直接密度可达q. 3.      如果存在一条链<p1,p2,-..,pi>,满足p1=p,pi=q,pi直接密度可达pi+1,则称p密度可达

基于密度聚类的DBSCAN算法

根据各行业特性,人们提出了多种聚类算法,简单分为:基于层次.划分.密度.图论.网格和模型的几大类. 其中,基于密度的聚类算法以DBSCAN最具有代表性. 假设有如下图的一组数据, 生成数据的R代码如下 x1 <- seq(0,pi,length.out=100) y1 <- sin(x1) + 0.1*rnorm(100) x2 <- 1.5+ seq(0,pi,length.out=100) y2 <- cos(x2) + 0.1*rnorm(100) data <- da

ML: 聚类算法R包 - 密度聚类

密度聚类 fpc::dbscan fpc::dbscan DBSCAN核心思想:如果一个点,在距它Eps的范围内有不少于MinPts个点,则该点就是核心点.核心和它Eps范围内的邻居形成一个簇.在一个簇内如果出现多个点都是核心点,则以这些核心点为中心的簇要合并.其中要注意参数eps的设置,如果eps设置过大,则所有的点都会归为一个簇,如果设置过小,那么簇的数目会过多.如果MinPts设置过大的话,很多点将被视为噪声点(先计算距离矩阵,然后看一下距离大概都是多少,找个靠谱的设置成半径) 优点: 对

【机器学习】---密度聚类从初识到应用

一.前述 密度聚类是一种能降噪的算法. 二.相关概念 先看些抽象的概念(官方定义): 1.:对象O的是与O为中心,为半径的空间,参数,是用户指定每个对象的领域半径值. 2.MinPts(领域密度阀值):对象的的对象数量. 3.核心对象:如果对象O的对象数量至少包含MinPts个对象,则该对象是核心对象. 4.直接密度可达:如果对象p在核心对象q的内,则p是从q直接密度可达的. 5.密度可达:在DBSCAN中,p是从q(核心对象)密度可达的,如果存在对象链,使得,是从关于和MinPts直接密度可达

密度聚类

·统计样本周边的密度,把密度给定一个阈值,不断的把样本添加到最近的簇.例如:人口密度,根据密度,聚类出城市 ·解决类似圆形的K-Means聚类的特点:密度聚类缺点:计算复杂度大,空间索引来降低计算时间,降低查找速度. (DBSCAN算法): 参数:DBSCAN(eps=0.5, min_samples=5, metric='euclidean', algorithm='auto', leaf_size=30, p=None, n_jobs=1) eps:两个样本之间的最大距离,即扫描半径min_

聚类算法--K-means和k-mediods/密度聚类/层次聚类

目录 简述 K-means聚类 密度聚类 层次聚类 一.简述 聚类算法是常见的无监督学习(无监督学习是在样本的标签未知的情况下,根据样本的内在规律对样本进行分类). 在监督学习中我们常根据模型的误差来衡量模型的好坏,通过优化损失函数来改善模型.而在聚类算法中是怎么来度量模型的好坏呢?聚类算法模型的性能度量大致有两类: 1)将模型结果与某个参考模型(或者称为外部指标)进行对比,个人觉得认为这种方法用的比较少 2)另一种是直接使用模型的内部属性,比如样本之间的距离(闵可夫斯基距离)来作为评判指标,这

【ML-7】聚类算法--K-means和k-mediods/密度聚类/层次聚类

目录 简述 K-means聚类 密度聚类 层次聚类 一.简述 聚类算法是常见的无监督学习(无监督学习是在样本的标签未知的情况下,根据样本的内在规律对样本进行分类). 在监督学习中我们常根据模型的误差来衡量模型的好坏,通过优化损失函数来改善模型.而在聚类算法中是怎么来度量模型的好坏呢?聚类算法模型的性能度量大致有两类: 1)将模型结果与某个参考模型(或者称为外部指标)进行对比,个人觉得认为这种方法用的比较少 2)另一种是直接使用模型的内部属性,比如样本之间的距离(闵可夫斯基距离)来作为评判指标,这

一种简化的密度聚类方法

先说一下什么是密度聚类的方法 参考文章:基于密度的聚类 这篇文章的大概意思通过一幅图来说明: 1 首先任意选定一个点假设就以图中最左边的h为第一个点,根据半径判断,在一定的范围内点的个数是否满足要求. -如果满足把这个点标记为核心点,这个圆判定为一个聚类. -如果不是,就把这个点判定为边界点,标记为噪声:在随机选取一个点. 2 确定这一类,依次判断这个圆内的点的属性(核心,边界). 3 如果还有没有被标记的点,在任意选取一个点从上面开始做,一直到标记完所有的点. 优点: 1 对噪声不敏感. 2