IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【聚类算法】DBSCAN算法及其Python实现 -> 正文阅读

[人工智能]【聚类算法】DBSCAN算法及其Python实现

一:DBSCAN算法

(1)快速入门BCSCAN算法

如下是一组未被聚类的数据

在这里插入图片描述

可以用肉眼进行大致划分

  • 绿色为第一类
  • 蓝色为第二类
  • 灰色为离群点

在这里插入图片描述

这种非凸数据是无法用K-Means算法进行区分的,如果使用则效果会是这样

在这里插入图片描述

而本节的DBSCAN算法可以解决这个问题。DBSCAN算法通过密度来识别簇

  • 簇通常位于高密度区域
  • 离群值通常位于低密度区域

在这里插入图片描述


核心点是DBSCAN算法中非常重要的点,一个点是否能够成为核心点关键在于该点周围的临近点个数是否大于等于某个 r r r值(称为半径,需要自己提前设定)

  • 例如下图,定义这个 r r r值为4,那么第1-4个点可以作为核心点,但第5-6个点不可以

在这里插入图片描述
在这里插入图片描述

接着,我们挑选这组数据的所有核心点非核心点

在这里插入图片描述
在这里插入图片描述


然后在核心点中随机选取一个并标记为绿色,然后把该绿色点周围的所有核心点都加入到该簇中,也标记为绿色

在这里插入图片描述
在这里插入图片描述

然后对其他绿色点执行重复操作

请添加图片描述

在处理时,如果同时喷到了核心点和非核心点,则暂时只把核心点加入其中

在这里插入图片描述
在这里插入图片描述

依据这个策略,进行扩展

在这里插入图片描述


然后处理非核心点。如下对于这个非核心点,其周围存在属于第一个簇的核心点,所以他可以并入

在这里插入图片描述

在这里插入图片描述

但是该非核心点上面的那个点现在就不可以并入了,或者说这就是它的边界

在这里插入图片描述

按照这个规则把所有非核心点并入,第一个簇完毕

在这里插入图片描述

(2)算法简介

A:基本概念

基本概念:DBSCAN全称为Density-Based Spatial Clustering of Applications with Noise,也即基于密度的带有噪声点的聚类方法。该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据中发现任意形状的簇,它将簇定义为密度相连的点的最大集合;在DBSCAN算法中将数据点分为以下3类

  • 核心点 如果一个对象在其半径Eps内含有超过MinPts数目的点,则该对象为核心点
  • 边界点 如果一个对象在其半径Eps内含有点的数量小于MinPts,但是该对象落在核心点的邻域内,则该对象为边界点
  • 噪声点 如果一个对象既不是核心点也不是边界点,则该对象为噪声点

其中EpsMinPtS是DBSCAN算法中的两个重要参数

  • Eps:定义密度时的邻域半径
  • MinPts:定义核心点时的阈值

如下图所示,假设MinPts设置为5,箭头表示Eps范围,则:

  • A A A是核心点:因为在其Eps邻域内有7个点
  • B B B是边界点:因为它落在了 A A A的Eps邻域内
  • C C C是噪声点:没有落在任何核心点的邻域内

在这里插入图片描述

B:直接密度可达、密度可达、密度相连

直接密度可达:如果点 p p p在核心点 q q q E p s Eps Eps邻域内,则称数据对象 p p p从数据对象 q q q出发是直接密度可达的

  • 注意是 p p p直接可达 q q q,但不能是 q q q直接可达 p p p,除非 q q q也是核心点

密度可达:如果存在数据对象链( p 1 p_{1} p1?, p 2 p_{2} p2?, … , p n p_{n} pn? , p n + 1 p_{n+1} pn+1?),其中 p i + 1 p_{i+1} pi+1?是从 p i p_{i} pi?关于 E p s Eps Eps M i n P t s MinPts MinPts直接密度可达的,则称数据对象 p n p_{n} pn?是从数据对象 p 1 p_{1} p1?关于 E p s Eps Eps M i n P t s MinPts MinPts密度可达的

  • 实际上直接密度可达的“传播”

密度相连:若从某核心点 p p p出发,点 q q q和点 k k k都是密度可达的,那么 q q q k k k就是密度相连的

如下图:

  • 左图:点 a a a为核心点,点 b b b为边界点,所以 a a a直接密度可达 b b b(但 b b b不直接可达 a a a b b b不是核心点)
  • 右图 c c c直接密度可达 a a a a a a直接密度可达 b b b,所以 c c c密度可达 b b b

在这里插入图片描述

(3)算法流程

A:流程

DBSCAN输入为

  • 参数 D D D:输入的数据集
  • 参数 ε \varepsilon ε:邻域半径
  • 参数 M i n P t s MinPts MinPts:密度阈值

其中 ε \varepsilon ε M i n P t s MinPts MinPts这两个参数的选择非常重要,选择时可以参考如下方法,但是在实际使用时通常时多次尝试即可

  • ε \varepsilon ε:可以根据距 K K K距离来设定,找出 突变点 K K K距离:对于给定的数据集 P P P= { p 1 , p 2 , . . . , p n } \{p_{1}, p_{2} , ... , p_{n}\} {p1?,p2?,...,pn?},计算点 p ( i ) p(i) p(i)到数据集 D D D的子集 S S S中所有点之间的距离,距离按从小到大的顺序排序,则 d ( k ) d(k) d(k)就称之为 K 距 离 K距离 K
  • M i n P t s MinPts MinPts:一般情况下小一点合适

算法流程如下,整体来说还是很容易理解的
在这里插入图片描述

在这里插入图片描述

B:演示

现在以下面的样本数据为例,演示DBSCAN算法工作流程

  • ε \varepsilon ε= 3
  • M i n P t s MinPts MinPts = 3

在这里插入图片描述

步骤①: 顺序扫描数据集样本点,首先取到 p 1 ( 1 , 2 ) p1(1, 2) p1(1,2)

  1. 计算每一点到 p 1 p1 p1的距离,例如 d ( p 1 , p 2 ) = 1.414 d(p1, p2)=1.414 d(p1,p2)=1.414
  2. 根据每个样本点到 p 1 p1 p1的距离和所设邻域 ε \varepsilon ε= 3,得到 p 1 p1 p1 E p s Eps Eps邻域为 { p 1 , p 2 , p 3 , p 13 } \{p1, p2, p3, p13\} {p1,p2,p3,p13}
  3. 所设 M i n p t s Minpts Minpts=3,而 p 1 p1 p1 E p s Eps Eps邻域有4个点,所以 p 1 p1 p1为核心点
  4. 因此以 p 1 p1 p1为核心点建立簇 C 1 C_{1} C1?,找出所有从 p 1 p1 p1密度可达的点( p 1 p1 p1邻域内的点都是 p 1 p1 p1直接密度可达的点,所以都属于 C 1 C_{1} C1?
  5. p 2 p2 p2的邻域为 ( p 1 , p 2 , p 3 , p 4 , p 13 ) (p1, p2, p3, p4, p13) (p1,p2,p3,p4,p13),且 p 1 p1 p1直接密度可达 p 2 p2 p2 p 2 p2 p2直接密度可达 p 4 p4 p4,所以 p 1 p1 p1密度可达 p 4 p4 p4,因此 p 4 p4 p4也属于 C 1 C_{1} C1?
  6. p 3 p3 p3 p 4 p4 p4 p 13 p13 p13也是核心点,其其邻域的点已经都在 C 1 C_{1} C1?中了
  7. 于是,以 p 1 p1 p1为核心点出发的那些密度可达的对象全部处理完毕,得到簇 C 1 C_{1} C1?,包含对象 ( p 1 , p 2 , p 3 , p 4 , p 13 ) (p1, p2, p3, p4, p13) (p1,p2,p3,p4,p13)

步骤②: 继续顺序扫描数据样本点,取到 p 5 ( 5 , 8 ) p5(5, 8) p5(5,8)

  1. 计算 p 5 p5 p5邻域,其 E p s Eps Eps邻域为 ( p 5 , p 6 , p 7 , p 8 ) (p5, p6, p7, p8) (p5,p6,p7,p8),由于有4个点,所以 p 5 p5 p5是核心点
  2. p 5 p5 p5为核心点建立簇 C 2 C_{2} C2?,找出所有从 p 5 p5 p5密度可达的点,得到簇 C 2 C_{2} C2?,包含点 ( p 5 , p 6 , p 7 , p 8 ) (p5, p6, p7, p8) (p5,p6,p7,p8)

步骤③: 继续顺序扫描数据集样本点取到 p 9 ( 9 , 5 ) p9(9, 5) p9(9,5)

  • p 9 p9 p9 E p s Eps Eps邻域内只有一个点,所以不是核心点

步骤④: 继续顺序扫描数据集样本点取到 p 10 ( 1 , 12 ) p10(1, 12) p10(1,12)

  • 同理, p 10 p10 p10并不是核心点

(4)Python实现

A:算法代码

import random
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd


def dbscan(data_set, eps, min_pts):
    examples_nus = np.shape(data_set)[0]  # 样本数量
    unvisited = [i for i in range(examples_nus)]  # 未被访问的点
    visited = []  # 已被访问的点
    # cluster为输出结果,表示对应元素所属类别
    # 默认是一个长度为examples_nus的值全为-1的列表,-1表示噪声点
    cluster = [-1 for i in range(examples_nus)]

    k = - 1  # 用k标记簇号,如果是-1表示是噪声点
    while len(unvisited) > 0:  # 只要还有没有被访问的点就继续循环
        p = random.choice(unvisited)  # 随机选择一个未被访问对象
        unvisited.remove(p)
        visited.append(p)

        nighbor = []  # nighbor为p的eps邻域对象集合,密度直接可达
        for i in range(examples_nus):
            if i != p and np.sqrt(np.sum(np.power(data_set[i, :]-data_set[p, :], 2))) <= eps:  # 计算距离,看是否在邻域内
                nighbor.append(i)

        if len(nighbor) >= min_pts:  # 如果邻域内对象个数大于min_pts说明是一个核心对象
            k = k+1
            cluster[p] = k  # 表示p它属于k这个簇

            for pi in nighbor:  # 现在要找该邻域内密度可达
                if pi in unvisited:
                    unvisited.remove(pi)
                    visited.append(pi)

                    # nighbor_pi是pi的eps邻域对象集合
                    nighbor_pi = []
                    for j in range(examples_nus):
                        if np.sqrt(np.sum(np.power(data_set[j]-data_set[pi], 2))) <= eps and j != pi:
                            nighbor_pi.append(j)

                    if len(nighbor_pi) >= min_pts:  # pi是否是核心对象,通过他的密度直接可达产生p的密度可达
                        for t in nighbor_pi:
                            if t not in nighbor:
                                nighbor.append(t)
                if cluster[pi] == -1:  # pi不属于任何一个簇,说明第pi个值未改动
                    cluster[pi] = k
        else:
            cluster[p] = -1  # 不然就是一个噪声点
    return cluster

B:可视化输出代码

  • 以下面的三个圆圈数据集为例
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from DBSCAN import dbscan

#  数据处理
data_types = [0.0000000e+00, 1.0000000e+00, 2.0000000e+00, 3.00E+00]
raw_data = pd.read_csv('./threecircles.csv', header=None)
raw_data.columns = ['X', 'Y', 'Type']
x_axis = 'X'
y_axis = 'Y'

examples_num = raw_data.shape[0]  # 样本数量
train_data = raw_data[[x_axis, y_axis]].values.reshape(examples_num, 2)  # 搞成数组

#  K距离图绘制函数
def select_minpts(data_set, k):
    k_dist = []
    for i in range(data_set.shape[0]):
        dist =  (((data_set[i] - data_set)**2).sum(axis=1)**0.5)
        dist.sort()
        k_dist.append(dist[k])
    return np.array(k_dist)

#  参数选择

# k = 3  # 取2*2-1
# k_dist = select_minpts(train_data, k)  # K距离
# k_dist.sort()  # 排序(默认升序)
# plt.plot(np.arange(k_dist.shape[0]), k_dist[::-1])  # 绘制K距离图,绘图时从大到小
# plt.show()

eps = 0.07  # 邻域半径
min_pts = 4  # 核心对象
cluster = dbscan(train_data, eps, min_pts)
print(cluster)

plt.figure(figsize=(15, 7), dpi=80)

# 第一幅图已知标签
plt.subplot(1, 2, 1)

for data_types_index in data_types:
    plt.scatter(raw_data[x_axis][raw_data['Type'] == data_types_index], raw_data[y_axis][raw_data['Type'] == data_types_index], label=str(data_types_index))
plt.title('label know')
plt.legend()


# 第二幅图聚类结果
plt.subplot(1, 2, 2)

class1_X = []
class1_Y = []
class2_X =[]
class2_Y =[]
class3_X =[]
class3_Y =[]
noise_X = []  # 噪声点
noise_Y = []  # 噪声点

for index, value in enumerate(cluster):
    if value == 0:
        class1_X.append(raw_data[x_axis][index])
        class1_Y.append(raw_data[y_axis][index])
    elif value == 1:
        class2_X.append(raw_data[x_axis][index])
        class2_Y.append(raw_data[y_axis][index])
    elif value == 2:
        class3_X.append(raw_data[x_axis][index])
        class3_Y.append(raw_data[y_axis][index])
    elif value == -1:
        noise_X.append(raw_data[x_axis][index])
        noise_Y.append(raw_data[y_axis][index])


plt.scatter(class1_X, class1_Y, c='g', label='class1')
plt.scatter(class2_X, class2_Y, c='r', label='class2')
plt.scatter(class3_X, class3_Y, c='blue', label='class3')
plt.scatter(noise_X, noise_Y, c='black', label='noise')
plt.title('DBSCAN')
plt.legend()
plt.show()

(5)聚类效果展示

①:鸢尾花数据集

  • eps = 0.35
  • min_pts = 4

在这里插入图片描述

②:三个圆圈数据集(K-Means实现效果差)

  • eps = 0.07
  • min_pts = 4

在这里插入图片描述

③:笑脸数据集(K-Means实现效果差)

  • eps = 0.05
  • min_pts = 4

在这里插入图片描述

④:人造数据集

  • 438个数据,分为三类(提前不知道标签)
  • eps = 1.8
  • min_pts = 4

在这里插入图片描述

⑤:西瓜数据集

  • eps = 0.08
  • min_pts = 2

在这里插入图片描述

二:DBSCAN算法探讨

(1)算法优缺点

A:优点

①:可以对任意形状的稠密数据集进行聚类,相对的,K-Means之类的聚类算法一般只适用于凸数据集

在这里插入图片描述

②:可以在聚类的同时发现异常点,对数据集中的异常点不敏感

③:不需要指定簇数,并且多次实验结果往往是相同的

B:缺点

①:如果样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合

②:调参相较于K-Means复杂一点,不同参数组合对聚类效果有很多影响

(2)参数选择

A:参数选择原则(快速)

  • min_pts:一般选择维度+1或者维度×2即可
  • eps:如果所分的类少了,那就把eps调小一点;如果所分的类多了,那就把eps调大一点

B:调参确定

前面说过,eps可以根据K-dist图(K距离图)确定。这里的K-dist是指,从某个点 P P P到第 K K K个与它最近的点的距离的值,然后将这些距离从小到大排序后绘图,称为K-dist图,其中拐点位置即为eps的值

  • 因为在拐点位置往往遇到了边界点或者噪声点

调参步骤如下

  1. 确定K值,一般取2*维度-1
  2. 绘制K-dist
  3. 拐点位置(波动最大的地方)为eps(可以取多个拐点尝试)
  4. min_pts可以取K+1
k = 3  # 取2*2-1
k_dist = select_minpts(train_data, k)  # K距离图
k_dist.sort()  # 排序(默认升序)
plt.plot(np.arange(k_dist.shape[0]), k_dist[::-1])  # 绘图时从大到小
plt.show()

如下eps建议取0.0581

在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 18:58:09  更:2022-05-21 19:00:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:02:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码