
アンケートの回答結果や顧客ごとの指標を眺めていて、「似た者どうしをいくつかのグループにまとめられたら、施策や訴求を考えやすいのに」と感じたことはないでしょうか。
このように、データを似ているものどうしのグループに自動的に仕分ける分析手法をクラスタリングと呼びます。
クラスタリングにはいくつかの方法がありますが、その中でも「似ているものから段階的にまとめていき、まとまり方の全体像を樹形図で見せてくれる」のが、今回ご紹介する階層クラスタリングです。
こちらのノートでは、この階層クラスタリングを、カスタムチャートを使ってExploratory上で実行し、デンドログラム(樹形図)として可視化する方法をご紹介いたします。
階層クラスタリングとは、一つひとつのデータ(今回であれば回答者一人ひとり)を出発点として、互いに距離の近いものから順番にペアにまとめ、さらにそのまとまりどうしを結合していくことを繰り返して、最終的にすべてが一つの大きなグループになるまでの「まとまり方の階層」を明らかにする手法です。
この結合の過程は、デンドログラム(樹形図)と呼ばれる木の枝のような図で表現されます。

図の下のほうで早く結合しているものほど互いによく似ており、上のほう(併合距離が大きいところ)で結合しているものほど性質が離れている、という関係を一目で読み取ることができます。
あらかじめグループの数を決めておく必要がなく、図を見てから「このあたりで区切ると何グループになるか」を後から決められるのが、階層クラスタリングの大きな特徴です。
階層クラスタリングやデンドログラムが好まれる理由は、グループ数を事前に決めずに階層構造を丸ごと可視化できること、対象が数十〜数百件程度であれば一人ひとりの近さや外れ値まで追えること、そして樹形図という直感的な図で分け方を説明しやすいことにあります。
一方、クラスター数をあらかじめ決めて大量のデータを手早く分けたい場合はK-meansクラスタリングなどが向いており、データの規模や目的に応じて使い分けます。
階層クラスタリングでは、まとまり具合を測るための「数値の列」が必要になります。
今回はサンプルとして、90名分のアンケート回答データを使用します。回答者ごとに「価格満足度」「品質満足度」「サポート満足度」「デザイン満足度」「配送満足度」の5つの項目を5段階(1〜5)で評価したデータで、この5つの満足度スコアの近さをもとに回答者をグループ分けしていきます。

今回のデータでは、各回答者を識別する「回答者ID」と、クラスタリングの計算に使う5つの満足度スコア(「価格満足度」「品質満足度」「サポート満足度」「デザイン満足度」「配送満足度」)が該当します。
「回答者ID」はデンドログラム上で各回答者を示すラベルとして使い、満足度スコアの5列を使って回答者どうしの距離を計算します。「セグメント」や「性別」「年代」といったテキストの列は計算には使いませんが、後からクラスターの特徴を解釈する際に役立ちます。
このノートで使用するサンプルデータは、以下からダウンロードいただけます。手順を実際に試しながら読み進めたい場合は、こちらのデータをExploratoryにインポートしてお使いください。
データをインポートしたら、チャート・ビューを開き、チャートタイプの一覧から「カスタム(Rコード)」を選択します。

カスタムチャートでは、R言語のコードをエディターに直接記述して、自由な形式のチャートを描くことができます。
カスタムチャートを選択したら、エディターに、以下のRスクリプトを貼り付けます。
# ${DATA} は現在開いているデータフレームを指す特別な記法です。
df <- ${DATA}
# 回答者ID を行名に設定します。ここで設定した値がデンドログラムの各枝のラベルになります。
rownames(df) <- df$回答者ID
# クラスタリングに使う数値列を1つずつ指定します。
# (不要な列を外したい、別の列を加えたい場合は、この一覧を編集してください)
mat <- df %>% select(
価格満足度,
品質満足度,
サポート満足度,
デザイン満足度,
配送満足度
)
# 回答者どうしの距離を計算します。method は距離の測り方の指定で、
# "euclidean"(ユークリッド距離)は各項目の差の大きさをそのまま距離として扱う、最も一般的な方法です。
# 他の選択肢:
# "manhattan" … 各項目の差の絶対値の合計。外れ値の影響を受けにくい
# "maximum" … 最も差が大きい項目だけを距離とする(チェビシェフ距離)
# "minkowski" … ユークリッドとマンハッタンの一般化。dist(mat, method = "minkowski", p = 3) のように p で調整
# "canberra" / "binary" … も指定可能
d <- dist(mat, method = "euclidean")
# 階層クラスタリングを実行します。method は「まとまりのまとめ方」の指定で、
# "ward.D2"(ウォード法)はグループ内のばらつきが小さくなるようにまとめる方法で、
# 大きさの揃った解釈しやすいグループができやすい定番の手法です。
# 他の選択肢:
# "complete" … 最も離れたペアの距離を基準にする(最遠隣法)。コンパクトなグループができやすい
# "average" … すべてのペアの距離の平均を基準にする(群平均法)。中庸な方法
# "single" … 最も近いペアの距離を基準にする(最近隣法)。細長くつながりやすい
# "centroid" / "median" / "mcquitty" … も指定可能
# ※ "ward.D2" はユークリッド距離を前提とする手法です
hc <- hclust(d, method = "ward.D2")
# 日本語ラベルの文字化けを防ぐため、フォントを指定します。
# 下記の "HiraKakuProN-W3" は Mac 標準のヒラギノ角ゴです。
# Windows の場合は "MS Gothic" や "Yu Gothic" など、お使いの環境にある日本語フォント名に変更してください。
par(family = "HiraKakuProN-W3")
# デンドログラム(樹形図)を描画します。
plot(hc,
hang = -1, # 各ラベルの高さを一番下に揃えて見やすくします
main = "階層クラスタリング(ユークリッド距離・ウォード法)", # グラフのタイトル
xlab = "回答者", # X軸のラベル
ylab = "併合距離", # Y軸のラベル(グループが結合された距離。高いほど性質が離れています)
cex = 0.8) # ラベルの文字サイズ
# クラスター数を k = 3 として、3つのグループを色付きの四角で囲みます。
# (border に指定する色数を k と揃えると、各グループが別々の色で表示されます)
rect.hclust(hc, k = 3, border = c("#E8734A", "#4A90D9", "#5FB878"))

冒頭の ${DATA}
は「現在開いているアクティブなデータフレーム」を指すExploratoryの特別な記法です。
各行にコメントで補足を入れていますので、引数の意味を確認しながらお使いください。距離の計算に使う列は、後から差し替えやすいように列名を1つずつ指定する形にしています。
なお、par(family = ...) で指定している
"HiraKakuProN-W3"
はMac標準の日本語フォント(ヒラギノ角ゴ)です。Windowsでこのまま実行するとラベルが文字化けすることがありますので、その場合は
"MS Gothic" や "Yu Gothic"
など、お使いの環境にインストールされている日本語フォント名に変更してください。
スクリプトを貼り付けたら、「ビュー」ボタンをクリックします。

回答者一人ひとりが下端から枝分かれし、似た回答者どうしが低い位置で結合していくデンドログラムが表示されます。rect.hclust
で指定した通り、全体が3つのグループに色分けされた四角で囲まれ、どの回答者がどのグループにまとまったのかを視覚的に確認できます。

グループの数を変えたい場合は、スクリプト末尾の
rect.hclust(hc, k = 3, ...) の k
の値を変更します。たとえば4グループに分けたい場合は k = 4
とし、border
に指定する色も4色に増やしていただくと、それぞれのグループが別々の色で表示されます。
デンドログラムができたら、次の3つの観点で図を眺めてみましょう。いずれも、樹形図の「枝の分かれ方」と「結合した高さ(併合距離)」から読み取れる情報です。

まず、いくつのまとまりに分けるのが自然かです。図を下から上に見ていくと、低い位置では細かく結合していたものが、あるところで大きく間隔が空いて枝が分かれます。
この「結合が急に飛ぶ高さ」で横に線を引いて区切ると、無理のないグループ数を判断できます。今回のサンプルでは、併合距離10あたりで区切ると3つのまとまりに分かれ、それぞれが色付きの四角で囲まれています。
次に、どのまとまりが他から際立っているかです。他より高い位置(大きい併合距離)で全体から切り離されるまとまりほど、他と性質が離れた独立したグループだといえます。逆に、上のほうまで一緒にまとまっている枝どうしは、互いに似た性質を持つグループどうしということになります。

最後に、個々の対象(回答者)の近さと特異さです。図の下のほうで早く結合している回答者どうしは回答傾向がよく似ており、なかなか他と結合せず一本だけ高い位置まで伸びている枝があれば、その回答者は他と異なる特異な回答をした可能性があります。
ここで大切な注意点があります。デンドログラムから分かるのは、あくまで「どう分かれるか」「どれとどれが近いか」という構造の情報だけだという点です。
図に表示されているのは回答者IDという記号であり、色分けも「1つ目・2つ目・3つ目のまとまり」を示しているにすぎません。それぞれのまとまりが何を意味するかまでは、この図だけからは分かりません。各グループが具体的にどんな特徴を持つのかを知るには、次のセクションのように、クラスター番号をデータに付ける必要があります。
デンドログラムで全体像を確認した後、「各回答者がどのグループに属するか」という情報をデータそのものに列として追加したい場合があります。
追加しておくと、クラスターごとの満足度の平均を比べたり、セグメントとの関係を集計したりと、その後の分析に活用できます。
この場合は、チャートではなくステップメニューから操作します。
ステップの追加メニューで「計算を作成」の「1つの列」を選択します。

計算を作成するためのダイアログが表示されたら以下のコードを入力します。
cutree(hclust(dist(pick(where(is.numeric))), method = "ward.D2"), k = 3)

cutree
は先ほどのデンドログラムを指定した数(k = 3)で切り分けてグループ番号を割り当てる関数です。
なお、上記のコードは pick(where(is.numeric))
によって、そのデータに含まれるすべての数値列を対象にしています。
今回のデータのように数値列が満足度スコアだけであればこのままで問題ありませんが、クラスタリングに使いたくない数値列(IDや年齢など)が混ざっている場合は、次のように列名を1つずつ指定してください。
cutree(
hclust(
dist(pick(価格満足度, 品質満足度, サポート満足度, デザイン満足度, 配送満足度)),
method = "ward.D2"
),
k = 3
)

実行すると、各行(各回答者)に「1」「2」「3」といったクラスター番号を持つ新しい列が追加されます。

なお、クラスターの列は、「クラスター1」「クラスター2」「クラスター3」といった形で内部的に順序関係を持つカテゴリー型として扱いたいため、今回は順序付きカテゴリー(Factor型)に変換します。
「Cluster」の列ヘッダーメニューから、「データタイプを変換」の「Factor(順序月文字列)型に変換」を選択します。

すると計算を作成のダイアログが開くので、そのまま実行します。

これでCluster列をFactor型に変換できました。

なお、デンドログラムの色分けやこのクラスター番号は「どのまとまりに属するか」を示すだけで、そのまとまりが「価格を重視する層」なのか「品質を重視する層」なのかまでは教えてくれません。番号のままでは、まだ中身の分からないグループにすぎないのです。
そこで、追加したクラスター番号を使って集計や可視化することで、各グループの特徴を調べることが可能です。
例えば、クラスターを色で分割したレーダーをチャートを作成することで、各グループの特徴を調べることが可能です。
