📋 このステップで学ぶこと
- 教師なし学習とクラスタリングの概念
- K-means法の仕組みと実装
- エルボー法とシルエット分析
- 階層的クラスタリング
- DBSCAN(密度ベースクラスタリング)
- クラスタリング手法の使い分け
演習問題: 8問
🎯 1. 教師なし学習とクラスタリング
📊 教師あり学習 vs 教師なし学習
教師あり学習:正解ラベル(y)がある → 予測モデルを作る
教師なし学習:正解ラベルがない → データの構造やパターンを発見する
【教師なし学習の主なタスク】
1. クラスタリング → データを似たもの同士でグループ分け
2. 次元削減 → 高次元データを低次元に圧縮(PCA、t-SNE)
3. 異常検知 → 通常とは異なるデータを検出
🎯 クラスタリングの目的
「似たもの同士を同じグループに、異なるものを別のグループに」
・クラスタ内の類似度:高い(まとまりがある)
・クラスタ間の類似度:低い(はっきり分かれている)
📊 2. K-means法
🔄 K-meansのアルゴリズム
1. 初期化:K個のクラスタ中心(セントロイド)をランダムに配置
2. 割り当て:各データ点を最も近いセントロイドに割り当て
3. 更新:各クラスタの重心を新しいセントロイドとする
4. 繰り返し:2-3を収束するまで繰り返す
# K-meansの基本実装
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# サンプルデータの生成(3つのクラスタ)
X, y_true = make_blobs(n_samples=300, centers=3, cluster_std=0.60, random_state=42)
# K-meansでクラスタリング
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
y_kmeans = kmeans.fit_predict(X)
# 結果の確認
print(“クラスタ中心:”)
print(kmeans.cluster_centers_)
print(f”\nイナーシャ(SSE): {kmeans.inertia_:.2f}”)
print(f”各クラスタのサンプル数: {np.bincount(y_kmeans)}”)
クラスタ中心:
[[-1.66 4.31]
[ 1.98 0.87]
[-1.39 2.56]]
イナーシャ(SSE): 158.73
各クラスタのサンプル数: [100 100 100]
⚠️ K-meansの注意点
- Kの数を事前に決める必要がある(エルボー法で決定)
- 球状のクラスタを仮定(複雑な形状には不向き)
- 初期値に依存(n_init で複数回実行)
- 外れ値に敏感(事前に外れ値を除去)
📈 3. 最適なクラスタ数の決定
エルボー法(Elbow Method)
📊 エルボー法の考え方
クラスタ数(K)を増やすと、イナーシャは減少。しかし、ある点を超えると減少が緩やかになります。この「肘」のような折れ曲がりの点が最適なK。
# エルボー法の実装
inertias = []
K_range = range(1, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(X)
inertias.append(kmeans.inertia_)
# プロット
plt.figure(figsize=(8, 5))
plt.plot(K_range, inertias, ‘bo-‘, linewidth=2, markersize=8)
plt.xlabel(‘クラスタ数 (K)’)
plt.ylabel(‘イナーシャ(SSE)’)
plt.title(‘エルボー法によるクラスタ数の決定’)
plt.xticks(K_range)
plt.grid(True, alpha=0.3)
plt.show()
シルエット分析
# シルエット分析
from sklearn.metrics import silhouette_score
silhouette_scores = []
for k in range(2, 11):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = silhouette_score(X, labels)
silhouette_scores.append(score)
print(f”K={k}: シルエットスコア={score:.4f}”)
best_k = range(2, 11)[np.argmax(silhouette_scores)]
print(f”\n最適なクラスタ数: K={best_k}”)
K=2: シルエットスコア=0.5817
K=3: シルエットスコア=0.6526 ← 最高スコア
K=4: シルエットスコア=0.5135
…
最適なクラスタ数: K=3
✅ シルエットスコアの解釈
シルエットスコア:-1〜1
・+1に近い:良くクラスタリングされている
・0付近:クラスタの境界にいる
・-1に近い:間違ったクラスタに割り当てられている
🌲 4. 階層的クラスタリング
📊 凝集型階層的クラスタリング
1. 開始:各データ点を1つのクラスタとする
2. 結合:最も近い2つのクラスタを結合
3. 繰り返し:すべてが1つのクラスタになるまで続ける
4. カット:デンドログラムを任意の高さで切ってクラスタ数を決定
# 階層的クラスタリングの実装
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.cluster import AgglomerativeClustering
# リンケージ行列の計算(Ward法)
Z = linkage(X, method=’ward’)
# デンドログラムの描画
plt.figure(figsize=(12, 5))
dendrogram(Z, truncate_mode=’lastp’, p=30)
plt.title(‘階層的クラスタリング(デンドログラム)’)
plt.xlabel(‘サンプル’)
plt.ylabel(‘距離’)
plt.axhline(y=20, color=’r’, linestyle=’–‘, label=’カットライン’)
plt.legend()
plt.show()
# sklearn の AgglomerativeClustering
agg = AgglomerativeClustering(n_clusters=3, linkage=’ward’)
y_agg = agg.fit_predict(X)
print(f”各クラスタのサンプル数: {np.bincount(y_agg)}”)
| リンケージ |
距離の定義 |
特徴 |
| Ward法 |
結合時の分散増加を最小化 |
球状のクラスタ向き、最も一般的 |
| 完全連結法 |
クラスタ間の最大距離 |
コンパクトなクラスタを作る |
| 平均連結法 |
クラスタ間の平均距離 |
バランスの良い結果 |
🔍 5. DBSCAN(密度ベースクラスタリング)
📊 DBSCAN
密度が高い領域をクラスタとし、低密度領域はノイズとして扱う手法。
主要パラメータ:
・eps:近傍の半径
・min_samples:コアポイントになるために必要な最小サンプル数
# DBSCANの実装(月形データ)
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons
# 月形データの生成
X_moons, y_moons = make_moons(n_samples=300, noise=0.05, random_state=42)
# DBSCAN
dbscan = DBSCAN(eps=0.2, min_samples=5)
y_dbscan = dbscan.fit_predict(X_moons)
# 結果の確認
n_clusters = len(set(y_dbscan)) – (1 if -1 in y_dbscan else 0)
n_noise = list(y_dbscan).count(-1)
print(f”クラスタ数: {n_clusters}”)
print(f”ノイズ点数: {n_noise}”)
クラスタ数: 2
ノイズ点数: 0
✅ DBSCANの利点
- クラスタ数を事前に指定する必要がない
- 任意の形状のクラスタを検出できる
- 外れ値をノイズとして検出できる
⚠️ DBSCANの注意点
- epsとmin_samplesの調整が難しい
- 密度が異なるクラスタには対応しにくい
⚖️ 6. クラスタリング手法の比較
| 手法 |
長所 |
短所 |
適した場面 |
| K-means |
高速、大規模データOK |
Kを事前指定、球状のみ |
球状クラスタ、大規模データ |
| 階層的 |
Kを後から決定可、デンドログラム |
計算量が多い |
中小規模データ、階層構造の分析 |
| DBSCAN |
任意の形状、外れ値検出 |
パラメータ調整難 |
非球状クラスタ、外れ値がある場合 |
💡 手法選択のガイドライン
1. まずK-meansを試す(高速で理解しやすい)
2. 球状でない場合 → DBSCAN
3. 階層構造を見たい場合 → 階層的クラスタリング
4. 外れ値が多い場合 → DBSCAN
📝 練習問題
問題1
やさしい
教師なし学習の特徴
教師なし学習の説明として正しいものを選んでください。
- A. 正解ラベルを使って予測モデルを作る
- B. 正解ラベルなしでデータの構造やパターンを発見する
- C. 報酬を最大化するように学習する
- D. 時系列データを予測する
正解:B
教師なし学習は、正解ラベルがない状態でデータの構造やパターンを発見する手法です。
問題2
やさしい
K-meansの手順
K-meansアルゴリズムの手順として正しい順序を選んでください。
- A. 割り当て → 初期化 → 更新 → 繰り返し
- B. 初期化 → 割り当て → 更新 → 繰り返し
- C. 更新 → 初期化 → 割り当て → 繰り返し
正解:B
1.初期化 → 2.割り当て → 3.更新 → 4.収束まで繰り返し
問題3
ふつう
エルボー法
エルボー法でクラスタ数を決定する際、何を見て判断しますか?
- A. イナーシャが最大になるK
- B. イナーシャの減少が緩やかになる点(エルボー)
- C. シルエットスコアが最大になるK
正解:B
「肘」のような折れ曲がりの点が最適なKです。
問題4
ふつう
シルエットスコア
シルエットスコアが0.8の場合、どのように解釈できますか?
- A. クラスタリングの品質が悪い
- B. クラスタリングの品質が良い
- C. データ点がクラスタの境界にいる
正解:B
シルエットスコアは-1〜1の範囲で、+1に近いほど良くクラスタリングされています。
問題5
ふつう
DBSCANの特徴
DBSCANの説明として正しいものを選んでください。
- A. クラスタ数を事前に指定する必要がある
- B. 球状のクラスタのみに対応する
- C. 外れ値をノイズとして検出できる
正解:C
DBSCANは外れ値をノイズ(ラベル=-1)として検出できます。クラスタ数の事前指定不要、任意の形状に対応可能です。
問題6
むずかしい
手法の選択
月形やドーナツ型のような非球状のクラスタがあり、外れ値も含まれるデータに最も適した手法は?
- A. K-means
- B. 階層的クラスタリング(Ward法)
- C. DBSCAN
正解:C(DBSCAN)
任意の形状のクラスタを検出でき、外れ値をノイズとして検出できるため。
問題7
むずかしい
K-meansの実装
Irisデータセットでエルボー法とシルエット分析を行い、最適なクラスタ数を決定してください。
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
iris = load_iris()
X = iris.data
for k in range(2, 6):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = silhouette_score(X, labels)
print(f”K={k}: inertia={kmeans.inertia_:.1f}, silhouette={score:.4f}”)
# 結果: K=3 が最適
問題8
むずかしい
DBSCANのパラメータ
make_moons データでeps を0.1, 0.2, 0.3に変えて結果を比較してください。
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
X, _ = make_moons(n_samples=300, noise=0.05, random_state=42)
for eps in [0.1, 0.2, 0.3]:
dbscan = DBSCAN(eps=eps, min_samples=5)
labels = dbscan.fit_predict(X)
n_clusters = len(set(labels)) – (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f”eps={eps}: clusters={n_clusters}, noise={n_noise}”)
eps=0.2が最適(2クラスタ、ノイズ0)
📝 STEP 18 のまとめ
✅ このステップで学んだこと
- 教師なし学習:正解ラベルなしでパターンを発見
- K-means:最も基本的なクラスタリング、球状クラスタ向き
- エルボー法:イナーシャの減少が緩やかになる点でKを決定
- シルエット分析:クラスタリングの品質を評価(-1〜1)
- 階層的クラスタリング:デンドログラムで階層構造を可視化
- DBSCAN:密度ベース、任意の形状、外れ値検出可能
🚀 次のステップへ
次のSTEP 19では、次元削減を学びます。PCA(主成分分析)とt-SNEを使って、高次元データを可視化・圧縮する方法を習得しましょう!
❓ よくある質問
Q1. K-meansの結果が毎回違うのはなぜ?
初期のセントロイド配置がランダムなためです。random_stateを固定するか、n_initで複数回実行して最良の結果を選びましょう。
Q2. クラスタリング前にスケーリングは必要?
はい、推奨されます。K-meansやDBSCANは距離ベースのため、スケールが大きい特徴量に引っ張られます。StandardScalerで標準化してから使用しましょう。
Q3. DBSCANのepsをどう決める?
k-距離グラフを使う方法があります。各点について最近傍k点までの距離をプロットし、急激に増加する点をepsとして選びます。
Q4. 大規模データにK-meansを使うには?
MiniBatchKMeansを使用します。データの一部で更新を行うため、大規模データでも高速に動作します。
Q5. クラスタリングの結果をどう評価する?
内部評価指標:シルエットスコア、Calinski-Harabaszスコア、Davies-Bouldinスコア
正解ラベルがある場合:調整ランド指数(ARI)、正規化相互情報量(NMI)
artnasekai
#artnasekai #学習メモ