スペクトラルクラスタリングによって、データをクラスタリング解析する手法を、実装・解説します。
本シリーズでは、Pythonを使用して機械学習を実装する方法を解説します。
各アルゴリズムの数式だけでなく、その心、意図を解説していきたいと考えています。
本記事ではSpectralClusteringを実装します。
以下のscikit-learnマップの黒矢印に対応します。
教師なしデータ→クラスター数既知→サンプル数1万以下→kMeans機能せず→[SpectralClustering]
です。
SpectralClusteringの実装
本記事では、moon型データと呼ばれる、半月上の2つのデータをクラスタリングします。
まずは、実際のデータ、kMeansによる分類、SpectralClusteringによる分類の結果を見てみます。
上図、真ん中のKMeansは中心点(★)からの距離でクラスターが決まります。
そのため、同心円状に広がっていないデータはうまく分類することができません。
一番下のSpectralClusteringでは、予想通りにきれいにクラスター分けできています。
実装コードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # 1:ライブラリのインポート-------------------------------- import numpy as np #numpyという行列などを扱うライブラリを利用 import pandas as pd #pandasというデータ分析ライブラリを利用 import matplotlib.pyplot as plt #プロット用のライブラリを利用 from sklearn import cluster, preprocessing #機械学習用のライブラリを利用 from sklearn import datasets #使用するデータ # 2:moon型のデータを読み込む-------------------------------- X,z = datasets.make_moons(n_samples=200, noise=0.05, random_state=0) # 3:データの整形------------------------------------------------------- sc=preprocessing.StandardScaler() sc.fit(X) X_norm=sc.transform(X) # 4:プロットしてみる------------------------------------------ %matplotlib inline x=X_norm[:,0] y=X_norm[:,1] plt.figure(figsize=(10,10)) plt.subplot(3, 1, 1) plt.scatter(x,y, c=z) plt.show # 4:KMeansを実施--------------------------------- km=cluster.KMeans(n_clusters=2) z_km=km.fit(X_norm) # 5: 結果をプロット----------------------------------------------- plt.subplot(3, 1, 2) plt.scatter(x,y, c=z_km.labels_) plt.scatter(z_km.cluster_centers_[:,0],z_km.cluster_centers_[:,1],s=250, marker='*',c='red') plt.show # 解説6:SpectralClusteringを実施--------------------------------- km=cluster.SpectralClustering(n_clusters=2, affinity="nearest_neighbors") z_km=km.fit(X_norm) # 7: 結果をプロット----------------------------------------------- plt.subplot(3, 1, 3) plt.scatter(x,y, c=z_km.labels_) plt.show |
解説6の部分が新しいので解説します。
km=cluster.SpectralClustering(n_clusters=2, affinity=”nearest_neighbors”)
これはクラスター数を2と設定し、affinity(親和性)をnearest_neighborsと設定しています。
affinityとはSpectralClusteringを実施する途中で、サンプルデータをグラフ行列に書き換えるのですが、そのグラフの作り方を設定しています。
ここでは、近いデータとつながるグラフを作成します。
それでは「結局、SpectralClusteringって何をやっていたの?」を説明します。
SpectralClusteringの心
正確な情報は以下をご覧ください。
●scikit-learnのSpectralClusteringの解説ページ
SpectralClusteringは教師なし学習の一種です。
データを自動的にクラスターに分けます。
このアルゴリズムはなかなか難しいです。
まずはスペクトルという言葉を理解する必要があります。
スペクトルというと、光をプリズムで7色に分解した光スペクトルや、音や信号を周波数で分解した周波数スペクトルといった言葉が一般的です。
ですがSpectralClusteringのスペクトルはもう少し抽象的で広い意味を持ちます。
ここでのスペクトルはスペクトル分解のことで、スペクトル分解とはデータを基底ベクトルの線形和で表現することです。
なんか難しい表現になりましたが、基本的には
「固有値と固有ベクトルで固有値分解するんだ~」くらいで大丈夫です。
つまりスペクトル分解とはおおざっぱには固有値分解のことです。
ではどの行列を固有値分解するのかですが、元データをグラフ行列にしたものを使用します。
ここでグラフ行列という新たな概念がでてきました。
グラフ行列の特性をきちんと理解するのは大変ですが、サンプルデータM個がそれぞれどのようにつながっているかを示す[M×M]の行列です。
どうつながっているかを決めるのがaffinityでの設定です。
本記事のコードでは近い点とはつながっているということにしています。
するとM個のサンプルが1つのグラフ行列で示されます。
ここでグラフ行列をクラスター数で、分割します(Ncut)。
今回の場合は2つのグラフになるようにグラフ行列を加工します。
こうして加工された[M×M]行列を固有値分解(スペクトル分解)し、固有ベクトルをクラスター数分だけ結合した行列を作成します。
今回は[M×2]の行列となります。
(2はクラスター数を2としたためです)
本記事の場合、元データがx,yの2次元だったので次元圧縮になっていませんが、もし元データの次元が3以上だった場合には、次元圧縮されたことになります。
そして導出された[M×2]の固有値ベクトル行列に、KMeansでクラスタリングします。
以上がSpectralClusteringでやりたいこととなります。
KMeansと異なり、データの集まり具合、くっつき具合でクラスターを作成できるため、同心円状になっていないデータも、うまくクラスター解析できます。
こちらのスライドはクラスター分解の説明が丁寧です。
以上、Pythonとscikit-learnで学ぶ機械学習入門|第10回:スペクトラル・クラスタリングでのクラスター分析でした。
次回は、GMM(Gaussian mixture models)について解説します。