クラスタリングは、ラベル(正解)が与えられていないデータから「自然なグループ」を発見する教師なし学習の手法です。顧客セグメンテーション、異常検知、画像分類の前処理など、幅広いビジネス・研究分野で活用されています。この記事では、最も代表的な K-means と、密度ベースの HDBSCAN の2手法を中心に、クラスタリング分析の実践方法を解説します。
クラスタリングとは — 教師なし学習の基本
クラスタリングは、類似したデータポイントを同じグループ(クラスター)に、異なるデータポイントを別のグループに分ける手法です。教師あり学習(分類や回帰)とは異なり、正解ラベルを必要としません。データの「構造」をデータ自身から発見するため、事前にグループの数や特性を知らなくても分析を始められます。
EDA におけるクラスタリングの主な目的は、(1) データに自然なグループ構造があるかどうかを探索する、(2) グループごとの特性(プロファイル)を把握する、(3) 各グループのサンプル数や分布を確認する、の3点です。クラスタリングの結果は、ターゲット変数との関連を調べることで、予測モデルの精度向上にも繋がります。
K-means アルゴリズムの仕組み
K-means は最も広く使われているクラスタリングアルゴリズムです。事前にクラスター数 K を指定し、以下の手順を収束するまで繰り返します。(1) K 個の初期中心点(セントロイド)をランダムに配置する、(2) 各データポイントを最も近いセントロイドのクラスターに割り当てる、(3) 各クラスターのセントロイドをクラスター内の平均点に更新する。このプロセスにより、クラスター内の分散を最小化する割り当てが見つかります。
K-means は計算が高速でスケーラビリティが高いのが利点ですが、(1) クラスター数 K を事前に指定する必要がある、(2) 球状のクラスターを仮定する(非球状のクラスターには対応できない)、(3) 外れ値に敏感、という制約があります。
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# サンプルデータの作成(3つのクラスター)
X, y_true = make_blobs(n_samples=500, centers=3, cluster_std=1.0, random_state=42)
# 標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-means の実行
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)
# 結果の可視化
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 真のラベル
axes[0].scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_true, cmap="tab10", s=20, alpha=0.7)
axes[0].set_title("真のクラスター")
# K-means の結果
axes[1].scatter(X_scaled[:, 0], X_scaled[:, 1], c=labels, cmap="tab10", s=20, alpha=0.7)
centers = kmeans.cluster_centers_
axes[1].scatter(centers[:, 0], centers[:, 1], c="red", marker="X", s=200, edgecolors="black")
axes[1].set_title("K-means の結果(K=3)")
plt.tight_layout()
plt.show()エルボー法 — 最適なクラスター数を見つける
K-means の最大の課題は「K をいくつにすべきか」です。エルボー法(Elbow Method)は、K を 1 から順に増やしながら、各 K でのクラスター内距離の合計(イナーシャ、Inertia)をプロットする手法です。K を増やすとイナーシャは必ず減少しますが、適切な K を超えると減少の勢いが鈍化します。この「折れ曲がり点(エルボー)」が最適な K の候補です。
ただし、エルボー法は必ずしも明確な折れ曲がりを示すとは限りません。特に、クラスターのサイズや密度が不均一な場合は、エルボーが不明瞭になることがあります。そのため、シルエット分析と併用するのがベストプラクティスです。
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
# エルボー法とシルエットスコアの同時評価
K_range = range(2, 11)
inertias = []
silhouette_scores = []
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)
inertias.append(kmeans.inertia_)
silhouette_scores.append(silhouette_score(X_scaled, labels))
# プロット
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# エルボー法
ax1.plot(K_range, inertias, "bo-")
ax1.set_xlabel("クラスター数 K")
ax1.set_ylabel("イナーシャ(クラスター内距離の合計)")
ax1.set_title("エルボー法")
# シルエットスコア
ax2.plot(K_range, silhouette_scores, "ro-")
ax2.set_xlabel("クラスター数 K")
ax2.set_ylabel("シルエットスコア")
ax2.set_title("シルエット分析")
plt.tight_layout()
plt.show()
best_k = K_range[np.argmax(silhouette_scores)]
print(f"最適な K(シルエットスコア最大): {best_k}")シルエット分析 — クラスターの品質を評価する
シルエットスコアは、各データポイントが「自分のクラスターにどれだけ適切に割り当てられているか」を -1 から +1 の範囲で評価する指標です。+1 に近いほどそのポイントは自分のクラスターにしっかり属しており、0 に近いとクラスター境界上にあり、-1 に近いと間違ったクラスターに割り当てられている可能性があります。
全データポイントのシルエットスコアの平均値が高い K が最適なクラスター数です。さらに、シルエットプロット(各ポイントのスコアをクラスターごとに横棒グラフで表示)を描くと、クラスターごとの品質のばらつきも確認できます。「あるクラスターだけスコアが低い」場合は、そのクラスターの分割を再検討する手がかりになります。
- 1
シルエットスコアの計算方法
各点について、(1) 同じクラスター内の他の点との平均距離 a、(2) 最も近い別クラスターとの平均距離 b を計算し、(b - a) / max(a, b) がシルエットスコアです。
- 2
全体の平均スコアで K を比較
K を変えながら平均シルエットスコアを計算し、最大値を取る K が最適候補です。スコアが 0.5 以上なら良好なクラスタリング、0.7 以上なら非常に良好と判断できます。
- 3
シルエットプロットで詳細を確認
各クラスター内のポイントのシルエットスコアを可視化し、クラスターごとの品質差やバランスを評価します。スコアが負のポイントが多いクラスターは問題です。
エルボー法とシルエット分析の結果が一致しない場合は、シルエットスコアを優先しつつ、ドメイン知識も加味して K を決定しましょう。ビジネス上「3つの顧客セグメント」が自然であれば K=3 を試す、というアプローチも有効です。
HDBSCAN — 密度ベースのクラスタリング
HDBSCAN(Hierarchical Density-Based Spatial Clustering of Applications with Noise)は、データの「密度」に基づいてクラスターを検出する手法です。K-means と異なり、(1) クラスター数を事前に指定する必要がない、(2) 任意の形状のクラスターを検出できる、(3) 外れ値(ノイズ)を自動的にラベル -1 として検出する、という3つの大きな利点があります。
HDBSCAN は DBSCAN の拡張版で、異なる密度のクラスターも検出できます。アルゴリズムは、(1) 各点の近傍密度を推定、(2) 密度に基づく距離でMinimum Spanning Tree を構築、(3) 階層的にクラスターを形成、(4) 安定性に基づいてクラスターを抽出、という手順で動作します。
import numpy as np
import hdbscan
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_blobs
import matplotlib.pyplot as plt
# 月形データ(非球状クラスター)+ ノイズ
X_moons, _ = make_moons(n_samples=400, noise=0.08, random_state=42)
noise = np.random.uniform(-1.5, 2.5, (50, 2)) # ノイズ点
X = np.vstack([X_moons, noise])
# HDBSCAN の実行
clusterer = hdbscan.HDBSCAN(min_cluster_size=15, min_samples=5)
labels = clusterer.fit_predict(X)
# 結果の可視化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# K-means(比較用)
from sklearn.cluster import KMeans
km_labels = KMeans(n_clusters=2, random_state=42).fit_predict(X)
ax1.scatter(X[:, 0], X[:, 1], c=km_labels, cmap="tab10", s=20, alpha=0.7)
ax1.set_title("K-means(K=2)")
# HDBSCAN
colors = labels.copy().astype(float)
colors[labels == -1] = np.nan # ノイズは灰色
ax2.scatter(X[:, 0], X[:, 1], c=colors, cmap="tab10", s=20, alpha=0.7)
noise_mask = labels == -1
ax2.scatter(X[noise_mask, 0], X[noise_mask, 1], c="gray", s=10, alpha=0.3, label="ノイズ")
ax2.set_title(f"HDBSCAN({len(set(labels) - {-1})} クラスター + ノイズ {noise_mask.sum()} 点)")
ax2.legend()
plt.tight_layout()
plt.show()
print(f"検出されたクラスター数: {len(set(labels) - {-1})}")
print(f"ノイズとして検出された点: {(labels == -1).sum()}")K-means と HDBSCAN の使い分け
K-means と HDBSCAN は相補的な手法であり、データの性質に応じて使い分けます。K-means は球状で均一なサイズのクラスターが期待される場合や、クラスター数がドメイン知識から推定できる場合に適しています。HDBSCAN は、クラスターの形状が不明、密度が不均一、外れ値が多い場合に適しています。
- 1
K-means を選ぶ場面
クラスター数が既知、球状クラスターが期待される、大規模データ(数十万件以上)で計算速度が重要な場合。顧客をN個のセグメントに分けるなど、ビジネス要件でKが決まる場合にも適しています。
- 2
HDBSCAN を選ぶ場面
クラスター数が不明、クラスターの形状が不規則、外れ値やノイズが多い場合。探索的な分析で「データにどんなグループがあるか分からない」段階では HDBSCAN が有力です。
- 3
両方使う場面(推奨)
EDA では両方を実行して結果を比較するのがベストプラクティスです。Qast ではK-means(エルボー法で最適K自動決定)と HDBSCAN の両方が自動実行されます。
クラスタープロファイル — 各グループの特性を理解する
クラスタリングで最も重要なのは、「各クラスターがどんな特性を持つか」を理解するクラスタープロファイリングです。各クラスターの特徴量の平均値・中央値・分布を比較し、「クラスター1は高年齢・高収入のグループ」「クラスター2は若年・デジタル利用率が高いグループ」といったビジネス上の解釈を与えます。
プロファイリングでは、全体平均との差分に注目します。クラスターの平均が全体平均と大きく異なる特徴量が、そのクラスターを特徴づける変数です。Qast では各クラスターの特性プロファイルが自動生成され、全体平均との差分をバーチャートで可視化します。
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# サンプル顧客データ
np.random.seed(42)
n = 500
df = pd.DataFrame({
"年齢": np.concatenate([
np.random.normal(25, 5, 200),
np.random.normal(45, 8, 200),
np.random.normal(60, 6, 100),
]),
"年間購入額": np.concatenate([
np.random.normal(30000, 10000, 200),
np.random.normal(80000, 20000, 200),
np.random.normal(50000, 15000, 100),
]),
"Web訪問回数": np.concatenate([
np.random.normal(50, 15, 200),
np.random.normal(20, 8, 200),
np.random.normal(10, 5, 100),
]),
})
# クラスタリング
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
df["クラスター"] = kmeans.fit_predict(X_scaled)
# クラスタープロファイル
profile = df.groupby("クラスター").agg(["mean", "median", "count"])
print("クラスタープロファイル:")
print(profile.round(1))
# 全体平均との差分
overall_mean = df.drop(columns="クラスター").mean()
for cluster_id in sorted(df["クラスター"].unique()):
cluster_mean = df[df["クラスター"] == cluster_id].drop(columns="クラスター").mean()
diff = cluster_mean - overall_mean
print(f"\nクラスター {cluster_id}(全体平均との差分):")
for col in diff.index:
print(f" {col}: {diff[col]:+.1f}")クラスターの評価指標
クラスタリング結果の品質を評価するための指標は、外部評価指標(正解ラベルがある場合)と内部評価指標(正解ラベルがない場合)に分けられます。EDA では正解ラベルが通常ないため、内部評価指標が主に使われます。
- 1
シルエットスコア(内部)
クラスター内の凝集度とクラスター間の分離度のバランスを -1〜+1 で評価します。値が高いほどクラスターの品質が良好です。
- 2
Calinski-Harabasz Index(内部)
クラスター間分散とクラスター内分散の比率です。値が大きいほどクラスターがよく分離されていることを示します。
- 3
Davies-Bouldin Index(内部)
各クラスターと最も類似したクラスターとの比率の平均です。値が小さいほどクラスタリングの品質が高いことを示します。
- 4
Adjusted Rand Index(外部)
正解ラベルがある場合に使用。クラスタリング結果と正解ラベルの一致度を -1〜+1 で評価します。1 が完全一致です。
クラスタリングの「正解」は存在しない場合がほとんどです。評価指標はあくまで参考であり、最終的にはドメインの専門家がクラスタープロファイルを見て「ビジネス上意味のあるグループ分けか」を判断することが重要です。
ビジネスにおけるクラスタリングの活用例
クラスタリングは多様なビジネスシーンで活用されています。最も一般的なのは顧客セグメンテーションで、購買行動や属性に基づいて顧客をグループ分けし、各セグメントに最適なマーケティング施策を実施します。他にも、異常検知(正常パターンのクラスターから外れるデータを異常として検出)、推薦システム(類似ユーザーグループを利用した協調フィルタリング)などで活用されています。
Qast でのクラスタリングは EDA の一部として実行されるため、クラスタリング結果を直接モデル学習に活用できます。たとえば、クラスターラベルを新しい特徴量として追加し、モデルの精度を向上させることが可能です。また、クラスターごとにモデルを分けて学習する「セグメント別モデリング」のアプローチも検討できます。
Qast のクラスタリングダッシュボード
Qast の EDA では、K-means(エルボー法とシルエット分析で最適 K を自動決定)と HDBSCAN の両方が自動実行されます。結果はインタラクティブなダッシュボードで表示され、2D散布図(PCA/t-SNE で射影)上にクラスターが色分けされます。各クラスターをクリックすると、クラスタープロファイル(各特徴量の平均・分布)が詳細パネルに表示されます。
エルボー法のプロットとシルエットプロットも自動生成されるため、最適 K の根拠を視覚的に確認できます。HDBSCAN の結果ではノイズポイント(ラベル -1)が灰色で表示され、外れ値の分布も一目で把握できます。プログラミング不要で高度なクラスタリング分析を実施し、ビジネスインサイトに繋げられるのが Qast の強みです。
まとめ — クラスタリング分析の実践フロー
クラスタリング分析は、(1) データの前処理(標準化・欠損値処理)、(2) K-means と HDBSCAN の両方を実行、(3) エルボー法・シルエット分析で最適 K を決定、(4) クラスタープロファイルでビジネス解釈を付与、(5) 評価指標でクラスタリング品質を確認、という流れで進めます。Qast はこのプロセスを完全に自動化し、直感的なダッシュボードで結果を提供します。
クラスタリング分析の前に、多変量分析(PCA/t-SNE)でデータの全体構造を把握しておくと、クラスタリング結果の解釈がスムーズです。「PCA の散布図で2つのグループが見えていた → K-means で K=2 がシルエット最高だった → 各グループの特性をプロファイリングした」というストーリーが理想的な分析フローです。

