基于密度的聚类算法DBscan

基于密度的聚类算法 DBscan

基于密度的聚类算法的结果是球状的簇

基于密度的聚类算法的结果可以是任意形状,这有利于处理带有噪音点的数据

DBscan 相关概念

  • 点P的邻接半径 eps : 以点P为中心,以 eps 为半径

  • 点P的eps邻域 : 与点P的距离 <= eps的所有点的集合

  • 密度域值 minPts :指定的一个数,表示最小的点的个数,它刻画了最小的密度情况,过滤掉密度稀疏的点

  • 核心点 : 点 P 的eps 领域点的个数 >= minPts ,则 P 称为核心点

  • 边界点 :点 Q 的eps 领域点的个数 < minPts ,但是 Q 落在某个核心点 P 的eps邻域内,则点 Q 称为边界点

  • 噪音点 :点 R 既不是核心点也不是边界点,则 R 称为噪音点

  • 直接密度可达 : 点 q 在点 p 的 eps 邻域内,则称 q 从 p 出发是直接密度可达
  • 密度可达 : 对于对象链 P1,P2,……,Pn , 若 Pi+ z1 从 Pi 出发直接密度可达,则 Pn 从 P1 出发密度可达(传递性,间接密度可达)

DBscan 算法思想

判断两点之间是否直接密度可达
def eps_neighborhood(a, b, eps):
    return dist(a, b) < eps
求某点的 eps 邻域
def region_query(dataSet, point_id, eps):
    n_points = dataSet.shape[1] #shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度
    seeds = []
    for i in range(0, n_points):
        if eps_neighborhood(dataSet[:, point_id], dataSet[:, i], eps):
            seeds.append(i)
    return seeds
为核心对象聚类并合并
 合并两个存在密度相连的元素的集合
def expand_cluster(dataSet, clusterResults, point_id, cluster_id, eps, minPts):

    seeds = region_query(dataSet, point_id, eps)
    if len(seeds) < minPts:
        clusterResults[point_id] = NOISE #标为噪音点
        return False
    else:
        clusterResults[point_id] = cluster_id #划分到该簇
        for seed_id in seeds:
            clusterResults[seed_id] = cluster_id #该点的eps邻域也划分到该簇

        while len(seeds) > 0: # 持续扩张,seeds里面的点的eps邻域一定与当前簇有密度可达的点,合并簇
            current_point = seeds[0]
            expand_seeds = region_query(dataSet, current_point, eps)
            if len(expand_seeds) >= minPts: #如果 current_point是核心点
                for expand_id in range(0, len(expand_seeds)):
                    result_point = expand_seeds[expand_id]
                    if clusterResults[result_point] == UNCLASSIFIED: #未分类的类做我的seed
                        seeds.append(result_point)
                        clusterResults[result_point] == cluster_id
                    elif clusterResults[result_point] == NOISE: #已分类的类与我合并
                        clusterResults[result_point] == cluster_id
            seeds = seeds[1:]
        return True
DBscan输出聚类结果
def dbscan(dataSet, eps, minPts):
    cluster_id = 1
    n_points = dataSet.shape[1]
    clusterResults = [UNCLASSIFIED] * n_points
    for point_id in range(0, n_points):
        point = dataSet[:, point_id]
        if clusterResults[point_id] == UNCLASSIFIED:
            if expand_cluster(dataSet, clusterResults, point_id, cluster_id, eps, minPts):
                cluster_id = cluster_id + 1
    return clusterResults, cluster_id - 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值