【聚类】一种自适应Eps和Minpts的DBSCAN方法的改进(python实现)

您所在的位置:网站首页 如何复现算法的优缺点和不足和改进 【聚类】一种自适应Eps和Minpts的DBSCAN方法的改进(python实现)

【聚类】一种自适应Eps和Minpts的DBSCAN方法的改进(python实现)

2024-07-04 07:58| 来源: 网络整理| 查看: 265

一、算法来源

1、DBSCAN算法原型 这个算法原型非常简单,有很多博主都有写,大家自己去看看就好了,也不用花太多时间,顶多十分钟就能了解个大概。

2、自适应Eps和Minpts参数 由于该算法对Eps和Minpts参数十分敏感,所以如何确定这两个参数对于DBSCAN来说是很重要的一步,这篇博文是基于李文杰老师的论文《自适应确定DBSCAN算法参数的算法研究》,通过这篇论文,输入数据集即可大致确定这两个参数,从而可以直接在DBSCAN中应用。

二、大致思想

其中的基本思想,是通过计算数据集 D 中每个数据点与其第 K个最近邻数据点之间的 K-最近邻距离,并对所有数据点的 K-最近邻距离求平均值,这个值就作为这个k时的eps,那么每一个k对应一个K-最近邻距离平均值(K=1时,即为平均最近邻距离),所以每一个k都对应一个eps。这时我们可以想一下它的物理意义,这个eps其实就是K-近邻距离最大的那个半径的平均。

然后论文又根据下面这个公式计算出Minpts。请添加图片描述 式中,Pi 为第 i 个对象的 Eps 邻域对象数量,n 为数据集 D 中的对象总数

随后用这些结果尝试使用DBSCAN算法进行聚类,如果连续的候选项聚类的类别数目相同,那么选择Eps相对较大的那个最为最终参数输入到DBSCAN算法中去。

论文中认为如果连续3个Eps候选项聚类的类别数目相同,那么可以认为数据集在这些参数下逐渐收敛,但是我觉得具体最好看图像是否收敛,所以我就简单的在程序里将聚类数目打印出来,读者可以自行选择聚利时使用的Eps和Minpts参数。

具体python程序: import math import copy import numpy as np from sklearn.cluster import DBSCAN import pandas as pd import matplotlib.pyplot as plt #两个样本点之间的欧式距离 def dist(a,b): """ :param a: 样本点 :param b: 样本点 :return: 两个样本点之间的欧式距离 """ return math.sqrt(math.pow(a[0]-b[0],2) + math.pow(a[1]-b[1],2)) #第k最近距离集合 def returnDk(matrix,k): """ :param matrix: 距离矩阵 :param k: 第k最近 :return: 第k最近距离集合 """ Dk = [] for i in range(len(matrix)): Dk.append(matrix[i][k]) return Dk #第k最近距的平均即eps def returnDkAverage(Dk): """ :param Dk: k-最近距离集合 :return: Dk的平均值 """ sum = 0 for i in range(len(Dk)): sum = sum + Dk[i] return sum/len(Dk) #传入数据计算距离矩阵 def CalculateDistMatrix(dataset): """ :param dataset: 数据集 :return: 距离矩阵 """ DistMatrix = [[0 for j in range(n)] for i in range(n)] for i in range(n): for j in range(n): DistMatrix[i][j] = dist(dataset[i], dataset[j]) return DistMatrix #传入数据和k输出eps,min_samples以及聚类簇的个数 #n=len(X),DistMatrix = CalculateDistMatrix(X) #n是数据长度,DistMatrix距离矩阵 def ems(dataset,k): #深度拷贝距离矩阵依此计算出eps tmp_matrix = copy.deepcopy(DistMatrix) for i in range(n): tmp_matrix[i].sort() Dk = returnDk(tmp_matrix,k) eps = returnDkAverage(Dk) tmp_count = 0 for i in range(len(DistMatrix)): for j in range(len(DistMatrix[i])): if DistMatrix[i][j]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3