DBSCAN聚类算法

来源:互联网 发布:网络市场的主要功能有 编辑:程序博客网 时间:2024/06/06 09:21

一、算法原理

根据密度进行聚类。

三类数据点:核心点,边界点,噪音点。

核心点:在半径Eps内含有超过Minpts个数的点。
边界点:在半径Eps内含有小于Minpts个数的点,但落在核心点的领域。
噪音点:不是以上两种点的点。

每个点都要判断一遍,标记为核心点,边界点和噪音点,噪音点要删除。

二、算法参数

eps:半径
min_sample:簇的样本数
metric:计算方式

eg:db=skc.DBSCAN(eps=0.01,min_samples=20)

三、算法应用代码解析

import numpy as npimport sklearn.cluster as skcimport matplotlib.pyplot as pltfrom sklearn import metricsmac2id=dict()onlinetimes=[]fr=open('TestData.txt',encoding='utf-8').readlines()#encoding='utf-8'?什么意思????for line in fr: mac = line.split(',')[2]#提取用户mac地址,作为每个用户的标识。 onlinetime = int(line.split(',')[6])#提取用户上网时间并转化为整形 starttime = int(line.split(',')[4].split(' ')[1].split(':')[0])#,2014-07-20 23:10:16这是分割对象,分割的时候以,为标识 # 切割下有逗号行的第四个元素。然后在第四个元素里面以空格为标识切割下有空格行的第1个元素,在第一个元素中以:为标识进行切割,切割下 #得到的各元素的第0个元素,即23,最后都转化为int类型 #字典用来存贮用户的地址和位置方便数组内相应位置的元组更新,当用户地址重复时,字典不做改变,改变的是数组中的元组。这样操作最后得到的 #结果就是用户上网最后的时间和最新的累计上网时长。 if mac not in mac2id:#如果用户mac地址不在mac2id字典中 mac2id[mac] = len(onlinetimes)#添加新的用户地址和地址位置。 onlinetimes.append((starttime, onlinetime))#数组长度加1,添加用户对应的上网时长和上网时间。 else: onlinetimes[mac2id[mac]] = [(starttime, onlinetime)]#数组字典长度都不变,更新重复地址中的上网时间和时长。real_X = np.array(onlinetimes).reshape((-1, 2))#把元组变化为数组,并且将数组塑造成不知道几行但一定是两列的矩阵X = real_X[:, 0:1]#0维上面(矩阵纵向)的数字不管(都要),但1维上面只要第0:1个元素(第一个元素取不到)。如果不指定区间地取值,比如[:,1]#这样切片,得到的新矩阵就不能保留原来矩阵的风格。得到了一维数组。db = skc.DBSCAN(eps=0.01, min_samples=20).fit(X)#使用上网开始时间数据计算得到数据相应标签(可以理解为数据的分身,有两个属性,一是#数据本身的值,二是该数据的簇值。 )labels = db.labels_#提取标签的簇值属性(标签属性)print('Labels:')print(labels)#打印标签raito = len(labels[labels[:] == -1]) / len(labels)#遍历标签中所有等于-1的元素并计算元素占整体元素的百分比。这里只能操作纵向元素。#纵向运用降维的话,就变成横向。print('Noise raito:', format(raito, '.2%'))n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)#set()去除labels中重复的元素,然后计算长度即代表所分成的簇,# 如果有噪音点则去除含有噪音点的簇,因此结果计算出来就是不含噪音点的簇的数目。print('Estimated number of clusters: %d' % n_clusters_)print("Silhouette Coefficient: %0.3f" % metrics.silhouette_score(X, labels))#评价聚类效果for i in range(n_clusters_): print('Cluster ', i, ':') print(list(X[labels == i].flatten()))#把labels中等于各自簇的元素用列表表示出来,并且降成一维数组。plt.hist(X, 24)plt.show()


原创粉丝点击