基于密度的聚类算法

基于密度的聚类算法(也叫做密度聚类算法)假设聚类结构能通过样本分布的紧密程度确定。在通常情况下,基于密度的聚类算法从样本密度的角度来考察样本之间的可连接性,并基于可连接样本不断扩展聚类簇以获得最终的聚类结果。DBSCAN是一种典型的基于密度的聚类算法。

基于上述概念,DBSCAN将簇的定义为:由密度可达关系导出的最大的密度相连样本集合。DBSCAN聚类算法伪代码如下所示。

仿真结果及Matlab主要代码

下图是使用DBSCAN算法的聚类结果图。图1是设定生成的数据点,图2是聚类结果图。

原始数据分布

聚类结果

Matlab代码实现(主要函数):

main函数:

clear all; close all; clc; 

%% 生成测试数据

theta = 0:0.01:2*pi;

d1 = [3*cos(theta) +rand(1,length(theta))/2;3*sin(theta)+ rand(1,length(theta))/2];

d2 = [2*cos(theta) +rand(1,length(theta))/2;2*sin(theta)+ rand(1,length(theta))/2];

d3 = [cos(theta) +rand(1,length(theta))/2;sin(theta)+ rand(1,length(theta))/2];

d = [d1 d2 d3]'; 

randIndex = randperm(length(d))';

d = d(randIndex,:);

figure(1)

plot(d(:,1),d(:,2),'.')  %原始数据画图

epsilon = threshold_calculate(d);  %计算epsilon

MinPts = 5;

IDX1 = DBSCAN(d,epsilon,MinPts);   %利用DBSCAN聚类

figure(2)

plot_clusterin_result(d,IDX1);     %画出结果图

 

threshold_calculate阈值计算函数

function threshold = threshold_calculate(d)

%% KNN k距离图,确定ε

N = size(d,1);

M = 1000;

ratio = 0.007;

Kdist = zeros(M,1);

[~,Dist] = knnsearch(d(2:end,:),d(1,:)); %d(2:numData,:)找到和A(1,:)最相似的行

Kdist(1) = Dist;

for i = 2:M

    [~,Dist]= knnsearch(d([1:i-1,i+1:end],:),d(i,:));

    Kdist(i)= Dist;

end

[sortKdist,~] = sort(Kdist,'descend');

threshold = sortKdist(round(M*ratio));

 

DBSCAN聚类函数

function [IDX,isnoise] = DBSCAN(A,epsilon,MinPts)

C = 0;

n = size(A,1);

IDX = zeros(n,1);

D = pdist2(A,A);   %计算(A,A)的行的距离

visited = false(n,1);

isnoise = false(n,1);

for i = 1:n

    if~visited(i)

       visited(i) = true;

       Neighbors = find(D(i,:) <= epsilon);

        ifnumel(Neighbors) < MinPts    %X(i,:)是噪声,标为0

           isnoise(i) = true;

        else

            C= C+1;    %对簇进行扩展

           IDX(i) = C;

            k= 1;

           while true

               j = Neighbors(k);

               if ~visited(j)

                   visited(j) = true;

                   Neighbors2 = find(D(j,:) <= epsilon);

                   if numel(Neighbors2) >= MinPts

                        Neighbors = [NeighborsNeighbors2];

                   end

               end

               if IDX(j) == 0

                   IDX(j) = C;

               end

               k = k + 1;

               if k > numel(Neighbors)

                   break;

               end

           end

        end

    end

end


©著作权归作者所有:来自51CTO博客作者mob604756f3c518的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 机器学习算法之BIRCH
  2. 基于几种分类算法的帕金森数据分类
  3. EM-EKF参数估计算法
  4. “手撕”BP算法——使用MATLAB搭建简单的神经网络(附代码)
  5. 聚类分析算法对文本分类之分词和构建词袋模型
  6. 算法的秘密+
  7. 解读:什么是Java的递归算法?
  8. 老调重弹篇:有关BC/C++语言程序编程学习的:10大基础算法科普帖
  9. 设计思想赏析-基因算法

随机推荐

  1. 1.4.6 收集sql语句的执行计划 2
  2. Python MySQLdb连接数据库的应用
  3. Effective MySQL之深入解析复制技术
  4. 在arcpy中删除或删除表的代码是什么?
  5. oracle11g 创建id自增长监听器的步骤
  6. 在SQL SELECT语句中重用别名字段
  7. 用javabean连接sql server 2000数据库报
  8. CentOS下MySQL主从同步配置 ​Slave_IO_R
  9. 使用IN语句缓慢mysql删除查询
  10. mysql的replace的使用