DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。 该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。
动画讲解DBSCAN算法的国外网站:https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
1.取半径为3,MinPts为3(圆圈能够圈住的最小的数目),则可以得到如下的分类结果,其中,P9为噪音点,P10为噪音点。
MinPts:这个参数就是圆能够圈住的点的个数,也相当于是一个密度,一般这个值都是偏小一些,然后进行多次尝试
(1)Eps邻域:给定对象半径Eps内的邻域称为该对象的Eps邻域。
(2)核心点(core point):如果对象的Eps邻域至少包含最小数目MinPts的对象,则称该对象为核心对象。
(3)边界点(edge point):边界点不是核心点,但落在某个核心点的邻域内。
(4)噪音点(outlier point):既不是核心点,也不是边界点的任何点。6,
我们假设最小样本容量为6,A、B、C为核心对象:
(5) 直接密度可达:给定一个对象集合D,如果p在q的Eps邻域内,而q是一个核心对象,则称对象p从对象q出发时是直接密度可达的,比如 上图中的 A 和 B 、B 和 C 等。
(6)密度可达: 如果有一系列的点,都满足上一个点到这个点是密度直达,那么这个系列中不相邻的点就称为密度可达,比如 A 和 D。
(7)密度相连: 如果存在对象O∈D,使对象p和q都是从O关于Eps和MinPts密度可达的,那么对象p到q是关于Eps和MinPts密度相连的,比如这 里的 E 和 F 点就是密度相连。
半径: 半径是最难指定的 ,大了,圈住的点就多了,簇的个数就少了;反之,圈住的点少了,簇的个数就多了,这对我们最后的结果是有影响的。我们这个时候K距离可以帮助我们来设定半径r,也就是要找到突变点,比如:
DBSCAN 算法的簇里面可以有一个或者多个核心点。如果只有一个核心点,则簇里其他的非核心点样本都在这个核心点的 Eps 邻域里。如果有多个核心点,则簇里的任意一个核心点的 Eps 邻域中一定有一个其他的核心点,否则这两个核心点无法密度可达。这些核心点的 Eps 邻域里所有的样本的集合组成一个 DBSCAN 聚类簇。
DBSCAN算法的描述如下。
输入:数据集,邻域半径 Eps,邻域中数据对象数目阈值 MinPts;
输出:密度联通簇。
处理流程如下。
DBSCAN 算法的计算复杂的度为 O(n²),n 为数据对象的数目。这种算法对于输入参数 Eps 和 MinPts 是敏感的。
dbscan(X, eps=0.5, *, min_samples=5, metric='minkowski',
metric_params=None, algorithm='auto', leaf_size=30,
p=2, sample_weight=None, n_jobs=None)
参数说明:
eps : float, optional
两个样本之间的最大距离,一个被认为是另一个样本的邻域。这不是群集中点的距离的最大界限。这是为您的数据集和距离函数选择适当的最重要的DBSCAN参数。
min_samples : int,可选
对于要被视为核心对象的点,邻域中的样本数(或总权重)。这包括点本身。
metric:最近邻距离度量参数。默认的欧式距离(即p=2的闵可夫斯基距离),可以使用的距离度量参数有:欧式距离 “euclidean”,曼哈顿距离 “manhattan”,切比雪夫距离“chebyshev”,闵可夫斯基距离 “minkowski”,带权重闵可夫斯基距离 “wminkowski”,标准化欧式距离 “seuclidean”,马氏距离“mahalanobis”。
metric_params : dict, optional
度量函数的其他关键字参数。
algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选
NearestNeighbors模块用于计算逐点距离并找到最近邻居的算法。有关详细信息,请参阅NearestNeighbors模块文档。
leaf_size : int,optional(默认值= 30)
叶子大小传递给BallTree或cKDTree。这可能会影响构造和查询的速度,以及存储树所需的内存。最佳值取决于问题的性质。
p : float,可选
正确译法:用于计算点之间距离的Minkowski矩阵的幂。
n_jobs : int或None,可选(默认=无)
要运行的并行作业数。 None除非在joblib.parallel_backend上下文中,否则表示1 。 -1表示使用所有处理器。
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.cluster import dbscan
# make_moons 这个方法是生成两个交错的半圆环
data,_ = datasets.make_moons(500,noise = 0.1,random_state=1) # 创建数据集
# print('数据集0,1', data)
df = pd.DataFrame(data,columns = ['feature1','feature2']) # 将数据集转换为dataframe
# 可视化处理
# 绘制样本点,s为样本点大小,aplha为透明度,设置图形名称
# 看下面第1个图
df.plot.scatter('feature1','feature2', s = 100,alpha = 0.6,
title = 'dataset by make_moon')
# DBSCAN算法
core_samples,cluster_ids = dbscan(data, eps = 0.2, min_samples=20) # eps为邻域半径,min_samples为最少点数目
# cluster_id=k,k为非负整数时,表示对应的点属于第k簇,k为簇的编号,当k=-1时,表示对应的点为噪音点
# print('标签', cluster_ids)
# np.c_用于合并按行两个矩阵
#(要求两个矩阵行数相等,这里表示将样本数据特征与对应的簇编号连接)
df = pd.DataFrame(np.c_[data,cluster_ids],columns = ['feature1','feature2','cluster_id'])
# print('两个矩阵合并后的DataFrame', df)
# astype函数用于将pandas对象强制转换类型,这里将浮点数转换为整数类型
df['cluster_id'] = df['cluster_id'].astype('int')
# 绘图,c = list(df['cluster_id'])表示样本点颜色按其簇的编号绘制
# cmap=rainbow_r表示颜色从绿到黄
# colorbar = False表示删去显示色阶的颜色栏
# 看下面第2个图
df.plot.scatter('feature1','feature2', s = 100,
c = list(df['cluster_id']),cmap = 'Reds',colorbar = False,
alpha = 0.6,title = 'DBSCAN cluster result')
plt.show()
图1:未运用DBSCAN算法进行处理的数据散点图
图2:运用DBSCAN算法进行处理的数据散点图
Birch聚类算法称为平衡迭代归约及聚类算法,它是一种常用的层次聚类算法。该算法通过聚类特征(Clustering Feature,CF)和聚类特征树(Clustering Feature Tree,CFT)两个概念描述聚类。聚类特征树用来概括聚类的有用信息,由于其占用空间小并且可以存放在内存中,从而提高了算法的聚类速度,产生了较高的聚类质量,并适用于大型数据集。层次聚类算法是讲数据样本组成一颗聚类树,根据层次分解是以自顶向下(分裂)还是自底向上(合并)方式进一步合并或分裂。
Birch聚类算法具有能处理的数据规模大、算法效率高、更容易计算类簇的直径和类簇之间的距离等优点。
Birch聚类算法的聚类特征(CF)通过三元组结构描述了聚类类簇的基本信息,
三元结构公式为:
上述中N表示聚类数据点的个数,每个点用一个d维向量表示;表示N个聚类数据点的线性和;SS表示N个聚类数据点的平方和。聚类特征通过线性和表示聚类的质心,通过平方和表示聚类的直径大小。
Birch算法主要包括以下三个阶段:
Birch(branching_factor=50, compute_labels=True,
copy=True, n_clusters=3, threshold=0.5)
参数说明:
from sklearn.cluster import Birch
X = [[1,1],[2,1],[1,3],[6,6],[8,5],[7,8]]
y = [0,0,0,1,1,1]
clf = Birch(n_clusters=2) # 聚类模型
clf.fit(X,y) # 训练
print(clf.labels_) # 聚类后的类标 , 从0开始的数字
输出为:
[1 1 1 0 0 0]
clf.labels_表示输出聚类后的类标。由于聚类类簇设置为2,故类标为0或1,其中X[1,1]、X[2,1]、X[1,3]聚类后属于1类,X[6,6]、X[8,5]、X[7,8]聚类后属于0类。
氧化物数据下载:http://archive.ics.uci.edu/ml/machine-learning-databases/glass/
其中数据集共包含9个特征变量,分别为ri、na、mg、al、si、k、ca、ba、fe,1个类别变量glass_type,共有214个样本。其中类别变量glass_type包括7个值,分别是:1 表示浮动处理的窗口类型、2表示非浮动处理的窗口类型、3表示浮动处理的加工窗口类型、4表示非浮动处理的加工窗口类型(该类型在该数据集中不存在)、5表示集装箱类型、6表示餐具类型、7表示头灯类型。
import pandas as pd
import matplotlib.pyplot as plt
glass = pd.read_csv("glass1.csv") # 读取glass1.csv文件
# 不同类别glass_type绘制为不同颜色的点(共7个类别)
plt.scatter(glass.al, glass.ri, c=glass.glass_type)
plt.xlabel('al')
plt.ylabel('ri')
plt.show()
散点图为:
代码为:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import Birch
# 数据获取
glass=pd.read_csv("glass1.csv")
X1 = glass.al # 获取第五列数据
X2 = glass.ri # 获取第二列数据
T = dict(zip(X1,X2)) # 生成二维数组
X = list(map(lambda x,y: (x,y), T.keys(),T.values())) # dict类型转换为list
y = glass.glass_type # 获取第11列数据
# 聚类
clf = Birch(n_clusters=3)# n_clusters=3表示该聚类类簇数为3,即聚集成3堆
clf.fit(X, y) # 训练
y_pred = clf.predict(X) # 预测
print('预测结果=', y_pred)
# 分别获取不同类别数据点
x1, y1 = [], []
x2, y2 = [], []
x3, y3 = [], []
# 分布获取类标为0、1、2的数据并赋值给(x1,y1) (x2,y2) (x3,y3)
i = 0
while i < len(X):
if y_pred[i]==0:
x1.append(X[i][0])
y1.append(X[i][1])
elif y_pred[i]==1:
x2.append(X[i][0])
y2.append(X[i][1])
elif y_pred[i]==2:
x3.append(X[i][0])
y3.append(X[i][1])
i = i + 1
# 三种颜色 红 绿 蓝,marker='x'表示类型,o表示圆点 *表示星型 x表示点
plot1, = plt.plot(x1, y1, 'or', marker="x")
plot2, = plt.plot(x2, y2, 'og', marker="o")
plot3, = plt.plot(x3, y3, 'ob', marker="*")
plt.xlabel('al')
plt.ylabel('ri')
plt.show()
输出为:
预测结果= [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 2 0
0 0 2 2 2 0 2 2 0 2 2 2 2 2 1 1 2 1 2 2 1 2 2 2 2 2 2 0 0 1 1 2 0 0 0 0 2
2 2 2 2 2 2 2 2 2 0 2 0 2 1 2 2 2 1 1 1 2 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 2 2 1 1 1 1]
散点图:
从图中可以看到,右下角红色x形点聚集在一起,其al含量较高、ri含量较低;中间绿色o点聚集在一起,其al、ri含量均匀;右部蓝色*星形点聚集在一起,其al含量较低、ri含量较高。可以看出Birch算法将数据集划分为三部分。
DBSCAN算法优缺点
优点
缺点
Birch算法优缺点
优点
缺点