密度聚类DBSCAN算法代码超详细注释(python版)
2020-02-17 03:55
323 查看
密度聚类DBSCAN算法代码超详细注释(python版)
个人对DBSCAN代码的理解
声明:我也不知道这个源代码是谁写的,看了之后自己手动做了注释,如果有侵权,本人会立刻删除。
不足的地方欢迎大家的指正,
代码如下(个人理解)
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets # 核心思想是贪心,k每加1,都会把这一个簇的全部子集都取出来完,才会进行下一个簇+1 def distance(x,y): return np.sqrt(np.sum( (x - y) **2 )) def dbscan(dataset, minPts, eps): # 每个点都有这三个参数 """ :param dataset: 数据集 :param minPts: 半径内的最小点数 :param eps: 半径 :return: 返回的是样本的簇的集合 """ n,m = dataset.shape #获取数据集的尺寸,其实只用到了n """ 注意:,注意这里传入的数据X是ndarray,因为有shape函数,所以这里的dataset也是ndarray格式 """ clusters = np.full(n,-1) # 顶一个容器去存储样本的分类,将整个数据的样本集初始化为样本数为n,值为-1的列表 # 注意:这里初始化类一个cluster的ndarray的容器,用来存放样本分类结果 #print(clusters) k = -1 #将类簇的个数初始化为-1 for i in range(n): #注意 range(n)是全部的数据集,这里就是遍历数据集 if clusters[i] != -1: #如果取出来的第i个样本的值不等于-1,则说明已经被聚类分到了某一个类簇 """ 这里操作的都是clusters这个一维的数组,cluster是ndarray """ continue #终止当前循环,还是下一个循环 # 获取邻域内的所有样本点,遍历整个数据集,然后进行对比,这里获得的时dataset的下标 subdataset = [j for j in range(n) if distance(dataset[j], dataset[i]) <= eps] """ 这是个生成式,“生成式”主流的就是list,list中存的时是dataset的下标 这里用的是dataset,用下标取出dataset中对应的样本的值,算出距离,并且将满足条件的dataset放在 subdataset中,subdataset是一个list """ #这里生成的是一个列表 # 注意这一句是生成模型,生成一个list,这里i是外层i,j是整个数据集进行遍历,算出的距离和截断值对比 # 因为这里用的是for循环,拍成一排的,按照顺序从前到后来,第一个样本点处理过后,在这次循环中就不会再遇到了 if len(subdataset) < minPts: #这里是那子集的长度和,半径内最小的样本数进行比较,下雨就终止本次循环开始下一次 continue # 注意到此位置处理的都是,未处被理的点,标记为边界点,或者噪声点(这里并未进行分类)设置别的class # 或者将上面的full 写成full((n,2)-1),,不同的类标记不同的情况 # 建立新簇/上面的if已经排除了,不能满足半径eps内的点个数少于minPts这种情况,所以进入到这里的点都是满足条件的 k += 1 # 在建了k之后,会把k中的所有点都取完的 # 这里是把子集(subdataset)内的所有点都标记为k,相当于是给样本赋值 """ 此处的i还是循环开始时的那个i,相当于是簇的起始点 """ clusters[i] = k #相当于给样本list中对应的第i个样本的属于类簇赋值为k """ 这里cluster时ndarray数组,不是list """ # 这里处理的是已经处理过点 for j in subdataset: #获取到满足要求的子集也就是subdataset print(subdataset) # 这里的subdataset是符合条件的元素的下标, clusters[j] = k """ 子集的所有点都等于k,用list的下标寻址,取出元素赋值为k,也就是聚类的结果 """ # 这里怎么再确认,找到的点是被处理过的,因为所有的点都被初始化赋值为了负1(-1), # 只要再进入循环的点大于-1,就是已经被处理过的点,注意外围的第一个for循环,只要不等于-1,就不会进入到这个循环中。 if j>i: # j是在子集中遍历, i是在完整的数据中遍历, j大于i说明j还是没有被处理的 # 这个是对新的for循环的判断,也是拍成一行进行逐个的来判断,也就是subdataset的数据集中的样本中遍历 # 这里的新子集subdataset中的数据j到全部的数据集(range(n))中去寻找,然后生成一个新的核心点列表 sub = [item for item in range(n) if distance(dataset[j],dataset[item])<=eps] """ 注意这里的j来自上面的j 注意这里的dataset[i]是dbscan传进来的参数,传进来的是ndarray类型的数组,所以这里也是ndarray的数组 """ #这里sub时一个列表的生成式,意思是遍历数据集中全部的点命名为item,如果j(也就是子集中的点)到item的距离小于半径 #就把满足这个条件的item点生成一个listsub for t in sub: #遍历sub列表 if t not in subdataset: # 如果sub列表中的点,不在子集中,则追加上来。 subdataset.append(t) """ list 才有append 这一个append的灵魂在于,append之后,需要经历的是for循环,早晚会再遍历到这个append的值, 遍历到之时就会有clusters[j] = k 这一句作为赋值,保证是在类簇K中。 """ print(clusters) return clusters
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- Center OS下安装python3
- Python中print单引号、双引号、三引号
- python基础--print()函数、变量定义、转义字符
- Python | 导包 ModuleNotFoundError: No module named 'xxx'
- python学习day01
- AttributeError错误,用的是python3,jango2.1为什么回报错是因为ForeignKeys不存在?
- win10 anaconda python3.6多虚拟环境使用VScode配置
- 学习笔记(04):跟着王进老师学开发:Python初级入门课程-身份运算符
- python3 安装/更新 及遇到的问题
- 关于python爬虫中的细节问题
- 关于python3版本下读取文件时出现的字符编码错误
- Python使用urllib,urllib3,requests库爬取网页
- Python爬虫(一)——开发环境
- Python爬虫(三)——Robots协议
- Python爬虫(四)——五个基础爬虫实例
- Python爬虫(五)——Beautiful Soup库
- Python基础笔记(1)
- 利用pyinstaller 打包Python文件
- Python中的单例模式
- Python中区分函数和方法