HDBSCAN(Hierarchical Density-Based Spatial Clustering of Applications with Noise)
一言でいうと:「クラスター数を指定しなくていい、密度ベースの賢いクラスタリング手法。ノイズ(どこにも属さない点)も自動的に検出してくれる」
k-meansとの違い
クラスタリングといえばk-meansが有名ですが、テキスト分析では相性が悪いケースがあります。
| 比較項目 | k-means | HDBSCAN |
|---|---|---|
| クラスター数の指定 | 必要(k=?を事前に決める) | 不要(自動で決まる) |
| クラスターの形状 | 球形のみ想定 | 任意の形状に対応 |
| ノイズの扱い | 全データをどこかに強制割当 | ノイズとして検出できる |
| 外れ値への耐性 | 弱い(外れ値がセントロイドを歪める) | 強い |
| 密度の違いへの対応 | 苦手 | 得意(密度が違うクラスターも分離) |
k-meansの限界
k-means の問題:「k=5 って決めたけど、本当に5クラスターあるの?」
k=3 と決めたとき 実際のデータ分布
○ ○ ○ ●●● ●●● ●●●●●
↑ ↑ ↑ (自然に3つの塊がある)
セントロイドを
無理やり3つ配置
→ 形のいびつなクラスターが生まれる
商品レビューの話題(トピック)は「何種類あるか」が事前にわかりません。HDBSCANはそれを自動で見つけてくれます。
密度の直感的な説明
「色が濃い部分」がクラスターの核心
HDBSCANの「密度」を一番わかりやすく理解する方法は、散布図の色の濃さで考えることです。
散布図のイメージ:
・ ・ ← スカスカ(密度が低い)=ノイズ候補
●●●●
●●●●●●● ← 色が濃い(密度が高い)=クラスターの核心
●●●●
・ ← 一匹狼(どこにも属さない)=ノイズ
●●●
●●●●●● ← 別の塊=別のクラスター
●●●
「点が密集している=色が濃い部分」がクラスターの中心になり、その周辺に薄くつながっている点がクラスターのメンバーになる、という直感は正しいです。
HDBSCANは内部的に「ある点の周囲にどれだけ点があるか」を密度として計算しています。密度が高い領域同士がつながっている塊を1つのクラスターと認識します。
ノイズの概念——一匹狼的なレビュー
「ノイズって何?」という疑問
最初にHDBSCANを使ったとき、ラベルに -1 が現れるのを見て戸惑うかもしれません。
labels = hdbscan.HDBSCAN().fit_predict(embeddings)
# array([0, 1, 0, -1, 2, -1, 1, ...])
# ^^ ^^
# ノイズ!?
-1 はエラーではありません。これが「ノイズ」です。
ノイズ=どのクラスターにも属さないレビュー
商品レビューのデータセットで考えてみましょう。
クラスター0:「配送が遅い」系のレビュー → 100件
クラスター1:「品質が良い」系のレビュー → 80件
クラスター2:「価格が高い」系のレビュー → 60件
ノイズ(-1):
- 「配送への不満と品質の称賛を混ぜたようなレビュー」1件
- 「文脈が特殊すぎて他と似ていないレビュー」3件
- 「誤ってデータセットに入った無関係な投稿」2件
これらは「どのクラスターにも半端にしか似ていない、一匹狼的なレビュー」です。
k-meansなら 強制的にどこかのクラスターに割り当ててしまいますが、HDBSCANは正直に「これはノイズ」と言ってくれます。分析の精度を守るために、あえて「わからない」と言える設計になっています。
ノイズ率の目安
ノイズ率 = ノイズ件数 / 全件数
~10% : 許容範囲(クラスターがうまく分離できている)
10〜30% : 要検討(min_cluster_size を下げると取り込める可能性あり)
30%〜 : パラメータ調整が必要(クラスターが細かすぎる)
パラメータの説明
min_cluster_size——クラスターと認めるための最小サイズ
hdbscan.HDBSCAN(min_cluster_size=100)
HDBSCANで最も重要なパラメータです。
- **「最低でもこの件数がいないとクラスターとは呼ばない」**という閾値
- 小さいほどクラスター数が増え、細かい分割になる
- 大きいほどクラスター数が減り、大きな塊だけが残る
min_cluster_size=50 → クラスター数:多い ノイズ:少ない
min_cluster_size=500 → クラスター数:少ない ノイズ:多い(小さな塊がノイズ扱い)
クラスター数を「指定」していないのに結果が変わる理由はここにあります。「最小サイズの閾値」を変えると、どの密度の塊をクラスターと認めるかが変わるからです。
min_samples——ノイズ判定の厳しさ
hdbscan.HDBSCAN(min_samples=5) # デフォルト:min_cluster_sizeと同値
- ある点が「コア点(クラスターの核心)」と認められるために、周囲に必要な点の数
- 大きくするほど厳しくなり、ノイズが増える
- 小さくするほど寛容になり、ノイズが減る
- 通常は
min_cluster_sizeと同じかやや小さい値にする
cluster_selection_method——クラスター境界の決め方
hdbscan.HDBSCAN(cluster_selection_method='eom') # デフォルト
hdbscan.HDBSCAN(cluster_selection_method='leaf')
| 値 | 特徴 |
|---|---|
'eom'(Excess of Mass) |
階層的なクラスター木の「安定した部分」を選ぶ。大小様々なクラスターを自然に検出 |
'leaf' |
木の末端(葉)を使う。クラスターが細かく・均一なサイズになりやすい |
テキストクラスタリングでは 'eom'(デフォルト) が多くの場合うまく機能します。
今回のパラメータ調整の試行錯誤
min_cluster_size を段階的に変えて、クラスタリング結果がどう変わるかを確認しました。
min_cluster_size |
クラスター数 | ノイズ件数 | ノイズ率 | 所感 |
|---|---|---|---|---|
| 50 | 42 | 312 | 8.4% | 細かすぎて解釈が大変。類似クラスターが乱立 |
| 150 | 18 | 489 | 13.2% | まだ多い。細かい話題まで拾いすぎ |
| 300 | 9 | 671 | 18.1% | バランスが取れてきた。主要な話題が見えてくる |
| 500 | 5 | 1,024 | 27.6% | 大きすぎる塊に。ノイズが多く情報損失が気になる |
→ min_cluster_size=300 を採用
調整の基準にしたのは以下の3点:
- 各クラスターに「意味のある共通テーマ」が読み取れるか
- ノイズ率が20%以下に収まっているか
- クラスター数が人間がレビューできる範囲(5〜15個)か
今回の使い方——商品レビュークラスタリングパイプラインでの役割
パイプライン内での位置づけ
高次元埋め込み(1536次元)
↓ UMAP(15次元に削減)
低次元ベクトル(15次元)
↓ HDBSCAN ← ここ
クラスターラベル(0, 1, 2, ..., -1)
↓ UMAP(2次元に削減・可視化)
散布図 + クラスター色分け
HDBSCANが担う役割
主なタスク:レビュー話題の自動グルーピング
import hdbscan
clusterer = hdbscan.HDBSCAN(
min_cluster_size=300,
min_samples=30,
cluster_selection_method='eom',
metric='euclidean' # UMAP削減後なのでユークリッドでOK
)
labels = clusterer.fit_predict(umap_embeddings)
注意:UMAPで次元削減した後のベクトルに対してHDBSCANを適用しています。UMAPの出力はユークリッド距離が有効になっているため、
metric='euclidean'を使います(生の埋め込みに直接かける場合はmetric='cosine'を検討)。
結果の解釈
import numpy as np
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = np.sum(labels == -1)
noise_rate = n_noise / len(labels)
print(f"クラスター数: {n_clusters}")
print(f"ノイズ件数: {n_noise} ({noise_rate:.1%})")
# 各クラスターのサイズ確認
for i in range(n_clusters):
size = np.sum(labels == i)
print(f"クラスター{i}: {size}件")
ノイズを活用する
ノイズと判定された投稿も捨てずに分析します:
- 希少なレビュー話題の候補:まだ表面化していない新しい不満や要望かもしれない
- 多言語・多文化のレビュー:日本語と英語が混在するなど、クラスターに馴染みにくいレビュー
- 誤分類の検出:関係ないデータが混入していたことを示すシグナル
まとめ
| 項目 | ポイント |
|---|---|
| 何をするか | 密度ベースの自動クラスタリング |
| k-meansとの違い | クラスター数不要・任意形状・ノイズ検出 |
| 密度の直感 | 散布図で「色が濃い部分」=クラスターの核心、その通り |
| ノイズ(-1)の意味 | どのクラスターにも馴染まない一匹狼的なレビュー。捨てずに活用 |
| 最重要パラメータ |
min_cluster_size(これを変えるとクラスター数が変わる) |
| 今回の採用値 |
min_cluster_size=300(50→150→300→500 で試した結果) |
参考
- HDBSCAN公式ドキュメント
- Campello et al. (2013). Density-Based Clustering Based on Hierarchical Density Estimates
- [[UMAP]] — 次元削減(HDBSCANの前処理として使用)
- [[review-clustering]] — 本プロジェクトでの実装
tags: #ML #クラスタリング #HDBSCAN #密度ベース #NLP #レビュー分析