ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

matlab练习程序(DBSCAN)

2019-07-12 20:56:48  阅读:267  来源: 互联网

标签:rand DBSCAN 练习 flag length matlab 聚类 theta 数据


DBSCAN全称Density-Based Spatial Clustering of Applications with Noise,是一种密度聚类算法。

和Kmeans相比,不需要事先知道数据的类数。

以编程的角度来考虑,具体算法流程如下:

1.首先选择一个待处理数据。

2.寻找和待处理数据距离在设置半径内的数据。

3.将找到的半径内的数据放到一个队列中。

4.拿队列头数据作为当前待处理数据并不断执行第2步。

5.直到遍历完队列中所有数据,将这些数据记为一类。

6.选择没有处理到的数据作为一个待处理数据执行第2步。

7.直到遍历完所有数据,算法结束。

大概就是下图所示的样子:

我这里没有单独输出离群点,不过稍微改进增加离群点个数判断阈值应该就可以,比较容易修改。

代码如下:

clear all;
close all;
clc;

theta=0:0.01:2*pi;
p1=[3*cos(theta) + rand(1,length(theta))/2;3*sin(theta)+ rand(1,length(theta))/2];      %生成测试数据
p2=[2*cos(theta) + rand(1,length(theta))/2;2*sin(theta)+ rand(1,length(theta))/2];
p3=[cos(theta) + rand(1,length(theta))/2;sin(theta)+ rand(1,length(theta))/2];
p=[p1 p2 p3]';

randIndex = randperm(length(p))';       %打乱数据顺序
p=p(randIndex,:);
plot(p(:,1),p(:,2),'.')

flag = zeros(length(p),1);      %聚类标记
clsnum = 0;                     %类的个数
disnear = 0.3;                 %聚类半径

for i=1:length(p)   
    nxtp = p(i,:);      %初始聚类半径内的邻域点队列
    if flag(i)==0
        clsnum = clsnum+1;
        pcstart = 1;            %设置队列起始指针
        preflag = flag;         %聚类标记更新
        while pcstart<=length(nxtp)         %判断是否完成队列遍历
            curp = nxtp(pcstart,:);         %得到当前要处理的点
            pcstart = pcstart+1;            %队列指针更新
            diffp = p-curp;                 %这里直接和所有数据比较了,数据量大的时候可以考虑kdtree
            dis = sqrt(diffp(:,1).*diffp(:,1)+diffp(:,2).*diffp(:,2));      %判断当前点与所有点之间的距离        

            ind = dis<disnear;                  %得到距离小于阈值的索引
            flag(ind) = clsnum;                 %设置当前聚类标记
            
            diff_flag = preflag-flag;   
            diff_ind = (preflag-flag)<0;        %判断本次循环相比上次循环增加的点
            
            tmp = zeros(length(p),1);
            tmp(diff_ind) = clsnum;
            flag = flag + tmp;                  %增加的点将其标记为一类
            preflag = flag;                 %聚类标记更新
            nxtp = [nxtp;p(diff_ind,:)];    %增加聚类半径内的邻域点队列
        end       
    end    
end

%聚类可能不止三组,我偷懒不想判断并plot了 figure; plot(p(flag==1,1),p(flag==1,2),'r.') hold on; plot(p(flag==2,1),p(flag==2,2),'g.') plot(p(flag==3,1),p(flag==3,2),'b.')

结果如下:

原始数据:

聚类结果:

标签:rand,DBSCAN,练习,flag,length,matlab,聚类,theta,数据
来源: https://www.cnblogs.com/tiandsp/p/11178274.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有