【机器学习】聚类算法-DBSCAN基础认识与实战案例

前言

在机器学习中,聚类是一种常见的无监督学习方法,它的目标是将数据集中的数据点分成不同的组,每个组之间具有相似的特征。聚类可以用于各种应用程序,如图像分割,社交媒体分析,医疗数据分析等。DBSCAN是一种聚类算法,它被广泛应用于各种领域。

一、DBSCAN算法原理

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它的原理是基于数据点周围的密度来确定聚类。在DBSCAN中,密度高的区域被认为是聚类,而密度低的区域则被认为是噪声。

DBSCAN的算法流程如下:

  • 选择一个数据点作为起点,然后查找与该点距离在指定范围内的所有数据点。
  • 如果距离在指定范围内的数据点数量大于或等于指定的阈值,则将这些数据点标记为核心点。
  • 对于所有核心点,将与其距离在指定范围内的所有数据点归为同一个簇中。如果两个核心点之间存在重叠的数据点,则将它们归为同一簇中。
  • 对于所有非核心点,将它们标记为噪声点。

基本概念:

  • 密度相连:若从某核心点p出发,点q和点k都是密度可达的,则称点q和点k是密度相连的。
  • 边界点:属于某一个类的非核心点,不能发展下线了
  • 直接密度可达:若某点p在点q的 r 邻域内,且q是核心点则p-q直接密度可达。
  • 噪声点:不属于任何一个类簇的点,从任何一个核心点出发都是密度不可达的

在DBSCAN中,有三个参数需要指定:

  • eps:指定在距离范围内的最大距离。
  • min_samples:指定一个点周围的最小数据点数量,用于确定核心点。
  • metric:用于计算距离的度量方法,密度阈值

二、基础使用

  • 导包
import matplotlib.pyplot as plt
import numpy as mp
from sklearn.datasets import make_circles
from sklearn.cluster import DBSCAN

make_circles是scikit-learn中的一个函数,用于生成一个随机的圆形数据集。该函数的参数包括n_samples,表示生成数据集中样本的数量;noise,表示在生成的数据中加入的高斯噪声的标准差;factor,表示内外圆之间的比例因子;random_state,表示生成数据的随机种子,用于确保多次生成的数据集一致。
make_circles函数会在二维平面上生成两个圆形状的簇,并将它们相互嵌套放置,以模拟实际中的非线性可分问题.

DBSCN()实例化参数介绍

  • eps:表示两个样本之间的最大距离,超出此距离的样本将被视为离群点,默认值为0.5。
  • min_samples:表示簇中的最小样本数,小于此数量的簇将被视为离群点,默认值为5。
  • metric:表示用于计算距离的度量方法,默认为欧几里得距离(euclidean)。还可以选择曼哈顿距离(manhattan)、余弦距离(cosine)等。
  • metric_params:表示度量方法的其他参数。
  • algorithm:表示计算DBSCAN的算法,可以选择基于kd树的高效算法(‘kd_tree’)或基于球树的高效算法(‘ball_tree’),默认为自动选择。
  • leaf_size:表示构建kd树或球树时的叶子大小,默认为30。
  • p:表示用于闵可夫斯基距离计算的参数,p=1时为曼哈顿距离,p=2时为欧几里得距离,p>2时为L_p距离,默认为2。
    -> n_jobs:表示用于计算的并行工作数量,默认为1。-1表示使用所有可用的CPU核心。

返回方法介绍

fit_predict(X):在训练模型的同时,返回聚类结果,即返回每个样本点所属的簇编号,如果是噪声点则返回-1。X为输入的数据。

  • labels_:训练后,每个样本点所属的簇编号,如果是噪声点则为-1。
  • core_sample_indices_:训练后,核心样本的索引。
  • components_:训练后,核心样本的特征向量。
  • eps_:训练后,最佳的eps值。
  • min_samples_:训练后,最佳的min_samples值。
  • get_params():获取当前模型的参数设置。

-数据集

X,y=make_circles(factor=0.3,n_samples=1000,random_state=42,noise=0.1)
X

-我们可视化一下我们看到的数据

plt.plot(X[:,0],X[:,1],'b.',marker='*')
plt.show()

在这里插入图片描述

  • 由于不同的eps对结果的影响不同,这里我们尝试多个eps进行训练

def plot_show(epe,modal):
    core_mask=np.zeros_like(modal.labels_,dtype=bool)

    #设置核心样本店
    core_mask[modal.core_sample_indices_]=True

    anoalie_mask=modal.labels_==-1

    # 标记噪声点
    non_core_mask=~(core_mask | anoalie_mask)

    cores=modal.components_
    anomalies=X[anoalie_mask]
    non_cores=X[non_core_mask]

    plt.scatter(cores[:,0],cores[:,1],c=modal
                .labels_[core_mask],marker='o',cmap='Paired')

    plt.scatter(cores[:, 0], cores[:, 1], marker='*', s=20, c=modal.labels_[core_mask])

    plt.scatter(anomalies[:,0],anomalies[:,1],c='red',marker='X',s=70)

    plt.scatter(non_cores[:,0],non_cores[:,1],c=modal.labels_[non_core_mask],marker='.')

    plt.axis('off')

    plt.title(f'epe:{
      
      epe}')


for i,epe in enumerate(epes):

    dbscan=DBSCAN(eps=epe,min_samples=5)
    dbscan.fit(X)
    plt.subplot(331+i)

    plot_show(epe,dbscan)

plt.show()

在这里插入图片描述看到可以不同的epe值对于分类的结果还是很大,选择合适的epe尤为重要,图中中的X就是核心样本所在的位置

三、DBSCAN与Kmeans处理比较

DNSCAN在对任意形状非线性的簇处理很有优势,而Kmeans对却无法很好处理,我们实验观察

  • 加载数据
from sklearn.datasets import make_moons

X,y=make_moons(n_samples=1000,noise=0.04,random_state=42)
#%% md
#%%
plt.plot(X[:,0],X[:,1],'b.',marker='*')
plt.show()

make_moons是scikit-learn中的一个函数,用于生成一个随机的月牙形数据集。该函数的参数包括n_samples,表示生成数据集中样本的数量;noise,表示在生成的数据中加入的高斯噪声的标准差;random_state,表示生成数据的随机种子,用于确保多次生成的数据集一致。
make_moons函数会在二维平面上生成两个半月形状的簇,并将它们相互交叉放置。

在这里插入图片描述

-比较两种分类方式

plt.subplot(121)
dbscan=DBSCAN(eps=0.1,min_samples=5)
dbscan.fit(X)
plt.scatter(X[:,0],X[:,1],c=dbscan.labels_)

plt.title('DBSCAN')

from sklearn.cluster import KMeans
plt.subplot(122)
kmeans=KMeans(n_clusters=2,random_state=42)
kmeans.fit(X)
plt.scatter(X[:,0],X[:,1],c=kmeans.labels_)
plt.title('KMEANS')

plt.show()

在这里插入图片描述
可见kmeans并没有达到我们的分类效果

总结

DBSCAN算法具有以下特点:

  • 不需要事先设定簇的个数。
  • 能够识别任意形状的簇。
  • 能够识别噪声点。
  • 对参数的设定比较敏感,但是通常只需要调整两个参数:半径 ϵ \epsilon ϵ和最小样本数 M i n P t s MinPts MinPts

但是dbscan在图像切割中,发现一个问题,如果min_samples设置太小,会导致图像切割后没有明显变化,如果设置太大,有些密度较小的点就会被当噪声去掉,导致图像损失,与原来的shape不一致,目前还没有好的处理方法,后期如果有解决方法,第一时间分享。

由于本人能力有限,上述内容有任何错误,欢迎指正
==我会继续努力分享学习,希望大家多多支持

猜你喜欢

转载自blog.csdn.net/qq_61260911/article/details/130089960