t_kahi’s blog

KNIMEやCellProfiler、創薬に関する記事と,日々のメモです

【KNIME】KNIMEでクラスタリング(3):DBSCAN

こんばんは,@PKです.

これまでk-meansや階層型クラスタリングなどのでクラスター分析について紹介しました.

www.t-kahi.com

www.t-kahi.com

今回はKNIMEでDBSCANクラスリングについて紹介します.

DBSCANについて

DBSCANはDensity-based spatial clustering of applications with noiseという名前のクラスタリングアルゴリズムの一種です.

これは密度準拠クラスタリング(英語版)アルゴリズムである。ある空間に点集合が与えられたとき、互いに密接にきっちり詰まっている点をグループにまとめ(多くの隣接点を持つ点、en:Fixed-radius_near_neighbors)、低密度領域にある点(その最近接点が遠すぎる点)を外れ値とする。DBSCAN は最も一般的なクラスタリングアルゴリズムのひとつであり、科学文献の中で最も引用されている。
DBSCAN - Wikipedia

下記説明がわかりやすいです.
scikit-learnでDBSCAN(クラスタリング) - Qiita
How DBSCAN works and why should we use it? - Towards Data Science

このクラスタリング手法の特徴として,クラスタ数を設定しなくても良い点や,球場でないクラスタも分類できる(k-meansなどは球状を仮定)点があります.

DBSCANもきちんとノードが用意されています(試しやすくてありがたい!).
nodepit.com

DBSCAN

今回紹介するDBSCANのWorkflowを以下に示します.
f:id:t_kahi:20190815235115p:plain

前回k-meansではうまくクラスターに分けられなかった三日月状のクラスターを分割してみます. 今回も「DBSCAN」ノードによるクラスタリングと同様の解析をRとPythonノードで処理した場合を紹介します.

サンプルデータ作成

サンプルデータを「Python Source」を使って作成します.

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
from IPython.display import display
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler

X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
output_table = pd.DataFrame(X_scaled)

今回は散布図として表示していませんが,出力結果は下図のようになります.
f:id:t_kahi:20190817002902p:plain

「DBSCAN」ノード

KNIMEでのDBSCANは,「Numeric Distance」でデータ間の距離を計算し,その後に「DBSCAN」でクラスタリングを行います.
f:id:t_kahi:20190817080951p:plain

「Numeric Distance」では計算したいカラムを決め,距離計算の手法を決めます.手法はEuclidean,Manhattan,cosine distanceを選択することができますが,今回はEuclideanを選びました.
ノードを実行すると,"distance measure"出力ポート(灰色■)に結果が出力されるのでDBSCANの入力ポートに繋げます.

続いて,DBSCANの設定です.距離計算をする前のデータと"distance measure"で出力された距離の情報をそれぞれ入力します.

DBSCANでは下記のようにクラスタを決定していくため,設定パラメーターは距離εとminPtsの2つとなります.

DBSCAN クラスタリングの目的として、点は、コア点(core points)、(密度)到達可能点、外れ値に分類される。以下のように行う。

  • 点 p がもし、p を含め、距離 ε(ε は p からの近傍の最大半径)以内に少なくともminPts の点があれば、その点はコア点である。
  • 点 q がもし、各 pi+1 が pi から直接到達可能(パス上のすべての点は、 q の可能な例外を持つ、コア点で無ければならない。)な、p1 = p かつ pn = q であるパス p1, ..., pn があれば、q は p から到達可能である。
  • 他のどの点からも到達可能でないすべての点は外れ値である。
    DBSCAN - Wikipedia

「Color Manager」でクラスタごとに色をつけて,「Scatter Plot」で可視化した結果を以下に示します.
f:id:t_kahi:20190817083028p:plain

目視で認識したクラスタごとに別れていますね!

Python Script (1⇒1)」

DBSCANをPythonのscikit-learnを使って同様に行います.

from sklearn.datasets import make_blobs
from sklearn.cluster import DBSCAN
import pandas as pd

dbscan = DBSCAN(eps=0.5, min_samples=2)
predict = pd.DataFrame(dbscan.fit_predict(input_table),columns=['predict'])

print(predict)

new_input = input_table.reset_index(drop=True)
print(new_input)

results = new_input.join(predict)

output_table = results.reset_index()

出力された結果を「Python View」で可視化します.

from io import BytesIO
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from IPython.display import display
import seaborn as sns

# Create buffer to write into
buffer = BytesIO()

sns.set_style("whitegrid")

data = input_table

image = plt.scatter(data['0'], data['1'], c=data["predict"])

# Create plot and write it into the buffer
image.get_figure().savefig(buffer, format='svg')
# The output is the content of the buffer
output_image = buffer.getvalue()

出力結果を以下に示します.
f:id:t_kahi:20190817083437p:plain

「R Snippet」

同様に,Rでも階層型クラスタリングの例を示します.

library(dbscan)

data <- knime.in


data.db <- dbscan(data, eps = 0.5, minPts = 2)

result <- data.db$cluster

knime.out <- data.frame(data, result)

出力された結果を「R View」で可視化します.
dbscanパケージを使用しました.

#R VIew (workspace)  
library(ggplot2)

data <- knime.in

p <- ggplot(data, aes(x=X0,y=X1,col=result)) + 
  geom_point()
p

出力結果を以下に示します.

f:id:t_kahi:20190817083613p:plain

終わりに

DBSCANは実はあまり馴染みがないクラスタリング手法でしたが,非球状のクラスタに適応できる点やクラスタ数を決める必要がない部分などは面白いと感じました.
KNIMEでできるクラスタリング手法についていくつか紹介してきましたが,k-means,階層型クラスタリング,DBSCAN以外にもクラスタリングの手法は用意されていますので,また機会があれば紹介したいと思います.

最後に動画を紹介します.

youtu.be