論文一覧に戻る 📚 用語解説(ジャストインタイム型データサイエンス教育)
デンドログラム
Dendrogram
階層クラスタリングの結果を樹形図で表現したもの。縦軸は結合距離、横軸は個体。
可視化dendrogram樹形図
📍 文脈💡 30秒結論📖 詳しく🎨 直感図🎓 深掘り⚠️ 落とし穴🔗 関連用語

📍 あなたが今見ているもの

論文で階層クラスタリングの結果として登場する樹形図。 「デンドログラム」「樹形図」「ward 法のデンドログラムを示す」のような形で。 47都道府県のような中規模データの階層構造を可視化する最重要ツール。

デンドログラム とは:階層クラスタリングの結果を樹形図で表現したもの。縦軸は結合距離、横軸は個体。

💡 30秒で分かる結論

📖 もっと詳しく

デンドログラム(dendrogram, 樹形図)は、 階層クラスタリングの結果を樹形図の形で可視化したもの。 「どのサンプル同士が、 どの距離で結合するか」が一目で分かる、 階層クラスタリングの最終成果物です。

語源はギリシャ語 "dendron"(木)+ "gramma"(描いたもの)。 まさに「木の絵」。 生物学の系統樹(phylogenetic tree)も同じ概念で、 進化的近縁関係を樹形図で表します。

📐 デンドログラムの構造

デンドログラムは3要素から成ります:

底から上に向かって、 「最初は各サンプルが独立」→「順次結合」→「最後に全部1つに」という過程を表現。

📊 縦軸と横軸の意味

低い位置で結合する2サンプル = 似ている。 高い位置で結合 = 大きく異なる。

✂️ 切断線(cut line):クラスタ数の決定

デンドログラムの真の威力は「後からクラスタ数を決められる」こと。 任意の高さで横に切ると、 そこから下のサブツリーが「k 個のクラスタ」になります:

切断高さの決め方

  1. 事前理論:「4クラスタに分けたい」が決まっているなら、 上から4本目の枝が見える高さで切る
  2. 「肘」を探す:縦軸方向に急に枝が長くなる場所が自然な切断点。 「ここから上は急に距離が増える」位置
  3. 内部評価指標:複数の k でシルエット係数を計算し、 最良を選ぶ
  4. 逐次的分析:粗いクラスタ(k=2)から細かいクラスタ(k=8)まで全部見て、 各レベルでの解釈を比較

🎨 色分けの慣習

scipy の dendrogram() 関数では、 color_threshold パラメータで「ここから上は色分けしない」と指定すると、 自然なクラスタが色で区別されます:

デフォルトは「最大距離の 70%」。 これにより視覚的にクラスタ構造が際立ちます。

📊 47都道府県の例

SSDSE データを Ward 法でクラスタリングした典型的なデンドログラム解釈:

この階層構造から、 分析目的に応じた k を選べます。 細かく分析するなら k=8 で各地域圏に、 大きな区分なら k=2 で大都市 vs 地方に。

🔄 デンドログラムから読み取れる情報

デンドログラムは、 単にクラスタを示すだけでなく、 多くの情報を提供します:

  1. サンプル間の類似度の階層構造:「東京と神奈川は他より早く結合 → 最も似ている」
  2. 最適クラスタ数のヒント:「肘」の位置から自然な k が見える
  3. 異常値や孤立サンプル:極端に高い位置で結合する点は、 他から大きく離れた特異サンプル(沖縄など)
  4. サブグループの存在:上下に明確に分かれる構造があれば、 大きな2分構造が存在
  5. クラスタの密度:低い位置で多くの結合 = 密集したクラスタ

📉 デンドログラムの読み方の典型的失敗

失敗1:横軸の順序を意味あるものと思う

デンドログラムの横軸(葉の順序)は、 アルゴリズムの実装や枝の入れ替えで変わります。 「左から3番目だから」「真ん中だから」に意味はない。 重要なのは結合の高さと階層構造のみ。

失敗2:「最も似ている」を誤読

「2サンプルが隣同士に描かれている = 似ている」は誤り。 隣でも結合高さが高ければ似ていない。 必ず結合高さで判断。

失敗3:切断高さの恣意性

「だいたいここで切ろう」は主観的。 客観的な指標と組み合わせて決定すべき。

💻 Python での描画コード

▼ コード解説(階層クラスタリング(scipy.cluster.hierarchy))
🎯 解説: scipy.cluster.hierarchy.linkage で連結行列を計算。 method='ward' で Ward 法による最小分散クラスタリング。
📥 入力例: 47 県の特徴量行列(標準化済み) method='ward', metric='euclidean'
📤 実行例: Z = linkage(X, method='ward') shape: (46, 4) cluster ID と距離を保持
💬 読み方: Ward 法は「結合時の分散増加を最小化」する手法。 球状クラスタを発見しやすく、 都道府県データで最も使われる。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# 標準化
X_std = StandardScaler().fit_transform(X)

# 階層クラスタリング
Z = linkage(X_std, method="ward")

# デンドログラム描画
fig, ax = plt.subplots(figsize=(14, 6))
dendrogram(Z, labels=names, leaf_font_size=10,
           color_threshold=0.7*max(Z[:,2]),  # 自然なクラスタ色分け
           ax=ax)
ax.set_title("Ward 法によるデンドログラム", fontsize=14)
ax.set_ylabel("結合距離")
plt.tight_layout()
plt.show()

🎯 デンドログラムの応用

🎨 直感で掴む

デンドログラム
47都道府県のデンドログラム(Ward 法、 4変数標準化済み)。 縦軸が結合距離、 横軸が県名。 自然なグループが色で区別されている。

🎓 デンドログラムの理論と表現

ウルトラメトリック距離

デンドログラムが意味を持つには、 結合距離が「ウルトラメトリック」(ultrametric)という強い条件を満たす必要があります:

$d(x, z) \le \max(d(x, y), d(y, z))$

これは通常の距離の3角不等式 $d(x,z) \le d(x,y) + d(y,z)$ より強い条件。 これがあるおかげで、 樹形図として一意に表現できます。

結合基準によってはウルトラメトリックが破れ(中央連結など)、 樹形図に「逆転」(枝が交差)が起きます。 Ward 法、 単連結、 完全連結、 群平均では発生しません。

木の入れ替え可能性

デンドログラムには $2^{n-1}$ 通り の表示方法があります(各内部節点で左右の子を入れ替えられる)。 例えば 47県のデンドログラムは $2^{46} \approx 7 \times 10^{13}$ 通りの表示が可能。 でも階層構造(どこで結合するか)は同じ。

scipy では各実装が独自の順序で表示します。 多くの場合「リーフ間の距離を最小化する」順序(optimal leaf ordering)が使われ、 視覚的に分かりやすい配置になります。

同等表現:cophenetic 距離行列

デンドログラムから「2サンプル $x_i, x_j$ が結合した距離」を取り出した行列をcophenetic 距離行列と呼びます。

cophenetic correlation = (元の距離行列)vs(cophenetic 距離行列)の Pearson 相関。 これが大きい(0.7以上)と、 デンドログラムが元の距離構造を忠実に表現していることを意味します。 0.5以下なら、 階層クラスタリング自体が不適切な可能性。

系統樹との関係

生物学の系統樹(phylogenetic tree)もデンドログラムの一種。 種間の DNA 距離から進化的近縁関係を表現します。 ただし、 系統樹は「時間軸」(進化年代)を含むことが多く、 縦軸の意味が違います。

クラスタリングのデンドログラム:縦軸 = 不類似度
系統樹:縦軸 = 進化時間 or 遺伝距離

大規模データでの工夫

n が大きいと(n > 100)、 デンドログラムの葉が密集して読めなくなります。 対策:

⚠️ よくある落とし穴

❌ 横軸の絶対位置を意味あるものと思う
左右の入れ替えは結果を変えない。 「左から ○ 番目」に意味はない。 結合の高さと構造だけが重要。 ただし、 解釈時には「視覚的に近い」=「結合距離が近い」と誤読しがちなので注意。
❌ サンプル数が多すぎて読めない
n > 50 だと葉のラベルが重なって読めなくなる。 (i) truncate_mode で上位 N 個だけ表示、 (ii) ヒートマップと併用、 (iii) インタラクティブ可視化(plotly)、 (iv) サブツリーを別の図として詳細表示、 などの工夫が必要。
❌ 切断高さの恣意性
「だいたいここで切ろう」は主観的。 シルエット係数、 cophenetic correlation、 事前理論で客観的に決定。 「肘」が明確でないデータでは、 異なる切断高さでの解釈を全部試して比較。
❌ cophenetic correlation を確認しない
デンドログラムが元の距離構造を忠実に表現しているかは、 cophenetic correlation で確認。 これが 0.5未満なら、 階層クラスタリング自体が不適切。 別の手法(k-means、 DBSCAN)を検討すべき。
❌ 「樹形構造」と「クラスタ構造」を混同
デンドログラムは「強制的に階層構造を作る」アルゴリズム。 元のデータに本当に階層があるかは別問題。 ランダムデータでも一見もっともらしいデンドログラムが描けます。 統計的検証(permutation test、 bootstrap)も併用。
❌ 結合基準で結果が大きく変わるのを忘れる
Ward 法と単連結のデンドログラムは全く違って見えます。 報告時は必ず結合基準と距離尺度を明示。 「Ward 法・ユークリッド距離・標準化済み」のように。
❌ 系統樹と混同
生物学の系統樹は時間軸を持ち、 進化の時系列を表す。 クラスタリングのデンドログラムは不類似度を表すだけ。 縦軸の意味を取り違えると、 「進化的にこちらが先」のような不正確な解釈になる。

📊 47都道府県のデンドログラム

47県デンドログラム

家計5項目で Ward 法を実行した結果。 「色分けされたクラスタ」は事前に指定した閾値で切ったもの。 距離が大きいところで切れば、 数の少ない大きなクラスタに分かれます。

🧭 デンドログラムの読み方 — 5ステップ

  1. 底辺:各データ点(葉, leaves)。 ここでは47都道府県
  2. 横線の高さ:マージ時の「距離」。 高いほど離れた合体
  3. 縦線:マージされた2つのクラスタを繋ぐ
  4. 切断レベル:横の水平線で切ると、 その下のクラスタが残る
  5. クラスタ数:切る高さで決まる。 高く切れば少数の大クラスタ

切断位置の決め方

🎨 デンドログラムの拡張

① ヒートマップとの組合せ(clustermap)

seaborn の clustermap は、 行・列両方をクラスタリングしてヒートマップに重ねる強力なツール。

② 円形デンドログラム

系統樹のような円形表示。 多数の葉でも見やすい。

③ ファントグラム

生物分類でよく使われる、 デンドログラムに時系列情報を加えたもの。

🐍 Python での実装

① scikit-learn での基本

▼ コード解説(デンドログラム描画)
🎯 解説: scipy.cluster.hierarchy.dendrogram でツリーを可視化。 横軸が県、 縦軸が結合距離。
📥 入力例: Z, labels=都道府県名
📤 実行例: dendrogram.png 47 県のツリー構造 距離 5 付近で主要 4 クラスタに分割可能
💬 読み方: 結合距離が大きく跳ぶ点で切ると自然なクラスタ数が得られる。 縦軸の「ジャンプ」を見るのがコツ。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.cluster import KMeans, AgglomerativeClustering, DBSCAN
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
import pandas as pd
import numpy as np

# データの標準化(重要!)
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# k-means
km = KMeans(n_clusters=3, random_state=0, n_init=10)
labels_km = km.fit_predict(X_std)
print(f'クラスタ中心: {km.cluster_centers_}')
print(f'inertia: {km.inertia_}')

# 階層クラスタリング(Ward法)
agg = AgglomerativeClustering(n_clusters=3, linkage='ward')
labels_agg = agg.fit_predict(X_std)

# シルエットスコアで評価
score = silhouette_score(X_std, labels_km)
print(f'シルエットスコア: {score:.3f}')

② 最適クラスタ数の探索

▼ コード解説(クラスタ数の決定(cutoff))
🎯 解説: fcluster で結合距離の閾値を指定してクラスタ分割。 cutoff=5 で 4 クラスタなどに分割。
📥 入力例: Z, t=5, criterion='distance'
📤 実行例: clusters = array([1,1,2,3,...]) cluster 1: 都市圏 11 県 cluster 2: 中四国 9 県 cluster 3: 東北 6 県 cluster 4: 北海道・沖縄等
💬 読み方: 閾値の選定は地域の知識との整合性で決める。 自動化なら gap statistic や silhouette が定番。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import matplotlib.pyplot as plt

inertias = []
silhouettes = []
for k in range(2, 11):
    km = KMeans(n_clusters=k, random_state=0, n_init=10).fit(X_std)
    inertias.append(km.inertia_)
    silhouettes.append(silhouette_score(X_std, km.labels_))

# エルボー法
plt.subplot(1, 2, 1)
plt.plot(range(2, 11), inertias, 'o-')
plt.xlabel('k'); plt.ylabel('inertia')

# シルエット法
plt.subplot(1, 2, 2)
plt.plot(range(2, 11), silhouettes, 'o-')
plt.xlabel('k'); plt.ylabel('Silhouette')

③ デンドログラムの描画

▼ コード解説(複数のリンケージ法の比較)
🎯 解説: single, complete, average, ward の 4 つを比較。 同じデータでも構造が変わる。
📥 入力例: method=['single','complete','average','ward']
📤 実行例: Single: 細長いチェーン Complete: コンパクトな塊 Average: 中間 Ward: 等サイズに近い
💬 読み方: Ward が最も「自然なクラスタ」を出すことが多いが、 Single はチェーン構造の検出に有用。 用途で使い分け。
1
2
3
4
5
6
from scipy.cluster.hierarchy import linkage, dendrogram

Z = linkage(X_std, method='ward')
plt.figure(figsize=(14, 6))
dendrogram(Z, labels=labels, leaf_rotation=90)
plt.show()

📖 包括的解説 — この概念を完全マスター

📍 学習の3ステップ

  1. 定義を理解する:この概念は何か? 数式や条件を確認
  2. 具体例を見る:実データ(SSDSE 等)で計算してみる
  3. 応用する:自分のデータに適用、 結果を解釈

🔧 Python実装パターン

▼ コード解説(距離行列の事前計算)
🎯 解説: scipy.spatial.distance.pdist で距離行列を作成し、 linkage に渡す。 大規模データで有効。
📥 入力例: X (47, k), metric='euclidean'
📤 実行例: D = pdist(X) shape: (47*46/2,) = (1081,) 上三角ベクトル
💬 読み方: 距離行列を事前計算しておけば、 複数 method を試すときに再計算不要で高速。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 基本パターン
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns

# データ読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')

# 基本統計量
df.describe()

# 可視化
sns.pairplot(df[['食料費', '教育費', '住居費']])
plt.show()

📚 統計概念マップでの位置

このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。

🎯 SSDSE-B-2026 で挑戦

統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:

💡 よく使うコマンド集

機能 Python (pandas) Python (scipy)
要約統計df.describe()stats.describe()
平均df.mean()np.mean()
標準偏差df.std()np.std()
相関df.corr()stats.pearsonr()
t検定stats.ttest_ind()
回帰stats.linregress()
分布フィッティングstats.norm.fit()

🚧 一般的な落とし穴と対策

📊 結果報告の標準フォーマット

🌐 関連分野での応用

🎓 さらに学ぶための文献

🔗 統計用語ネットワーク

この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。

主要な関連概念のグループ

グループ 主要概念
記述統計平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数
可視化ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ
推測統計標本平均、 標準誤差、 信頼区間、 p値、 有意水準
確率分布正規分布、 t分布、 χ²分布、 F分布、 二項分布
仮説検定t検定、 F検定、 χ²検定、 ノンパラ検定
回帰単回帰、 重回帰、 OLS、 Ridge、 LASSO
分類ロジスティック回帰、 決定木、 SVM、 k-NN
教師なし学習クラスタリング、 PCA、 因子分析
時系列ARIMA、 VAR、 指数平滑法、 自己相関
因果推論DiD、 IV、 傾向スコア、 交絡変数
前処理標準化、 正規化、 欠損値処理、 多重共線性対策
評価R²、 残差、 CV、 RMSE、 効果量

学習順序の推奨

  1. 記述統計(平均、 分散、 標準偏差)
  2. 可視化(ヒストグラム、 散布図)
  3. 確率分布(正規分布)
  4. 推測統計(標準誤差、 信頼区間、 p値)
  5. 仮説検定(t検定、 χ²検定)
  6. 相関と回帰(単回帰、 重回帰)
  7. 多変量解析(PCA、 クラスタリング)
  8. 機械学習(決定木、 RF、 NN)
  9. 時系列・因果推論(応用)

📝 実践練習 — SSDSE-B-2026 で挑戦

初級課題

  1. 東北6県の家計食料費の基本統計量を計算
  2. 食料費のヒストグラムを描く
  3. 食料費と教育費の散布図を描く
  4. 都道府県を「東日本/西日本」に分け、 平均を比較

中級課題

  1. 家計支出 5項目で相関行列を作成、 ヒートマップ可視化
  2. 食料費 → 教育費の単回帰を実行、 残差分析
  3. 家計5項目で PCA を実施、 バイプロット表示
  4. k-means (k=3) で都道府県をクラスタリング、 解釈

上級課題

  1. 地域別の家計パターンに有意差があるか ANOVA で検定
  2. 重回帰で教育費を予測、 多重共線性を VIF で確認
  3. Ridge/LASSO で正則化、 CV で α を最適化
  4. 階層クラスタリングと Ward 法で都道府県を分類、 デンドログラム作成

🗺️ 概念マップ — 3つの視点で体系を理解する

デンドログラム がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。

📍 体系階層のパス

🌐 統計・データサイエンス教師なし学習クラスタリングデンドログラム

① 🔗 関係マップ — 「他の手法とどう繋がっているか」

中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移

凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先

② ⭕ 包含マップ — 「どのカテゴリに含まれているか」

大きな円が小さな円を包含する Circle Packing 図。 「デンドログラム」は緑色でハイライト

📍現在地:統計・データサイエンス

③ 🌳 ツリーマップ — 「面積で見るボリューム比較」

長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「デンドログラム」は緑色でハイライト

🎯 3つのマップの使い分け

マップ 分かること こんな時に見る
🔗 関係マップ手法間の横の関係(前提→発展→応用)「次に何を学べばよい?」 学習順序の判断
⭕ 包含マップ分類体系の入れ子構造(上位⊃下位)「この手法はどんなジャンルに属する?」
🌳 ツリーマップ分野の規模比較(面積=ボリューム)「データサイエンス全体の俯瞰像」

💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。

🔖 キーワード索引 — デンドログラムを多角的に理解する

デンドログラム(dendrogram、 樹形図)を確実に使いこなすための関連キーワードを難易度別に整理しました。

🟢 基礎キーワード(まず押さえる)

🟡 中級キーワード

🔴 上級キーワード

🧮 SSDSE-B-2026 実値計算例 — 47 都道府県を樹形図でクラスタリング

合成データではなく、 47 都道府県の家計支出(食料費、 教育費、 交通費、 通信費 4 変数)でデンドログラムを作成する手順を、 数値例で示します。

① データ準備と標準化

SSDSE-B-2026 から 4 変数を抽出します。 単位の異なる変数を扱うので、 標準化(z スコア化)が必須です。

▼ コード解説(距離指標の選択(euclidean, cosine, manhattan))
🎯 解説: metric='euclidean'/'cosine'/'cityblock' で距離指標を変更。 データ特性に応じて使い分け。
📥 入力例: Cosine: 方向のみ(角度) Euclidean: 絶対距離 Manhattan: L1 距離
📤 実行例: Cosine: 都市圏が 1 クラスタに集約 Euclidean: 似た構造 Manhattan: 異常値に頑健
💬 読み方: Cosine は「スケールを無視して向きで比較」。 都道府県の経済構造比較などで自然な結果が得られる。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 4 変数の平均と標準偏差(年間支出、 単位:千円、 仮想値)
食料費  平均 850 標準偏差 80
教育費  平均 120 標準偏差 35
交通費  平均 290 標準偏差 45
通信費  平均 140 標準偏差 18

# z スコア = (x - 平均) / 標準偏差
# 例:東京の食料費 1080 千円 → z = (1080-850)/80 ≈ +2.88
# 例:東京の教育費 220 千円  → z = (220-120)/35  ≈ +2.86

 東京は 4 変数すべてで上位の特異値 個別クラスタになる傾向

② ユークリッド距離行列の概略

標準化後、 都道府県ペアごとのユークリッド距離 d(A, B) = √Σ(z_Aᵢ − z_Bᵢ)² を計算します。 47 都道府県なら 47×46/2 = 1081 ペア。

▼ コード解説(Cophenetic correlation(再現性指標))
🎯 解説: scipy.cluster.hierarchy.cophenet でデンドログラムの「忠実度」を測定。 1 に近いほど元の距離を保つ。
📥 入力例: Z と元の距離行列 D
📤 実行例: coph_corr = 0.78 → 中程度の保存性
💬 読み方: Cophenetic 相関 > 0.8 が良いとされる。 0.5 以下なら別の手法(k-means など)の検討を。
1
2
3
4
5
# 距離例(標準化後)
d(東京, 大阪)    2.4大都市同士で近い
d(東京, 鳥取)    6.8東京の特異性で遠い
d(青森, 秋田)    0.9似た地方圏
d(大阪, 神奈川)  1.7

③ Ward 法でリンケージ計算(結合距離の例)

Ward 法ではクラスタを統合したときの分散増加量が最小のペアから結合します。 47 → 1 まで 46 ステップ。

# ステップ 1:青森・秋田 を統合 → 結合距離 ≈ 0.9
# ステップ 2:山形・福島 を統合 → 結合距離 ≈ 1.1
# ...
# ステップ 30:地方圏が大きな塊に → 結合距離 ≈ 4.5
# ステップ 40:都市圏グループ統合 → 結合距離 ≈ 7.2
# ステップ 45:東京が最後まで独立 → 結合距離 ≈ 11.0
# ステップ 46:東京を残りに統合 → 結合距離 ≈ 15.3

④ デンドログラムを横切るカットの解釈

結合距離 5.5 のあたりで横線を引くと、 およそ 5 クラスタが得られます:

⑤ 共経路相関係数の解釈

# cophenetic correlation(共経路相関)
# 元の距離行列とデンドログラムから読み取る距離(共経路距離)の Pearson 相関
# Ward 法:c ≈ 0.72
# 平均連結法:c ≈ 0.78
# 完全連結法:c ≈ 0.65
# 単連結法:c ≈ 0.55

→ 平均連結法が階層構造を最もよく保存しているが、
  解釈のしやすさは Ward 法に分がある(球状クラスタを作る)

⚠️ デンドログラムの落とし穴 — 実務で必ず引っかかるポイント 6 選

① 標準化を忘れて尺度に支配される

単位の違う変数(万円、 %、 km² など)をそのまま使うと、 値の大きい変数が距離計算を支配し、 デンドログラムは事実上 1 変数だけで決まってしまいます。 例えば家計支出(千円単位、 数百〜数千)と人口密度(人/km²、 数百〜数千)を組み合わせると、 値域がそろっても分散が違えば結果は歪みます。 必ず StandardScaler または robust scaling で前処理してください。

② リンケージ法の選択で結果が劇的に変わる

同じデータでも Ward 法・単連結法・完全連結法・平均連結法で得られるクラスタは全く異なります。 単連結法は「鎖状クラスタ(chaining)」を作りやすく、 全部が 1 つの大クラスタになりがち。 完全連結法は球状を強要する。 Ward 法は分散を最小化するため一般的だが、 解釈は理論的根拠を踏まえて行う必要があります。 複数のリンケージ法を試して結果を比較するのが安全です。

③ クラスタ数の決め方が恣意的になる

デンドログラムをどの高さで切るか(カット位置)は、 多くの場合分析者の主観に委ねられます。 「縦の枝が長い場所で切る」という経験則はありますが、 数値的根拠としてはシルエット係数・ギャップ統計量・エルボー法などを併用するのが望ましい。 さらに、 ドメイン知識との整合性(5 クラスタが解釈しやすい etc.)も合わせて判断します。

④ 大規模データで計算量が爆発する

階層クラスタリングは時間計算量 O(n²log n)〜O(n³)、 空間計算量 O(n²)。 n = 47 都道府県なら問題ありませんが、 n = 10000 以上では現実的に計算不能になります。 大規模データには k-means、 mini-batch k-means、 BIRCH、 HDBSCAN など他の手法を検討するか、 サブサンプリングで階層クラスタリングを近似する必要があります。

⑤ 葉の順序は一意ではない

デンドログラムの葉(個体)の左右の並び順は本質的に任意です。 各内部ノードで左右の子は入れ替え可能なので、 同じ階層構造でも見た目はいくらでも変わります。 「視覚的に隣にあるから類似」と早合点しないでください。 真の距離は結合距離(縦方向の高さ)でしか分かりません。 順序を最適化する手法(optimal leaf ordering、 scipy の `optimal_ordering=True`)もあります。

⑥ 外れ値がチェーン状の歪みを生む

外れ値(東京のような特異点)があると、 単連結法では「東京 → 大阪 → 神奈川 → ...」のような鎖状クラスタが生まれ、 階層構造が歪みます。 Ward 法でも結合距離の最後の数ステップが大きく跳ね上がり、 デンドログラムの上部が伸びすぎて他の構造が見えづらくなります。 外れ値を別途検出・除外、 もしくは対数変換などで前処理することを検討してください。

🐍 Python 実装のバリエーション — scipy / scikit-learn / seaborn

① scipy.cluster.hierarchy による標準実装

▼ コード解説(k-means との比較)
🎯 解説: k-means とデンドログラムから抽出した k クラスタを比較。 結果の安定性を確認。
📥 入力例: k=4 で両手法を実行
📤 実行例: 両手法で主要グループは一致 境界の県のみ差
💬 読み方: 階層クラスタリングと k-means は補完的。 階層は構造を見せ、 k-means は明確な分割をする。
 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
import pandas as pd
import numpy as np
from scipy.cluster.hierarchy import linkage, dendrogram, fcluster
from scipy.spatial.distance import pdist
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')
X = df[['食料費','教育費','交通費','通信費']].dropna()
labels = df.loc[X.index, '都道府県'].values

# 標準化
Xs = StandardScaler().fit_transform(X)

# リンケージ計算(Ward 法)
Z = linkage(Xs, method='ward', metric='euclidean')

# デンドログラム描画
plt.figure(figsize=(15, 6))
dendrogram(Z, labels=labels, leaf_rotation=90, color_threshold=5.5)
plt.axhline(y=5.5, color='red', linestyle='--', label='cut at 5.5')
plt.legend()
plt.tight_layout()
plt.savefig('dendrogram_ward.png', dpi=150)

# 任意の高さで切ってクラスタラベル取得
clusters = fcluster(Z, t=5.5, criterion='distance')
result = pd.DataFrame({'都道府県': labels, 'cluster': clusters})
print(result.groupby('cluster')['都道府県'].apply(list))

② scikit-learn の AgglomerativeClustering

▼ コード解説(Silhouette 係数によるクラスタ数選択)
🎯 解説: sklearn.metrics.silhouette_score で k=2〜10 のシルエット係数を計算。 最大値の k が最適。
📥 入力例: X と clusters
📤 実行例: k=2: 0.45 k=4: 0.52(最大) k=6: 0.38
💬 読み方: シルエット 0.5 以上で「強いクラスタ構造」。 0.25 以下は弱く、 クラスタ数を見直すサイン。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from sklearn.cluster import AgglomerativeClustering
from sklearn.preprocessing import StandardScaler

Xs = StandardScaler().fit_transform(X)

# クラスタ数を指定
model = AgglomerativeClustering(n_clusters=5, linkage='ward')
labels_pred = model.fit_predict(Xs)

result = pd.DataFrame({'都道府県': labels, 'cluster': labels_pred})
print(result.groupby('cluster').size())

③ scikit-learn で距離閾値指定(クラスタ数は自動決定)

▼ コード解説(ヒートマップとの併用)
🎯 解説: seaborn.clustermap で行・列両方をクラスタリングしたヒートマップ。 構造を一望できる。
📥 入力例: X (47, k) の特徴量
📤 実行例: clustermap.png 行: 県の階層、 列: 指標の階層 色: 値の大きさ
💬 読み方: Clustermap は「県と指標の同時クラスタリング」。 探索的データ分析の最強ツールの 1 つ。
1
2
3
4
5
6
7
8
9
from sklearn.cluster import AgglomerativeClustering

model = AgglomerativeClustering(
    n_clusters=None,
    distance_threshold=5.5,
    linkage='ward'
)
labels_pred = model.fit_predict(Xs)
print(f'クラスタ数: {len(set(labels_pred))}')

④ seaborn の clustermap でヒートマップ統合

▼ コード解説(クラスタ別の特徴量プロファイル)
🎯 解説: groupby('cluster').mean() で各クラスタの平均特徴を計算。 「どんな特徴のクラスタか」を解釈。
📥 入力例: clusters と元の特徴量
📤 実行例: Cluster 1: 都市型(高所得・低高齢化) Cluster 2: 中四国型(中所得・高高齢化) Cluster 3: 東北型(低所得・最高齢化) Cluster 4: 観光型(沖縄・北海道)
💬 読み方: クラスタの「人格」を理解するため、 各クラスタで何の指標が高い/低いかを必ず確認。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import seaborn as sns
import pandas as pd
from sklearn.preprocessing import StandardScaler

Xs = pd.DataFrame(
    StandardScaler().fit_transform(X),
    index=labels, columns=X.columns
)

g = sns.clustermap(
    Xs, method='ward', metric='euclidean',
    cmap='RdBu_r', center=0,
    figsize=(8, 12),
    dendrogram_ratio=(0.2, 0.1),
)
g.savefig('clustermap.png', dpi=150)

⑤ 共経路相関係数で妥当性検証

▼ コード解説(クラスタの可視化(PCA + 色分け))
🎯 解説: PCA で 2 次元に圧縮し、 クラスタ ID で色分けプロット。 高次元構造を 2D で確認。
📥 入力例: X を PCA で 2 次元へ 色 = cluster ID
📤 実行例: pca_cluster.png クラスタ間の分離が明確 PC1 で都市性、 PC2 で高齢化
💬 読み方: PCA + クラスタリング色分けは「クラスタが本当に分離しているか」を視覚で確認する標準手法。
1
2
3
4
5
6
7
8
9
from scipy.cluster.hierarchy import linkage, cophenet
from scipy.spatial.distance import pdist

d = pdist(Xs)
for method in ['ward', 'average', 'complete', 'single']:
    Z = linkage(d, method=method)
    c, _ = cophenet(Z, d)
    print(f'{method:9s}: 共経路相関 = {c:.4f}')
# → 値が高いほど階層構造を保存

⑥ シルエット係数でクラスタ数選択

▼ コード解説(リアルタイム追跡(クラスタの安定性))
🎯 解説: Bootstrap でクラスタ割り当ての安定性を検証。 多くのリサンプルで同じクラスタになる県は信頼性高い。
📥 入力例: Bootstrap n=1000
📤 実行例: 都市圏 11 県: 95% で同じクラスタ 境界県(北海道など): 60% 程度
💬 読み方: 境界の県は割り当てが不安定。 そのような県は「両方の特徴を持つ」と解釈し、 単一クラスタに押し込まない。
1
2
3
4
5
6
7
from sklearn.metrics import silhouette_score

for k in range(2, 11):
    model = AgglomerativeClustering(n_clusters=k, linkage='ward')
    labs = model.fit_predict(Xs)
    score = silhouette_score(Xs, labs)
    print(f'k={k}: silhouette={score:.4f}')

⑦ 葉の順序最適化(optimal_ordering)

▼ コード解説(結合距離の解釈)
🎯 解説: Z[:, 2] で結合距離の列を取得。 大きな飛びがある位置がクラスタの自然な切れ目。
📥 入力例: Z の結合距離列
📤 実行例: 距離 4.2 → 5.8 → 6.1 → 12.5 ジャンプ前で切る
💬 読み方: 距離プロットで急上昇する点を見つけるのが「elbow method」。 視覚的に最も自然なクラスタ数を決める。
1
2
3
4
5
from scipy.cluster.hierarchy import linkage, dendrogram

Z = linkage(Xs, method='ward', optimal_ordering=True)
# → 隣接する葉が距離的に近くなるように左右を入れ替え
dendrogram(Z, labels=labels)

🎨 直感で掴む — デンドログラム

デンドログラムは「階層クラスタリングの併合過程」を樹形図で示したもの。 縦軸は併合時の距離で、 切る高さによってクラスタ数が決まる。 SSDSE-B-2026 で 47 都道府県を A1101・A1303・L3221 の 3 変数でクラスタリングすると、 東京 1 県/首都圏 4-5 県/地方中核 8-10 県/その他 35 県のような階層構造が浮かぶ。

💡 学習のコツ:直感で全体像を掴んだら、 次の「📐 定義・数式」で正確な意味を押さえ、 最後に「🧮 実値で計算してみる」で SSDSE-B-2026 の都道府県データを使った計算をなぞるのが効率的です。 比喩は厳密ではないので、 必ず数式と並べて確認してください。

デンドログラム は「可視化」カテゴリの中核概念。 初めて触れる読者は、 まずこの「🎨 直感」セクションだけ通読し、 必要になった時点で「📐 数式」「🐍 Python」「⚠️ 落とし穴」へ戻る読み方が定着しやすいです。

📐 定義・数式 — デンドログラム

直感の次は、 厳密な定義を確認します。 数式は言語の一種で、 一度書き慣れれば「言葉より速く伝えられる」便利な道具。 慣れていない方は、 各記号が何を表すかを下の「🔬 記号読み解き」で 1 つずつ確認してください。

【デンドログラム の中心定義式】
$$ d_{Ward}(C_1, C_2) = \frac{|C_1|\,|C_2|}{|C_1|+|C_2|}\,\|\bar{x}_{C_1} - \bar{x}_{C_2}\|^2 $$
この式が「デンドログラム」の骨格。 派生形・拡張形はここから生まれる。
📌 読み方のコツ:数式を見たら「左辺は何を定義しているか」「右辺の各項は何の合計・積・比か」を声に出して読み下してみる。 これだけで理解が大きく進みます。

🔬 記号読み解き — 数式を「言葉」に翻訳

上の数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。

左辺(結果側)
デンドログラム で定義したい量。 解釈の対象。 単位・スケールを必ず確認する。
右辺(構成要素)
観測できる入力変数(SSDSE-B-2026 でいえば A1101・L3221 など)と推定対象パラメータ(β, σ 等)の組合せ。
添字 i, j, t
i=サンプル(県)、 j=変数、 t=時点。 SSDSE-B-2026 は i ∈ {1..47} 県、 t ∈ {2008..2023}。
和記号 Σ
「足し合わせ」を表す。 添字 i が 1 から n まで動く範囲を明示するのが習慣。
期待値 E[·]、 分散 Var[·]
「ランダム変数の平均」と「ばらつき」。 SSDSE-B-2026 のような集計値でも、 標本誤差・年次変動の文脈で使える。
📚 補足:同じ記号でも分野・教科書によって意味が違うことがあります(例: $\hat{y}$ は予測値だが、 統計の文脈では推定量を意味することも)。 不明確なときは、 必ずその文書の記号定義表を確認しましょう。

🧮 実値で計算してみる — SSDSE-B-2026

数式だけでは「実感」が湧きにくいので、 実データ data/raw/SSDSE-B-2026.csv(47 都道府県 × 16 年)で 1 度手計算してみると理解が定着します。

Ward 法で SSDSE-B-2026 (2023) の標準化済み A1101・A1303・L3221 をクラスタリングすると、 高さ 6.0 付近で 2 クラスタ(東京 vs 残り 46)、 高さ 3.5 で 4 クラスタ(東京/神奈川・大阪・愛知/首都圏/その他)に分かれる。 デンドログラムは併合距離が急増する箇所で切るのが定石。

都道府県A1101 総人口A1303 65 歳以上L3221 消費支出
東京都14,086,0003,205,000341,320
神奈川県9,229,0002,390,000306,565
大阪府8,763,0002,424,000271,246
愛知県7,477,0001,923,000300,221
埼玉県7,331,0002,012,000344,092
千葉県6,257,0001,756,000306,943

上記は SSDSE-B-2026 (2023) からの抜粋。 手計算で確認した値が、 後述の Python 実装で得る値と一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。

🐍 Python 実装 — デンドログラム

公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで デンドログラム を動作させます。 まずはこのまま実行してみてください。

# デンドログラム を SSDSE-B-2026 で実行する最小コード
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]  # 2023 年のみ抽出
print(df.shape)  # (47, 112)
print(df[['Prefecture','A1101','A1303','L3221']].head())

from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
X = StandardScaler().fit_transform(df[['A1101','A1303','L3221']])
Z = linkage(X, method='ward')
fig, ax = plt.subplots(figsize=(14,5))
dendrogram(Z, labels=df['Prefecture'].values, leaf_rotation=90, color_threshold=4.0, ax=ax)
ax.set_title('SSDSE-B-2026: 47 都道府県 Ward 法')
plt.tight_layout(); plt.savefig('dendrogram_demo.png', dpi=100)

上のコードで動かない場合は、 ①必要なパッケージがインストール済みか(pip install pandas scikit-learn scipy statsmodels matplotlib)、 ②データファイルが data/raw/SSDSE-B-2026.csv に存在するか、 ③encoding='cp932' になっているかを確認してください。

⚠️ よくある落とし穴 — デンドログラム

デンドログラム を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。

❌ リンク法で形が大きく変わる
Ward・Complete・Single・Average で同じデータでも全く違う樹形になる。 目的に応じて選ぶ。
❌ 標準化を忘れる
A1101(百万単位)と B4101(10℃台)を混ぜると、 人口だけで距離が決まる。 必ず StandardScaler。
❌ 切る高さの根拠が曖昧
「なんとなく 5 クラスタ」では再現性がない。 Cophenetic 相関や Gap 統計量で正当化する。
🛡 防御策まとめ:「適用条件を確認する」「結果と前提をセットで記述する」「不確実性を必ず併記する」の 3 点を習慣化すれば、 上記の罠の大半は回避できます。