数据挖掘Java——DBSCAN算法的实现

news2024/11/15 13:36:23

一、DBSCAN算法的前置知识

DBSCAN算法:如果一个点q的区域内包含多于MinPts个对象,则创建一个q作为核心对象的簇。然后,反复地寻找从这些核心对象直接密度可达的对象,把一些密度可达簇进行合并。当没有新的点可以被添加到任何簇时,该过程结束。

DBSCAN是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在有“噪声”的空间数据库中发现任意形状的聚类。聚类就是将数据对象分组成为多个类或簇,划分的原则是在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大。与分类不同的是,聚类操作中要划分的类是事先未知的,类的形成完全是数据驱动的,属于一种无指导的学习方法。

对象的ε-领域:给定对象在半径ε内的区域。

核心对象:如果一个对象的ε-领域至少包含最小数目MinPts个对象,则称该对象为核心对象。

直接密度可达:给定一个对象集合D,如果p是在q的ε-领域内,而q是一个核心对象,我们说对象p从对象q出发是直接密度可达的。
密度相连的:如果对象集合D中存在一个对象o,使得对象p和q是从o关于ε和MinPts密度可达的,那么对象p和q是关于ε和MinPts密度相连的。

二、DBSCAN算法的基本思想

DBSCAN是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在有“噪声”的空间数据库中发现任意形状的聚类。
从数据库中抽取一个未处理过的点,如果抽出的点是核心点,那么找出所有从该点密度可达的对象,形成一个簇;如果抽出的点是边缘点(非核心对象),跳出本次循环,寻找下一点,直到所有点都被处理。

三、DBSCAN算法的例子

DBSCAN算法例子
在这里插入图片描述
在这里插入图片描述

四、DBSCAN算法的实现过程

实验内容
有如下二维数据集,取ε =2,minpts=3,请使用DBSCAN算法对其聚类(使用曼哈顿距离)
在这里插入图片描述
实验思路
(1)定义Point类,Point类中含横坐标x,纵坐标y等属性,包含静态方法getIsSame():判断两个Point类对象是否相同、calculateDistance()方法:计算两个Point类对象之间的距离(欧氏距离)、calculateMHDDistance()方法:计算两个Point类对象之间的距离(曼哈顿距离)。定义ExcelData类,ExcelData类中包含横坐标x(添加注解@ExcelProperty(value=“横坐标”)),纵坐标y(添加注解@ExcelProperty(value=“纵坐标”)),ExcelData类主要用于读取excel文件的数据映射到ExcelData类中。定义Cluster类,在Cluster类中包含属性核心点corePoint,簇内的所有点的集合sameList。
(2)定义初始数据集dataList,定义半径e,定义核心对象e领域内对象的最少数目MinPts,调用getFileData()方法对初始数据集进行初始化。在getFileData()方法体内部使用EasyExcel对excel文件进行读取并映射到ExcelData类对象中,将ExcelData类对象中的属性x和属性y作为构造参数,实例化出Point类对象point,并将所有的point添加到dataList集合中,完成对数据集的初始化。
(3)创建clusterList集合,用于存放所有的簇。遍历dataList集合中的每一个Point类对象point,在循环体内部,调用getEPointList()方法获取一个Point类对象领域内所有的点集合ePointList,如果ePointList集合的长度不小于MinPts,说明点point是核心对象,则实例化一个以point为核心对象的簇cluster,并用ePointList实例化簇cluster的sameList属性,然后调用canReachPoint()方法遍历核心对象直接密度可达的点,合并其所有密度可达的点,将最终的簇newCluster加入到簇集合newCluster中。在循环体内部首先调用isExitCluster()方法判断是否点已经存在于某个簇中,已经在簇中的点则不再考虑,不再执行循环体内接下来的代码,直接开始遍历下一次循环,直到遍历过dataList集合中的每一项后,循环结束。
(4)遍历clusetrList集合,将集合中的每一项cluster输出即可。
(5)在isExistCluster()方法体内部,判断point对象是否已经在已存在的簇中,遍历clusterList集合中的每一个簇cluster,获取簇cluster中的sameList属性,判断其sameList集合中是否含point,若含有则返回true。遍历结束后,返回false。
(6)在canReachPoint()方法体内部,遍历簇cluster中包含的所有点,判断除核心对象点以外的每一个点point是否是核心对象,若point也是核心对象,则其领域内所有的点是簇cluster核心点的密度可达的点,也可以合并到簇cluster中,将这些点添加到密度可达的点集合reachPointList中,当循环结束后,将集合reachPointList中所有的密度可达的点加入到簇的sameList集合中,重新实例化簇cluster,最终将cluster返回。
(7)getEpointList()方法的作用是获取一个点e领域内所有点的集合。在方法体内部,定义点集合pointList用于存放point的e领域内所有的点,遍历数据集dataList中的每一个点p,调用Point类内的静态方法calcuteMHDDistance()方法,计算点point和点p的曼哈顿距离,用变量ptoPoint来存放,如果ptoPoint小于半径e,则说明点p在点point的e领域内,则将p加入到pointList集合当中,最终返回pointList集合。

实现源码

Cluster类
package com.data.mining.entity;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class Cluster {
    private Point corePoint;
    private List<Point> sameList = new ArrayList<>();

    public Cluster(){}

    public Cluster(Point cp){
        corePoint = cp;
    }
}

Point类
package com.data.mining.entity;

import lombok.Data;

@Data
public class Point {
    private double x;
    private double y;

    public Point(){}

    public Point(double x, double y){
        this.x = x;
        this.y = y;
    }

    public static boolean getIsSame(Point p1, Point p2){
        if (p1.getX() == p2.getX() && p1.getY() == p2.getY()) return true;
        return false;
    }

    public static double calculateDistance(Point p1, Point p2){
        double xDistance = p1.getX() - p2.getX();
        double yDistance = p1.getY() - p2.getY();
        double tmp = xDistance * xDistance + yDistance * yDistance;
        return Math.sqrt(tmp);
    }

    public static double calculateMHDDistance(Point p1, Point p2){
        return Math.abs(p1.getX() - p2.getX()) + Math.abs(p1.getY() - p2.getY());
    }

}

ExcelData类:因为本实验样本集太多,于是笔者将样本集存入到了excel文件中,用EasyExcel读取excel文件。因此创建ExcelData类
package com.data.mining.entity;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class Cluster {
    private Point corePoint;
    private List<Point> sameList = new ArrayList<>();

    public Cluster(){}

    public Cluster(Point cp){
        corePoint = cp;
    }
}

DBSCAN算法实现代码
package com.data.mining.main;

import com.alibaba.excel.EasyExcel;
import com.data.mining.entity.Cluster;
import com.data.mining.entity.ExcelData;
import com.data.mining.entity.Point;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

public class DBSCAN {
    // 定义初始数据集
    public static List<Point> dataList = new ArrayList<>();
    // 定义半径e
    public static double e = 2.0;
    // 定义核心对象领域内对象的最少数目
    public static int MinPts = 3;

    public static void main(String[] args) {
        getFileData();
//        initDataList();
        List<Cluster> clusterList = new ArrayList<>();
        for (Point point : dataList) {
            if (isExistCluster(point, clusterList)) continue; //已经在簇中的点不再考虑
            List<Point> ePointList = getEPointList(point);
            if (ePointList.size() >= MinPts){ //说明点point是核心对象
                Cluster cluster = new Cluster(point);
                cluster.setSameList(ePointList);
                Cluster newCluster = canReachPoint(cluster);
                clusterList.add(newCluster);
            }
        }
        int pointSum = 0;
        for (Cluster cluster : clusterList) {
            System.out.println(cluster);
            pointSum += cluster.getSameList().size();
        }
        System.out.println(pointSum);
    }

    /**
     * 判断point是否已经在已存在的簇中
     * @param point
     * @param clusterList
     * @return
     */
    public static boolean isExistCluster(Point point, List<Cluster> clusterList){
        for (Cluster cluster : clusterList) {
            List<Point> pointList = cluster.getSameList();
            if (pointList.contains(point)) return true;
        }
        return false;
    }

    /**
     * 遍历核心对象直接密度可达的点,合并其所有密度可达的点
     * @param cluster
     * @return
     */
    public static Cluster canReachPoint(Cluster cluster){
        List<Point> pointList = cluster.getSameList();
        List<Point> reachPointList = new ArrayList<>(); //存放核心点所有密度可达的点(暂存要新加入进来的点)
        for (Point point : pointList) {
            Point corePoint = cluster.getCorePoint();
            if (Point.getIsSame(corePoint, point)) continue; //这里不再遍历核心对象点
            List<Point> reachList = getEPointList(point); //核心对象直接密度可达的点其e领域内所有的点的集合
            if (reachList.size() >= MinPts){ //说明point也是核心对象,其领域内的所有点也可以合并到cluster中
                for (Point reachPoint : reachList) {
                    if (pointList.contains(reachPoint)) continue; //对于pointList中已经有的点不再重复添加
                    reachPointList.add(reachPoint); //将密度可达的点添加到密度可达的点集合中
                }
            }
        }
        pointList.addAll(reachPointList); //将密度可达的点全加入到簇中
        cluster.setSameList(pointList);
        return cluster;
    }

    /**
     * 获取一个点的e领域内所有的点集合
     * @param point
     * @return
     */
    public static List<Point> getEPointList(Point point){
        List<Point> pointList = new ArrayList<>(); //存放point的e领域内所有的点
        for (Point p : dataList) {
            double ptoPoint = Point.calculateMHDDistance(point, p);
            if (ptoPoint <= e) pointList.add(p); //说明点p在point的e领域内
        }
        return pointList;
    }

    public static void getFileData(){
        try {
            FileInputStream inputStream = new FileInputStream("E:\\宋泽旭个人\\课程作业\\课程设计\\data_mining\\dbscan.xlsx");

            List<ExcelData> fileData = EasyExcel.read(inputStream).head(ExcelData.class).sheet()
                    .headRowNumber(1).doReadSync();
            for (ExcelData excelData : fileData) {
                Point point = new Point(excelData.getX(), excelData.getY());
                dataList.add(point);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 使用了书本上的例子进行测试,只为测试算法实现是否正确。main方法中并没有执行initDataList方法
     */
    public static void initDataList(){
        Point p1 = new Point(1, 0);
        Point p2 = new Point(4, 0);
        Point p3 = new Point(0, 1);
        Point p4 = new Point(1, 1);
        Point p5 = new Point(2, 1);
        Point p6 = new Point(3, 1);
        Point p7 = new Point(4, 1);
        Point p8 = new Point(5, 1);
        Point p9 = new Point(0, 2);
        Point p10 = new Point(1, 2);
        Point p11 = new Point(4, 2);
        Point p12 = new Point(1, 3);

        dataList.add(p1);
        dataList.add(p2);
        dataList.add(p3);
        dataList.add(p4);
        dataList.add(p5);
        dataList.add(p6);
        dataList.add(p7);
        dataList.add(p8);
        dataList.add(p9);
        dataList.add(p10);
        dataList.add(p11);
        dataList.add(p12);
    }
}


实验结果
在这里插入图片描述
这图片这么小,反正我是看不清,所以用表格盛一下:
在这里插入图片描述

五、实验总结

本实验结果笔者并不保证一定是正确的,笔者仅仅是提供一种使用Java语言实现DBSCAN算法的思路。因为实验并没有给答案,笔者已将网络上有答案的实验数据输入程序后,程序输出的结果和答案一致,所以问题应该不大。若有写的不到位的地方,还请各位多多指点!
笔者主页还有其他数据挖掘算法的总结,欢迎各位光顾!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/99135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7.加载properties属性文件

一、加载properties属性文件 目的&#xff1a;将数据库的连接参数抽取到一个单独的文件中&#xff0c;与Spring配置文件解耦 1. 编写jdbc.properties属性文件 jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/spring_db jdbc.usernameroot jdbc.passwo…

基于萤火虫算法改进的DELM预测-附代码

萤火虫算法改进的深度极限学习机DELM的回归预测 文章目录萤火虫算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.萤火虫算法4.萤火虫算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1…

代码中的坏味道

学习笔记自https://zhuanlan.zhihu.com/p/141435233 识别代码中的坏味道系列 如下图是工作中常见的代码的坏味道&#xff1a; 上图中的坏味道出自《重构》这本书&#xff0c;虽然并不是全部&#xff0c;但是涵盖了日常中最常见的一些代码坏味道。 接触这些坏代码可以分为三类&…

【Linux】shell 及权限理解

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;shell命令…

计算机基础学习笔记:操作系统篇之硬件结构,存储层次结构

二、存储器的层次结构 本文知识来源小林Coding阅读整理思考&#xff0c;原文链接请见该篇文章 存储层次 寄存器高速缓存&#xff0c;Cache 1-3级内存磁盘&#xff08;SSD&#xff0c;HDD&#xff09; 关键点 各层次的存储的 介质、速度、容量 以及工作层次理解CPU Cache的作…

【Spring]SpringMVC

一、SpringMVC简介 1、什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层。指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 实体类Bean&#xff1a;专门存储业务数据…

【qt Spin Box | Double Spin Box输入小部件函数学习篇】

Spin Box | Double Spin Box输入小部件函数学习篇【1】UI设计布局【2】setMinimum | setMaximum【3】setPrefix | setSuffix【4】setValue【5】setDisplayIntegerBase【6】setSingleStep【7】value【8】举例【1】UI设计布局 【2】setMinimum | setMaximum setMinimum 此属性保持…

点对点网络与广播式网络的区别

目录 一、点对点网络与广播式网络的区别 二、结点和节点 一、点对点网络与广播式网络的区别 写下本文的原因是笔者在学习计算机网络第一章时看到了下面王道书上的一句话&#xff0c;我不理解这句话想表达的是谁需要“分组存储转发和路由选择机制”。于是当时得出了一个错误…

Python读取excel内容追加到mysql表中赋予字段注释

前言 由于最近遇到一个实体类有特别多的字段&#xff0c;我就想自己一个地在表中创建&#xff0c;并写注释未免太浪费人力和时间了&#xff0c;然后在网上查找资料&#xff0c;果不其然让我看到了一个可以使用Python读取excel内容追加到mysql表中赋予字段注释&#xff0c;这简…

前端零碎知识随笔

一、介绍 本篇博客主要使用来记录一些比较零碎的知识点&#xff0c;都是本人在日常开发工作中遇到的&#xff0c;或者是在学习过程中遇到的。因为这些知识点都比较零碎&#xff0c;为了防止遗忘&#xff0c;所以特意写一篇博客来记录&#xff0c;后面也不会不断慢慢更新的。 …

[附源码]计算机毕业设计Python-大学生健康档案管理(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

JSP+MySQL基于ssm的环保数据自动采集及预测系统

在21世纪的今天,随着科技的进步和发展,人们的生活逐渐趋于自动化、便捷化、数据化。而发展总会有代价,科技的进步总是伴随着环境的恶化。人类用智慧将地球的资源充分利用,以便丰富人们的生活,推动国家的进步。回过头去看,地球的环境已经成为威胁人类长久生存的主要问题之一。在…

34-Vue之ECharts高级-调色盘

ECharts高级-调色盘前言调色盘主题调色盘全局调色盘局部调色盘渐变颜色前言 本篇来学习下ECharts中调色盘的使用 调色盘 它是一组颜色&#xff0c;图形、系列会自动从其中选择颜色, 不断的循环从头取到尾, 再从头取到尾, 如此往复主要分三种&#xff1a;主题调色盘、全局调色…

基于GDAL的gdb格式数据读写功能实现

一、GDAL类库下载&#xff1a; 下载地址&#xff1a;GISInternals Support Site 比如我下载的是release-1930-x64-gdal-3-4-2-mapserver-7-6-4 点击release-1930-x64-gdal-3-4-2-mapserver-7-6-4的链接&#xff0c;下载这两个文件 二、解压文件和安装gdb插件 1.下载好的两个…

Innodb存储引擎-备份和恢复(分类、冷备、热备、逻辑备份、二进制日志备份和恢复、快照备份、复制)

文章目录备份和恢复分类冷备热备逻辑备份mysqldumpSELECT...INTO OUTFILE恢复二进制日志备份与恢复快照备份(完全备份)复制快照复制的备份架构备份和恢复 分类 &#xff08;1&#xff09;根据备份的方法可以分为&#xff1a; Hot Backup&#xff08;热备&#xff09;&#x…

【图像去噪】中值+均值+Lee+Kuan图像滤波【含Matlab源码 1179期】

⛄一、图像去噪及滤波简介 1 图像去噪 1.1 图像噪声定义 噪声是干扰图像视觉效果的重要因素&#xff0c;图像去噪是指减少图像中噪声的过程。噪声分类有三种&#xff1a;加性噪声&#xff0c;乘性噪声和量化噪声。我们用f(x,y&#xff09;表示图像&#xff0c;g(x,y&#xff0…

ADI Blackfin DSP处理器-BF533的开发详解63:DSP接总线屏的硬件和驱动设计(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 EBIU总线LCD屏 硬件实现原理 LCD2.4 寸液晶屏子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT1 和 PORT2 上&#xff0c;板卡插入时&#xf…

基于JAVA的水产批发系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

【Linux】低级IO

目录 一、文件的概念 二、C语言文件操作回顾 三、使用系统调用进行文件I/O 1、系统调用open 1.1open接口介绍 1.2open形参中标记位flags的意义 1.3open的使用 2、系统调用write 2.1write接口介绍 2.2write的使用 3、系统调用read 3.1read接口介绍 3.2read的使用 …

什么是 SAP ABAP FDA - Fast Data Access 技术?

快速数据访问 (Fast Data Access&#xff0c;缩写为 FDA) 是一种可在 SAP ABAP 环境中访问的协议。 它允许针对 SAP HANA 提交 OPEN SQL SELECT 语句&#xff0c;从而使用 SAP ABAP 的数据格式。 在快速数据访问场景里&#xff0c;SAP ABAP 内表数据传输到数据库并返回。这种方…