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にもソースコードはあげてあります。