密度聚类DBSCAN原理及代码实现

1、密度聚类及DBSCAN

密度聚类:密度聚类算法,即基于密度的聚类,此类算法假设聚类结构能通过样本分布的紧密程度确定。通常,密度聚类算法从样本密度的角度来考察样本之间的可连接性,并基于可连接样本不断拓展聚类簇以获得最终的聚类结果。

DBSCAN是典型的密度聚类算法,它基于一组“邻域”参数(ϵ,MinPts)来刻画样本分布的紧密程度。邻域参数有何用呢?它其实限定了聚类簇的规模大小至少为MinPts,若样本点xϵ至少包含MinPts个样本,则称其为“核心对象”。DBSCAN算法簇是由密度可达关系导出的最大的密度相连的样本集合。何谓密度可达呢?要说清密度可达,就必须牵涉密度直达以及密度相连等概念,详细定义可以参考周志华老师的《机器学习》。我的理解是,若样本点x1密度可达x2,则x1可借助一系列样本点到达x2,而这些点顺次之间的距离是小于ϵ的。

所以寻找聚类簇的一种朴素方法是:考虑核心对象x,由x密度可达的所有样本点组成的集合即为一簇(注意,可能包含其他的核心对象),然后排除核心对象队列中已有聚类簇的核心对象,重复上一过程得到其他聚类簇。

2、Matlab程序

function [k,C] = DBSCAN(D)
%D = rand(2, 30);                       %样本集

eps = 0.11;                            %邻域参数
MinPts = 5;                            %领域参数
O = zeros(1, size(D, 2));              %核心对象集
C = cell(size(D,2));

d = zeros(size(D, 2), size(D, 2));     %样本之间的距离大于eps元素值为1,反之0
for i = 1:size(D, 2)
    for j = size(D, 2):-1:i
        if pdist(D(:, [i j])') <= eps
            d(i, j) = 1;
        end
        d(j, i) = d(i, j);
    end
    %d(i,i) = 0;
    if sum(d(i, :)) >= MinPts
            O(i) = i;
    end
end

k =  0;                                %初始化聚类簇数
Tau = 1:size(D, 2);                    %初始化未访问样本集合
while sum(O) ~= 0
    Tau_old = Tau;                     %记录当前未访问样本集合

    %随机选取一个核心对象j,找出其密度可达点
    j = 1;
    while O(j) == 0
        j = j+1;
    end

    %ob = O(j);
    Q = zeros(1, size(Tau, 2));
    Q(j) = j;                          %将核心对象j加入队列Q
    Tau(j) = 0;                        %将核心对象j移出Tau

    while sum(Q) ~= 0

        %取出Q中首个样本m
        m = 1;
        while Q(m) == 0
            m = m+1;
        end
        Q(m) = 0;

        if sum(d(m,:)) >= MinPts
            for l = 1:size(d, 2)
                if d(m, l) == 1 && Tau(l) ~= 0
                    Q(l) = l;
                    Tau(l) = 0;
                end
            end
        end

    end
    k = k+1;
    for i = 1:size(Tau, 2)
        if Tau(i) ~= 0
            Tau_old(i) = 0;
        end
        if Tau_old(i) ~= 0
            O(i) =0;
        end
    end
    C{k} = Tau_old;
end

for i = 1:k
    C{i} = find(C{i}~=0);
    C{i}
    D1 = D(:,C{i});
    scatter(D1(1,:),D1(2,:));
    hold on
end

运行结果:
当D为西瓜数据集4.0(见周志华老师的《机器学习》P202),聚类结果如下:
这里写图片描述


本文参考自周志华老师的《机器学习》.

展开阅读全文

没有更多推荐了,返回首页