3
2

SPSS Modelerで最適なクラスター数(のヒント)を探してみる その2

Last updated at Posted at 2024-07-31

前回の記事からの続きです。

さて、今回は予告通りに、SPSS Modelerの拡張ノードを利用してシルエットスコアや誤差平方和(SSE)を計算して最適なクラスター数を推定してみます。

シルエットスコアとは(再掲)

シルエットスコア(Silhouette Score)は、クラスタリングの効果を評価するために使用される指標の一つです。このスコアは、各データポイントがどの程度適切にクラスタリングされているかを数値で示します。具体的には、クラスタ内の凝集度とクラスタ間の分離度を用いて計算されます。
シルエットスコアは -1 から 1 の範囲で、1 に近いほどクラスタリングの品質が高いことを示します。スコアが 0 に近い場合は、クラスタの境界が曖昧であることを示し、負の値はクラスタリングが不適切である可能性があります。
引用 :

※.引用元のそのままの内容を記載させていただいております。

エルボー法(再掲)

エルボー法は、それぞれのクラスター内の誤差平方和(SSE)を計算し、クラスター数とそれぞれの誤差平方和の和をプロットして適切なクラスター数を判断する手法です。エルボー(肘)のように曲線が折れ曲がる点が適切なクラスター数と考えます。

image.png

SPSS Modelerの拡張ノード

 
さて今回は、SPSS ModelerでRやPythonのシンタックスを記述してデータ加工やモデル作成が行える拡張ノードを利用します。以下のように5種類あります。本記事では、拡張の出力ノードを利用します。あれ?拡張モデルではないの?と思われる思いますが、スコアリングなどしないなら、出力ノードでもモデル作成と精度確認などができます。(次回、スコアリング用に拡張モデルの利用方法を紹介しようと思います。)

image.png

記述できるシンタックスは R、Python for Spark、Pythonの3種類。v18.5でPythonが追加されました。

image.png

Python for SparkとPythonの違いは何のか?v18.4以前のバージョンの拡張ノードでPythonを使う場合は、「Python for Spark」のみの選択が可能であり、SparkのDataFrameにデータが読みこまれていましたが、新しくネイティブの「Python」が選択可能になり、pandasのDataFrameに読み込むことが可能になりました。 ネイティブ Python APIを使うと、Python for Sparkに比較して、初回の実行のオーバーヘッドが大幅に削減されます。

ということでパフォーマンスなどが向上しています。但し利用するPythonをModelerに同梱されているものから変更できないなど不便な部分もあります。Python for Sparkでは、自身で導入したPythonを指定して利用することができます。ご利用は計画的に。

今回はv18.4以前のユーザーでも参考になるように、Python for Sparkでやってみます。

拡張の出力ノードでシルエットスコア・SSEを計算する

前回に引き続き、使用するデータは、みんな大好きirisのデータです。

データダウンロード先 :

SPSS Modelerは v18.5を利用します。(本記事の内容はバージョン18.5でなくても問題なく実行できます。)

1. 作ったストリーム その2

入力データもirisなので特に加工などせずシンプルなストリームです。
各ノードの設定については、入力ノードとデータ型ノードは前回と同じ設定ですので、説明は割愛します。
また、拡張モデルノードとナゲットがありますが、今回は割愛します。(一応、クラスタリングの結果をModelerで確認できるようにモデルも作成してみました。)

image.png

2. 拡張の出力ノード シンタックス

① シンタックス全体

k-meansシンタックス

#---------------------------------------------------------
# 必要なライブラリインポート
#---------------------------------------------------------
#SPSS用ランタイム
import spss.pyspark.runtime
#K-Means
from sklearn.cluster import KMeans
#シルエットスコア計算
from sklearn.metrics import silhouette_score

#---------------------------------------------------------
# データ読込処理
#---------------------------------------------------------
#コンテキスト取得
ascontext = spss.pyspark.runtime.getContext()

#データフレーム形式によるデータ読込
sdf = ascontext.getSparkInputData()
#Pandasに変換
pdf = sdf.toPandas()

#---------------------------------------------------------
# 説明変数、目的変数の設定
#---------------------------------------------------------
#入力データのスキーマ読み込み
inputSchema = ascontext.getSparkInputSchema()

#スキーマから変数名、ロールを参照して説明変数を設定
#変数準備
predictors =[]
#カラム分ループ
for col in inputSchema:

    #説明変数ロール判定 - 入力
    if col.metadata['role']=='input':
        #説明変数配列に追加
        predictors.append(col.name)
 
print("説明変数 = ")
print( predictors )
#---------------------------------------------------------
# シルエットスコア算出
#---------------------------------------------------------
#For文で繰り返す
#クラスタ数を指定
for k in range(2,10):
    # k-meansクラスタリング
    model = KMeans(n_clusters=k, random_state=0)
    #結果を取得
    KM_Predict = model.fit_predict(pdf[predictors])

    # シルエットスコアの計算
    score = silhouette_score(pdf[predictors], KM_Predict)

    #結果出力
    print("With K = " + str( k ) )
    print("Silhouette = " + str(score))
    print ('SSE: %.2f'% model.inertia_)

②. シンタックス詳細

 では、パート毎に説明していきます。

a. ライブラリの読み込み

 ここでは、SPSS Modeler上でPythonを利用する時に必要なライブラリと、K-meansモデル、シルエットスコア計算用のライブラリをインポートしています。
※.事前にscikit-learn(sklearn)をPython環境にインストールしておいてください。

k-meansシンタックス ライブラリ読み込み

#---------------------------------------------------------
# 必要なライブラリインポート
#---------------------------------------------------------
#SPSS用ランタイム
import spss.pyspark.runtime
#K-Means
from sklearn.cluster import KMeans
#シルエットスコア計算
from sklearn.metrics import silhouette_score

b. データの読み込み

 SPSS ModelerからSparkデータフレーム形式でデータを受け取り、Pandasデータフレーム形式に変換します。

k-meansシンタックス データ読み込み

#---------------------------------------------------------
# データ読込処理
#---------------------------------------------------------
#コンテキスト取得
ascontext = spss.pyspark.runtime.getContext()

#Sparkデータフレーム形式によるデータ読込
sdf = ascontext.getSparkInputData()
#Pandasデータフレームに変換
pdf = sdf.toPandas()

c. 説明変数の設定

 データ型ノードで設定したロールを参照して、K-meansに入力するデータを定義します。K-meansには説明変数のみでいいので、ロールが”入力”のデータのみ選択しています。

k-meansシンタックス 説明変数定義

#---------------------------------------------------------
# 説明変数、目的変数の設定
#---------------------------------------------------------
#入力データのスキーマ読み込み
inputSchema = ascontext.getSparkInputSchema()

#スキーマから変数名、ロールを参照して説明変数を設定
#変数準備
predictors =[]
#カラム分ループ
for col in inputSchema:

    #説明変数ロール判定 - 入力
    if col.metadata['role']=='input':
        #説明変数配列に追加
        predictors.append(col.name)


d. K-meansモデルの作成、シルエットスコア・SSE計算

 ループしてクラスター数を変えながらK-meansモデル作成、シルエットスコア算出、SSE算出をしています。
 SSEは、inertia_関数で計算できます。

k-meansシンタックス 説明変数定義
#---------------------------------------------------------
# シルエットスコア算出
#---------------------------------------------------------
#For文で繰り返す
#クラスタ数を指定
for k in range(2,10):
    # k-meansクラスタリング
    model = KMeans(n_clusters=k, random_state=0)
    # 結果を取得
    KM_Predict = model.fit_predict(pdf[predictors])

    # シルエットスコアの計算
    score = silhouette_score(pdf[predictors], KM_Predict)

    #結果出力
    print("With K = " + str( k ) )
    print("Silhouette = " + str(score))
    print('SSE: %.2f'% model.inertia_)

3. シルエットスコア・SSEを確認する

拡張の出力ノードを実行して、結果を確認します。

image.png

With K = 2 ←クラスター数
Silhouette = 0.6808136202936816 ←シルエットスコア
SSE: 152.3 ←SSE

上記のようにクラスター数が9まで結果が出力されています。

また、SSEとクラスター数の関係をグラフ化すると下図のようになります。クラスター数3のあたりで肘が曲がったようなグラフになっていますね??(まぁ、実際の分析できれいに特徴がでることは稀だと思います)。シルエットスコアも考慮するとひとまず、クラスター数は3を目安にしていいのではないでしょうか。

image.png

まとめ

前回と今回の記事で、SPSS Modelerで最適なクラスター数を探す指標となるシルエットスコア・SSEの確認方法を紹介しました。
最終的には各クラスターの特徴を確認して分析者がクラスター数やパラメータを調整することになります。が、きちんした指標をもとにしてクラスタリングをしたというひとつの根拠にもなりますので、ぜひ活用してみてください。

次回はせっかくなので、拡張モデルノードを使ってクラスタリング結果を確認してみます。

参考情報

SPSS Modeler ノードリファレンス目次

SPSS Modeler 逆引きストリーム集(データ加工)

SPSS funさん記事

SPSS連載ブログバックナンバー

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2