2018.04.15 Sun |

Pythonでのクラスタリング2

前回に引き続き、Pythonでのクラスタリングを行っていきましょう。

前回行った、データの読みこみや、標準化、データの分割は、再度行いません。前回のコードをすべて実行したままの環境であるという前提で以下を実行していきます。

kmeansでは、fitメソッドで学習した後、predictメソッドで所属クラスターを予測するということをしました。sklearnライブラリでのクラスタリングでは、predictメソッドがなく、testデータセットに関してどのクラスターに属するかを予測できないものがあります。
まずは、predictメソッドがあって、testデータセットがどのクラスターに属するかを予測できるものをご紹介し、
その次に、predictメソッドがなくて、testデータセットがどのクラスターに属するかを予測できないものをご紹介していきたいと思います。

#predictメソッドがあるもの1
#GaussianMixture
#http://scikit-learn.org/stable/modules/generated/sklearn.mixture.GaussianMixture.html#sklearn.mixture.GaussianMixture
#GaussianMixtureモジュールのインポート
from sklearn.mixture import GaussianMixture
#インスタンスの作成
GM = GaussianMixture(n_components=2)
#学習用説明変数での学習
GM_fit = GM.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#テストデータのラベル予測
prediction = GM_fit.predict(test_X_scaled)
#混合行列の作成
metrics.confusion_matrix(prediction,test_y)

#対角線にあたる数値が大きい(67と92)ので、良性乳ガンと悪性乳ガンがしっかり分けられているのが分かると思います。
#実際他のデータでGaussianMixtureModelを使ったことがあるのですが、そちらでも精度は良かったです。
#ただ、0が多いデータに関しては、予測が上手くいかなかった経験があります。巨大なデータに対して適用できないというのもたまに見かけるので(個人的に経験したことはありませんが)、いろいろ試してみるのが良いと思います。個人的には数百、数千サンプルくらいで、0でない中身がある場合は、うまくクラスタリングできました。

#predictメソッドがあるもの2
#Birch
#http://scikit-learn.org/stable/modules/generated/sklearn.cluster.Birch.html#sklearn.cluster.Birch
#Birchモジュールのインポート
from sklearn.cluster import Birch
#インスタンスの作成
BRCH = Birch(n_clusters=2)
#学習用説明変数での学習
BRCH_fit = BRCH.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#テストデータのラベル予測
prediction = BRCH_fit.predict(test_X_scaled)
#混合行列の作成
metrics.confusion_matrix(prediction,test_y)
#これも対角線上の成分(60と97)がその他の二つ大きい値なので、上手くクラスタリングできたと言えるでしょう。

#predictメソッドがあるもの3
#AffinityPropagation
#http://scikit-learn.org/stable/modules/generated/sklearn.cluster.AffinityPropagation.html#sklearn.cluster.AffinityPropagation
#AffinityPropagationモジュールのインポート
from sklearn.cluster import AffinityPropagation
#インスタンスの作成
AfP = AffinityPropagation()
#学習用説明変数での学習
AfP_fit = AfP.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#テストデータのラベル予測
prediction = AfP_fit.predict(test_X_scaled)
#混合行列の作成
metrics.confusion_matrix(prediction,test_y)

#さて、ここで問題がおきました。予測ラベルが、2種類以上あります。元々良性か悪性かの2種類のラベルしかないデータなので、2種類のラベルで予測してほしかったのですが、AffinityPropagation()のハイパーパラメータには、いくつのクラスターを返すかという指定ができないみたいなんですね。(軽くsklearnのドキュメントを読んだ限り)なので、クラスター数を指定したいときは、他の手法を使った方が良いと言えるでしょう。

#predictメソッドがあるもの4
#MeanShift
#http://scikit-learn.org/stable/modules/generated/sklearn.cluster.MeanShift.html#sklearn.cluster.MeanShift
#MeanShiftモジュールのインポート
from sklearn.cluster import MeanShift
#インスタンスの作成
MST = MeanShift(n_jobs=-1)
#学習用説明変数での学習
MST_fit = MST.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#テストデータのラベル予測
prediction = MST_fit.predict(test_X_scaled)
#混合行列の作成
metrics.confusion_matrix(prediction,test_y)

#ここでも予測クラスが、2つ以上(ここでは7つ)になってしまいました。
#これも、MeanShift()において、クラスター数を指定することができないためです。(指定できるなら教えてください)
#もし、クラスター数を指定したい場合は他の手法が良いでしょう。

#それでは次に、predictメソッドがなく、fitで学習したときの学習用データに対するラベルを返すしかない手法をご紹介します。fitメソッドではなく、fit_predictメソッドを使うと、いきなりラベルを返すのでそれでも良いです。(fitメソッドだと、インスタンスのlabels_属性を取得する必要があるので少々二度手間です)

#predictメソッドがないもの1
#AgglomerativeClustering
#http://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html#sklearn.cluster.AgglomerativeClustering
#AgglomerativeClusteringモジュールのインポート
from sklearn.cluster import AgglomerativeClustering
#インスタンスの作成
A_Cluster = AgglomerativeClustering(n_clusters=2)
#学習用説明変数での学習
#AgglomerativeClusteringには、predictメソッドはなく、ラベルを返す、fitとfit_predictだけある
A_Cluster_fit = A_Cluster.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#混合行列の作成
metrics.confusion_matrix(A_Cluster_fit.labels_,train_y)
#対角線の部分(129と222)が相対的に大きいので、学習データに関しては、うまく良性乳がんと悪性乳がんを分けられているのがわかります。testデータセットに対する予測用のメソッドがないのが残念です。

#次にもう一つ、predictメソッドがないクラスタリング手法をご紹介します。

#predictメソッドがないもの2
#SpectralClustering
#http://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralClustering.html#sklearn.cluster.SpectralClustering
#SpectralClusteringモジュールのインポート
from sklearn.cluster import SpectralClustering
#インスタンスの作成
SC = SpectralClustering(n_clusters=2,n_jobs=-1)
#学習用説明変数での学習
SC_fit = SC.fit(train_X_scaled)
#metricsモジュールのインポート
from sklearn import metrics
#混合行列の作成
#metrics.confusion_matrix(prediction,test_y)
metrics.confusion_matrix(SC_fit.labels_,train_y)
#これは、対角線上でなく上二つが相対的に大きくなっており、大部分が一つのクラスターに属するという結果になっており、(今回は203+142=345、51+2=53、の二つのクラスターに分かれるという結果になったが、実際の良性乳ガンと悪性乳ガンの比率はここまで極端ではないので不適切)、このクラスタリング手法(正確にはこのハイパーパラメータでのこのクラスタリング手法)より他の物を使った方が良いことがわかる。

ということで、今回はここまで。

鈴木瑞人
東京大学大学院新領域創成科学研究科メディカルゲノム専攻 博士課程
株式会社パッパーレ 代表取締役(https://www.pappare.co.jp/)
NPO法人Bizjapan テクノロジー部門BizXチームリーダー(http://bizjapan.org/en/)
実践的機械学習勉強会 代表( https://0f1304e65103e294f80c0307ba.doorkeeper.jp/ )

2024.9  
未経験者必見!『キャリアリターン採用』開始しました  詳しく