t_kahi’s blog

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

【KNIME】KNIMEでクラスタリング(1):k-meansでクラスター分析

こんばんは,@PKです.

クラスター分析といえば,階層型クラスタリングやk-meansなどが有名かと思いますが,KNIMEでもクラスター分析に関するノードがいくつか用意されています.

今回はクラスター分析に関するKNIMEノード紹介と,k-meansでクラスター分析を行った際のWorkflowを紹介します.

KNIMEでのクラスター分析

クラスタリング (英: clustering)、クラスタ解析(クラスタかいせき)、クラスター分析(クラスターぶんせき)は、データ解析手法(特に多変量解析手法)の一種。教師なしデータ分類手法、つまり与えられたデータを外的基準なしに自動的に分類する手法。また、そのアルゴリズム。 さまざまな手法が提案されているが、大きく分けるとデータの分類が階層的になされる階層型手法と、特定のクラスタ数に分類する非階層的手法とがある。それぞれの代表的な手法としてウォード法、K平均法などがある。
データ・クラスタリング - Wikipedia

クラスター分析は,上述の通り教師なし学習であり,階層型と非階層型に分けることができます.
KNIMEでは,階層型・非階層型の様々なクラスタリングのノードが用意されています.
f:id:t_kahi:20190728232033p:plain

KNIMEでのクラスタリングについて,上図で示しているDBSCAN,階層型クラスタリング,k-meansを3回に分けてご紹介します.

今回紹介するk-meansは非階層型クラスタリング手法です.
k-meansではまず,あらかじめ設定した数のクラスターをランダムに割り当てます.その後,クラスターの重心を計算し,1番近い重心のクラスターになるように再度クラスターが分けられます.この操作を,重心が変化しなくなるまで行いクラスターを決定します.

k-meansは多くの記事で分かりやすく紹介されています.
k平均法 - Wikipedia
クラスター分析の手法③(非階層クラスター分析) | データ分析基礎知識

KNIMEでもk-means専用ノードが用意されています.
nodepit.com
Performing a k-Means clustering – KNIME Hub

それではWorkflowの紹介です.

Workflowの概要

紹介するWorkfllowを以下に示します.
f:id:t_kahi:20190815202349p:plain
今回はサンプルデータを「Python Source」で生成し,k-meansでクラスタリングを行います.
サンプルデータは上図に示すように3つのクラスタに分かれるサンプルを作成しました.

k-meansでのクラスタリングは非常にシンプルなので,KNIME専用ノードとPython,Rのそれぞれでデータを分析した結果を示しておきます.

サンプルデータの作成

3つのクラスターを含むようなサンプルデータを「Python Source」で作成しました.
スクリプトはこちらを参考にしました.
Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

#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_blobs
X, y = make_blobs(random_state=42)
print(X)
print(y)
output_table = pd.DataFrame(X)

出力された結果を「Scatter Plot」で可視化します.
f:id:t_kahi:20190812161100p:plain

このデータをk-means手法を使ってクラスタリングします.

「k-means」でクラスター分析

「k-means」でのクラスター解析は非常にシンプルです.
まず「k-means」の設定画面でクラスターの数と,クラスターを分けるのに使用するカラムを選択します.
その後,出力されたクラスターのラベルが付いたカラムごとに「Color Manager」で色を付け,「Scatter Plot」で出力した結果を下図に示します.
f:id:t_kahi:20190815203328p:plain

例が非常にシンプルということもあり,きれいにクラスターが分かれています.
「k-means」の設定もクラスター数だけなので非常に扱いやすいと思います.

Python Script (1⇒1)」

続いてk-meansのクラスタリングPythonのscikit-learnを使って同様に行います.

#Python Script
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import pandas as pd

kmeans = KMeans(n_clusters=3)
kmeans.fit(input_table)

predict = pd.DataFrame(kmeans.predict(input_table),columns=['predict'])
new_input = input_table.reset_index(drop=True)

results = new_input.join(predict)

output_table = results.reset_index()

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

#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

buffer = BytesIO()

sns.set_style("whitegrid")

data = input_table

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

image.get_figure().savefig(buffer, format='svg')

output_image = buffer.getvalue()

Python Viewの出力結果を以下に示します.
f:id:t_kahi:20190812162943p:plain

「R Snippet」

同様に,Rでもk-meansのクラスター分析の例を示します.

#R Snippet
data <- knime.in

data.km <- kmeans(data,3)
result <- data.km$cluster

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

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

#R VIew
library(ggplot2)

data <- knime.in
plot <- ggplot(data, aes(x=X0,y=X1,col=result)) + 
  geom_point()
plot

「R View」の結果を以下に示します.
f:id:t_kahi:20190812163454p:plain

k-meansでうまく分けられない例

k-meansは原理もわかりやすく強力な手法ですが,クラスターの形によってはうまく分離できないケースもあります.

例えば,下記のような三日月形をしているクラスターはうまく分けるとこができないようです.
f:id:t_kahi:20190812163911p:plain

まとめ

今回示したように,KNIMEでk-meansを行うWorkflowは非常にシンプルで強力な手法だと思いますが,一方で,最後に示した例のように変な形をしているクラスターをうまく分けることができません. (2)や(3)で,一般的なクラスター分析手法の一つである階層型クラスタリングや,三日月形のクラスターをうまく分離できるDBSCANという手法について紹介します.

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

youtu.be