【クラスタリング,python】DBSCANを使ってみる【異常検知,python】

DBSCANを使って簡単なクラスタリングをしてみます。

DBSCANとは(簡単に)

DBSCANは密度ベースのクラスタリングアルゴリズムの1つです。

k-meansと異なり最初にクラスター数を指定しなくてい良いのが特徴的な手法です。

DBSCANは、適当に点を決め、その周辺にデータがあればそのデータを同じクラスタ内のデータとして設定します。
そして、新たにクラスタに加えたこのデータに対してもそのデータの周辺にデータがあるかを確認して、少しずつクラスタを広げていきクラスタを決める手法です。

そして、密度が低い点を外れ値とみなします。

DBSCANの詳細に関しては別の文献を当たってみてください。

実装(sklearnを使って試してみる)

まず、必要なライブラリをインポートします。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from sklearn import datasets
from sklearn.cluster import DBSCAN

データを作ります。今回は非常にシンプルなデータセットを使ってみます。

X, Y = datasets.make_blobs(n_samples=200, centers=2, n_features=2, cluster_std=0.4, random_state=0)

作ったデータを見てみます。

plt.scatter(X[:, 0], X[:, 1], c="blue")

では、DBSCANを使って分類してみます。

設定すべきパラメータは、2つだけです。

  • 隣接点と判定する距離しきい値 eps
  • クラスタと判定する点数 min_samples
clustering = DBSCAN(eps=0.2, min_samples=2).fit(X)

クラスタリングした結果(ラベル)を見てみます。

この中で-1が外れ値(どのクラスタにも属さない)を示していて、それ以外をクラスタとしています。

clustering.labels_
# 以下出力
array([ 0,  0,  0,  0,  1,  2,  2,  3,  0,  2,  0,  0,  2,  2,  0,  2, -1,
        0,  0,  0,  0,  2,  2,  2,  1,  2,  0,  2,  0, -1,  2,  0,  0,  0,
        2,  2,  0,  0,  2,  2,  2,  4,  0,  2,  2,  0,  2, -1,  2, -1,  0,
        2,  2,  2,  0,  2,  1,  2,  0,  0,  0,  5,  2,  2,  1,  0,  0,  0,
        2,  2, -1,  2,  0,  0,  0,  0, -1, -1,  3,  0,  2,  0, -1, -1,  0,
       -1,  2,  0,  0,  0,  2,  3,  2,  2,  0,  0,  0,  2,  2,  0,  2,  0,
        2,  2,  2,  2,  2,  2,  0,  2,  4,  1,  2,  2,  2,  0,  0,  0,  0,
        0,  2,  0,  2,  0,  0,  0,  2,  0,  4,  2,  0,  2,  2,  0,  2,  6,
        2,  0,  0,  5,  2,  0,  2,  2,  0,  2,  2,  2,  0,  0,  0,  2,  2,
        2,  0,  2,  2,  0,  0,  0,  0,  1,  6,  4,  0,  0,  2,  2,  3,  3,
        0,  0,  0,  2,  0,  2,  2,  2, -1, -1,  0,  2,  0,  2,  2,  2,  0,
        0,  0,  2,  0,  2,  0,  0,  0,  0,  2,  6,  2,  2])

では、データにラベル付した結果を見てみます。

unique_labels = np.unique(clustering.labels_)
for label in unique_labels:
    x = X[np.where(clustering.labels_==label)]
    plt.scatter(x[:, 0], x[:, 1],label=label)
plt.legend()

こんな感じクラスタリングされています。まぁまぁ良い感じですね。

異常検知で使いたい場合には-1ラベルが付けられたデータが外れ値となっていますので、このデータが異常となります。

githubにもソースコードはあげてあります。

https://github.com/tocom242242/anomaly_detection/blob/main/%20simple_problem/DBSCA_simple_dataset.ipynb

参考文献

タイトルとURLをコピーしました