[クラスタリングアルゴリズム] 密度クラスタリングに基づくDBSCAN

どのブログでも、どのモットーでも、人は自分が思っている以上のことができる。
https://blog.csdn.net/weixin_39190382?type=blog

0. 序文

kmeansは一瞬で香りがなくなった気がします、ははは

説明:このアルゴリズムはクラスター化するだけでなく、外れ値を除去することもできます。クラスター化後、-1 のラベルが付いたノイズ ポイント (外れ値) を除去できます。
ここに画像の説明を挿入

1.本文

1.1 コンセプト

DBSCAN (ノイズを伴うアプリケーションの密度ベースの空間クラスタリング) 密度ベースの空間クラスタリング。密度に基づいてデータをクラスターに分割すると、ノイズの多い空間で任意の形状のクラスターを発見できるようになります。

1.1.1 視覚的な理解

今、その中にマイクロビジネスを発展させたいと考えている人たちがいます。ある人に近親者が増え、その数が5 人を超えた場合にのみ、マイクロ ビジネスは成功したと見なされます。このルールにより、群衆の中で異なる「零細企業グループ」を分割することが容易になり、つまりクラスタリングが実現されます。(短いですか、木がありますよ~)

1.2.2 一般的な概念

(1). 3種類のポイント

  • 核心点
  • 境界点
  • ノイズポイント

以下の図に示すように、ある点は、指定された半径内(距離を決定するために上記の直接の相対関係) 内に一定数の他の点 (上記は 5 より大きく、密度を決定するために使用されます) がある場合、このとき、その点はコアポイントと呼ばれます。

最終的なルールが満たされなくなるまで、半径を使用して「ダウンライン」を作成し続けます。最後の「ダウンライン」は境界点と呼ばれ、クラスターに含まれない点はノイズ ポイントです。
ここに画像の説明を挿入

(2). 4つの関係性

  1. P が中心点で、Q が P の近傍にある場合、P から Q への密度は直接であると言われます。
    • コアポイントから独自の密度への直接アクセス
    • 非対称まで密度を高めます。(P から Q への密度は直接的ですが、Q から P への密度は必ずしも直接的ではありません。注意:上記のマイクロビジネスの例はここでは間違っています。データ ポイント間の距離に注目すると、より理解しやすいはずです。)
  2. コア ポイントの密度 P1 から P2 に直接アクセスできる場合、P2 から P3 に密度に直接アクセスでき、...、Pn から Q に密度に直接アクセスでき、P1 から Q に密度にアクセスできます (密度も到達可能です)。 、対称性がありません、密度からの直接アクセスは対称性を持ちません、理解しやすいように比較する必要があります)
  3. コア ゾーン S があり、S から P および Q が密度 で到達可能である場合、P と Q は密度接続されており、密度接続は対称性を持ち、2 つの密度接続点は同じクラスター内にあります。
  4. 2 つの点が密度接続関係に属していない場合、2 つの点は密度接続されておらず、密度接続されていない 2 つの点は異なるクラスターに属しているか、それらの点にノイズが存在します。

以下の図を見て理解してください。
ここに画像の説明を挿入

1.2 アルゴリズムのステップ

  1. すべてのサンプル ポイントをトラバースします。指定した半径内のサンプルの数が指定した値より大きい場合、現在のサンプルがコア ポイントのリストに含まれ、直接密度を持つポイントが一時的なクラスターを形成します。
  2. 一時クラスターについて、その中のポイントがコア ポイントであるかどうかを確認し、コア ポイントである場合は、現在のポイントによって形成されたクラスターを現在のポイント自体の一時クラスターとマージして、新しい一時クラスターを取得します。(オフラインでの開発プロセス)
  3. このプロセスは、現在の一時クラスター内の各ポイントがコア ポイントのリストに含まれないか、その密度直接ポイントが既に一時クラスター内に存在するまで繰り返されます。この一時クラスターはクラスターにアップグレードされます。
  4. 残りの一時クラスターに対してこのプロセスを続けます。すべての一時クラスターが処理されるまで。

ここに画像の説明を挿入

1.3 デモ

説明: Jupyter Notebook で実行します

サンプルポイントの生成

%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import numpy as np
import pandas as pd
from sklearn import datasets


X,_ = datasets.make_moons(500,noise = 0.1,random_state=1)
df = pd.DataFrame(X,columns = ['feature1','feature2'])

df.plot.scatter('feature1','feature2', s = 100,alpha = 0.6, title = 'dataset by make_moon');

ここに画像の説明を挿入
クラスタリング

%matplotlib inline
%config InlineBackend.figure_format = 'svg'

from sklearn.cluster import dbscan

# eps为邻域半径,min_samples为最少点数目
core_samples,cluster_ids = dbscan(X, eps = 0.2, min_samples=20) 
# cluster_ids中-1表示对应的点为噪声点

df = pd.DataFrame(np.c_[X,cluster_ids],columns = ['feature1','feature2','cluster_id'])
df['cluster_id'] = df['cluster_id'].astype('i2')

df.plot.scatter('feature1','feature2', s = 100,
    c = list(df['cluster_id']),cmap = 'rainbow',colorbar = False,
    alpha = 0.6,title = 'sklearn DBSCAN cluster result');

ここに画像の説明を挿入

1.4 eps値の設定

1.4.1 方法 1: OPTICS アルゴリズム

from sklearn.cluster import OPTICS
from sklearn.datasets import make_blobs

# 生成随机数据
X, y = make_blobs(n_samples=1000, centers=3, random_state=42)

# 使用 OPTICS 算法自适应估计 eps 值
optics = OPTICS(min_samples=10, xi=0.05)
optics.fit(X)

# 输出聚类结果和估计的 eps 值
print("Estimated eps:", optics.eps_)
print("Cluster labels:", optics.labels_)

1.4.3 方法 2: K 距離

from sklearn.neighbors import NearestNeighbors
from sklearn.datasets import make_blobs

# 生成随机数据
X, y = make_blobs(n_samples=1000, centers=3, random_state=42)

# 计算 k-距离
knn = NearestNeighbors(n_neighbors=10)
knn.fit(X)
distances, indices = knn.kneighbors(X)

# 估计 eps 值
eps = distances[:, 9].mean()

# 输出估计的 eps 值
print("Estimated eps:", eps)

1.5 アニメーションの理解

お勧めのアニメーション Web サイト:
https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/

ここに画像の説明を挿入

1.6 ノイズポイント(外れ値)の表示

1次元データを表示する

def show_scatter_1D(data,labels,noise_black=False):
    plt.clf()
    if noise_black:
        noise_data = data[labels == -1, 0]
        plt.scatter(noise_data,np.zeros_like(noise_data), edgecolor='red',c='white', label='Noise')
    for l in set(labels) - {
    
    -1}:
        norm_data = data[labels == l, 0]
        plt.scatter(norm_data, np.zeros_like(norm_data), cmap='viridis', label=f'Cluster {
      
      l}')
    plt.legend()
    plt.show()

2Dデータを表示する

def show_scatter_2D(data,labels,noise_black=False):
    plt.clf()
    if noise_black:
        plt.scatter(data[labels == -1, 0], data[labels == -1, 1],edgecolor='red', c='white', label='Noise')
    for l in set(labels) - {
    
    -1}:
        plt.scatter(data[labels == l, 0], data[labels == l, 1], label=f'Cluster {
      
      l}')
    plt.legend()
    plt.show()

ここに画像の説明を挿入

参考

[1] https://blog.csdn.net/swy_swy_swy/article/details/106130675
[2] https://blog.csdn.net/Cyrus_May/article/details/113504879
[3] https://blog.csdn .net/huacha__/article/details/81094891#t0
[4] https://zhuanlan.zhihu.com/p/336501183
[5] https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/

おすすめ

転載: blog.csdn.net/weixin_39190382/article/details/131421107