商品企画やマーケティング部に方々から、コレスポンデンス分析(コレポン、対応分析)のご要望をいただくことがあります。
Modelerの標準機能には無いため、IBM SPSSの別製品であるStatistics(IBM SPSS Statistics Base + IBM SPSS Categories)を使うことになります。
とは言え、Modelerでコレポンしたい!という気持ちもあります。
オープンソースでよければ、Pythonのmcaパッケージで多重コレスポンデンス分析ができます。
そこで、今回はModelerの拡張ノードを使って、多重コレスポンデンス分析をしてみます。
※Pythonでのコレポンはこちらの記事で紹介しています
分析テーマ例
飲料メーカーの商品イメージについてアンケート調査した結果から、商品とイメージのポジショニングを把握し、新規商品開発に役立てます。
実行環境
- IBM SPSS Modeler Client 18.3
- Python 3.8.6 ※Modeler同梱
作業ポイント
最初は拡張出力ノードを使ってみたのですが、Pythonのグラフ表示機能に対応していないようで、ポジショニング・マップを表示できませんでした。
そこで、拡張変換ノードでPythonのコレスポンデンス分析を行い、第1・2主成分のスコアを取得してから、散布図ノードでグラフを作ってみます。
- クロス集計表の読み込み
- 拡張変換ノードでコレスポンデンス分析
- ポジショニング・マップ(散布図)の作成
手順
1.mcaパッケージをインストール
Modelerで使用するPythonの指定方法やパッケージのインストール方法は、以下の記事をご参照ください。
2.クロス集計表を読み込む
今回はcsvファイルを使いますので、Modelerの[入力]パレットから「可変長ファイル」ノードを使用します。
ファイルには、以下のサンプルデータが含まれています。※手作りデータです
10商品(行)に対して、11のイメージ(列)があります。
アンケートで、各商品にそれぞれのイメージが当てはまるかどうか回答(Yes or No)してもらい、当てはまると回答された度数を集計したものです。
商品,高級感がある,お手頃価格,目が覚める,リラックスできる,よく飲む,たまに飲む,香り高い,あっさりしている,コクがある,渋みがある,おしゃれな感じ
エチオピア,22,28,36,46,5,4,26,13,6,3,7
カフェラテ,0,0,3,4,2,4,0,2,0,0,0
カプチーノ,7,11,17,23,4,5,2,4,3,2,5
グアテマラ,5,0,5,7,2,1,1,5,3,1,2
ココア,0,1,3,4,2,5,6,1,0,0,0
ブラジル,17,23,4,0,3,2,23,0,0,1,0
モカ,6,8,13,30,6,1,17,1,11,2,6
季節の果汁,5,7,16,23,2,2,5,6,5,3,5
煎茶,6,1,8,6,2,1,13,26,16,28,2
抹茶ラテ,27,13,16,2,2,12,0,2,1,2,10
3.拡張変換ノードを接続
[レコード設定]パレットから「拡張の変換」ノードを選択し、先ほどの「可変長ファイル」ノードから繋ぎます。
4.「拡張の変換」ノードを開き、「Python for Spark」を選択
5.「Pythonシンタックス」に下記を記述
#ライブラリのインポート
import mca #コレスポンデンス分析
import numpy as np
import pandas as pd
#Modeler用
import spss.pyspark.runtime
from pyspark.sql.types import *
asContext = spss.pyspark.runtime.getContext()
sparkContext = asContext.getSparkContext()
sqlContext = asContext.getSparkSQLContext()
#データの読み込み
inputData = asContext.getSparkInputData() #前ノードからのデータ読込
pdf = inputData.select("*").toPandas() #pandasデータフレームワークに変換
indnm = pdf.columns[0] #1列目の列名(商品)を取得
df = pdf.set_index(indnm) #1列目の値(商品名)をインデックスに設定
#多重コレスポンデンス分析を実行
mca_counts = mca.MCA(df)
rows = mca_counts.fs_r(N=2) #商品(行)の成分スコア Nは保持する成分の数
cols = mca_counts.fs_c(N=2) #イメージ(列)の成分スコア Nは保持する成分の数
#商品(行)の成分スコアでデータフレームを作成
df_rows= pd.DataFrame(
rows,
columns = ['第1成分','第2成分']
)
rownm = df.index
df_rows.insert(0, 'クロス集計', '行') #グラフプロット時に形状を指定するために使用
df_rows.insert(1, '対象', rownm)
#イメージ(列)の成分スコアでデータフレームを作成
df_cols= pd.DataFrame(
cols,
columns=['第1成分','第2成分']
)
colnm = df.columns
df_cols.insert(0, 'クロス集計', '列') #グラフプロット時に形状を指定するために使用
df_cols.insert(1, '対象', colnm)
#上記2つのデータフレームを結合
dfall = pd.concat([df_rows, df_cols])
#スキーマを作成(後続ノードに渡すフィールド(カラム)を設定)
fieldList =[
StructField('クロス集計',StringType(),True),
StructField('対象',StringType(),True),
StructField('第1成分',FloatType(),True),
StructField('第2成分',FloatType(),True)
]
outputSchema = StructType(fieldList)
#Modelerで使用 後続ノードに渡すデータ
if asContext.isComputeDataModelOnly():
outputData = sqlContext.createDataFrame(dfall)
asContext.setSparkOutputSchema(outputSchema)
else:
outputData = sqlContext.createDataFrame(dfall)
asContext.setSparkOutputData(outputData)
6.散布図ノードを接続
[グラフ]パレットから「散布図」ノードを選択し、「拡張の変換」ノードから繋ぎます。
7.散布図を作成
以下のように設定し、[実行]をクリックします。
- Xフィールド:第1成分
- Yフィールド:第2成分
- 色:対象
- 形状:クロス集計
下図のようなグラフが表示されます。※編集後のグラフです
こちらはModelerのグラフを[編集モード]で加工したもので、背景、フォント、枠線の変更や、凡例内の並べ替えなどを行いました。
Modelerのグラフは、デフォルトだとかなりクラシックな感じがする、と個人的には思います。
しかし、グラフの機能は豊富で、スタイルを変更したり、自分で編集した設定内容をノードに保存したり、デフォルトとして適用することもできます。
報告書の作成にも便利ですので、ぜひお試しください。
プロットされているものの名前とスコアは、マウスオーバーすると表示されます。
以上、Modelerで多重コレスポンデンス分析をしてみました。
※データの検定や結果の解釈などは省略
注意・改善ポイント
- スキーマでのデータ型の都合上、小数点以下が第4位に丸められてしまいます…
が、ポジショニング・マップで全体を把握できれば良いかな、と思います。 - グラフ上に全部の名前を表示できると嬉しいのですが…
Modelerの散布図ではできないようです。
また、拡張ノードでPythonのグラフも使えません。
拡張ノードのRスクリプトではグラフが表示できるようなので、Rでコレポンにチャレンジしてもよいかもしれません。
※参考
Python for Spark を使用したスクリプト – IBM Documentation
データのメタデータ – IBM Documentation
スクリプト例 – IBM Documentation
PySpark と pandas DataFrame 間の変換を最適化する
http://mogile.web.fc2.com/spark/sql-ref-datatypes.html