DBSCAN基于密度的聚类算法

**DBSCAN算法和实现

——DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法,它是一种适应性极强的聚类算法,不同于K-means聚类,它无需确定簇的数量k,可以自己基于密度来实现。首先介绍一下几个基本的概念。

基础概念

1.密度:密度指的是在某距离内含有对象的最小数目。
2.核心对象:如果一个对象的eps邻域内至少包含MinPt个对象,则称该对象是核心对象。
3.直接密度可达:给定一个对象集合D,如果p在q的eps邻域内,并且q是一个核心对象,则p是从q直接密度可达的。(如下图所示),eps可以想象为一个超球体的半径,Minp就是这个超球体内的点,这样比较容易理解。

直接密度可达
4.密度可达:对于q和p之间,有一个样本序列p1,p2,p3,……,pn, 其中p1=q, pn=p,若Pi+1是由Pi直接密度可达的(关于eps和MinPts),则对象p是由q关于eps和MinPts密度可达的。(如下图所示)
密度可达

算法介绍

在DBSCAN算法中,一个簇就是从一个点出发,所有密度可达的点的集合,如果某一个点不属于任何一个簇,也就是说这个点不能由任何点密度可达,那么这个点被称为异常点。
算法流程:
1、输入:样本D={x1, x2, x3,……., xm},邻域参数(eps,MinPts),距离的度量方式(本文中我们用欧几里得距离来介绍,事实上大部分时候也用的是欧几里得距离方法)
2、输出:簇划分、异常点索引

算法实现:
1、初始化聚类的簇数K=0,已访问样本对象VT为空,分类结果result为空,异常索引noise为空。
2、遍历m的样本对象,判断其是否为核心对象,若不是核心对象,在索引对应的VT中标记为1,表示该对象已访问。如果是核心对象,则聚类簇数K=K+1,并且找到它的领域内的所有对象,标记已访问,遍历每一个邻域中的点,且在result矩阵中,所有密度可达的对象对应的索引位置都赋予K值。
3、对result矩阵取反,就是noise矩阵。也就是说result矩阵中,值为0的位置说明对应的样本不属于任何簇,是异常的。

源代码

总之,说的有点简单,具体见源码如下。

function [result, noncore,noise] = dbscan(SetOfPoints, eps, minPts) 

    cluster = 0;
    sizeOfCell = size(SetOfPoints,1);
    result = zeros(sizeOfCell,1);

%欧氏距离矩阵Dmatrix,对应于各个样本点之间的距离。
    Dmatrix = pdist2(SetOfPoints,SetOfPoints);
%初始化已访问样本和噪声样本。
    visited = false(sizeOfCell,1);
    noncore = false(sizeOfCell,1);


    for index = 1 : sizeOfCell
        if visited(index) == false
            visited(index) = true;%已访问标记。

            Neighbors = regionQuery(index, eps);
            if numel(Neighbors) < minPts
                noncore(index) = true;
            else
                cluster = cluster + 1;
                ExpandCluster(index, Neighbors, cluster, eps, minPts)%找出所有密度可达的点,归于cluster类。
            end  
        end
    end

    function ExpandCluster(index, Neighbors, cluster, eps, minPts)
        result(index) = cluster;
        temp = 1;

        while true
            neighbor = Neighbors(temp); 
            if visited(neighbor) == false
                visited(neighbor) = true;
                NeighborsSecond = regionQuery(neighbor, eps);
                if numel(NeighborsSecond) >= minPts
                   Neighbors = [Neighbors NeighborsSecond]; %密度可达点的索引扩展
                end
            end

            if result(neighbor) == 0
                result(neighbor) = cluster;

            end

            temp = temp + 1;
            if temp > numel(Neighbors)
                break;
            end
        end
    end

    function Neighbors = regionQuery(i, eps)
        Neighbors = find(Dmatrix(i,:)<=eps);%返回Dmatrix矩阵中第i行,小于eps的索引。
    end
 noise=~result;
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值