算法流程描述
DBSCAN是一种基于密度的聚类算法,这类密度聚类算法一般假定类别可以通过样本分布的紧密程度决定。同一类别的样本,他们之间是紧密相连的,也就是说,在该类别任意样本周围不远处一定有同类别的样本存在。通过将紧密相连的样本划为一类,这样就得到了一个聚类类别。通过将所有各组紧密相连的样本划为各个不同的类别,则我们就得到了最终的所有聚类类别结果。
核心概念
基本概念
- 核心对象:若某个点周围的密度达到算法设定的阈值则其为核心点。(即邻域内点的个数不少于minPts)
- ε邻域的距离阈值:设定的半径ε。
- 直接密度可达:若某点p在q的邻域内,且q是核心点,则p-q直接密度可达。
- 密度可达:若有一个点的序列q0、q1、…、qk,对任意qi-qi-1是直接密度可达的,责成从q0到qk密度可达,这实际上是直接密度可达的“传播”。
- 密度相连:若从某核心点出发,点q和点k都是密度可达的,则称点q和点k是密度相连的。
- 边界点:属于某一个类的非核心点,不能发展下线了(类似传销)。
- 噪声点:不属于任何一个类簇的点,从任何一个核心点出发都是密度不可达的。
举例说明:A表示核心对象、B和C表示边界点以及N表示离群点。
半径与MinPts
在DBSCAN算法中有两个重要参数,即半径Eps和密度MinPts。半径是最难指定的,大了,圈住的就多了,簇的个数就少了;反之,簇的个数就多了,这对我们最后的结果是有影响的。
这个时候K-距离可以帮助我们来设定半径Eps,也就是要找到突变点。具体方法是:首先选中一个点,计算它和所有其他点的距离,从小到大排序,如果某两个距离之间的差距很大,就认为前面的一个距离是合适的,可以使用该距离指定出半径。
MinPts就是圈住的点的个数,也相当于是一个密度,一般这个值都是先设置为偏小一些,然后进行多次尝试选择合适值。
算法流程
DBSCAN算法
1.将所有点标记为核心对象、边界点和噪声点。
2.删除噪声点。
3.为距离在Eps之内的所有核心对象之间赋予一条边。
4.每组连通的核心对象(构成连通分量)形成一个簇。
5.将每个边界点指派到一个与之关联的核心对象的簇中。
更加具体的算法框架:
python实现代码
各方法的解释
find_neighbor(j, x, eps)函数用于从点的集合x中找到在j点以eps为半径范围内的邻域点的集合;DBSCAN函数为算法核心,主要采用队列的思想实现了算法流程;diyDataTest函数是使用自定义的数据集进行测试的函数;loadDataTest函数是加载文档中的数据进行测试的函数。
代码
from sklearn import datasets
import numpy as np
import random
import matplotlib.pyplot as plt
import time
import copy
# 找邻域中的点
def find_neighbor(j, x, eps):
N = list()
for i in range(x.shape[0]):
temp = np.sqrt(np.sum(np.square(x[j] - x[i]))) # 计算欧式距离
if temp <= eps:
N.append(i)
return set(N)
# 算法核心
def DBSCAN(X, eps, min_Pts):
k = -1
neighbor_list = [] # 用来保存每个数据的邻域(用集合表示,即多个集合的序列)
omega_list = [