DBSCAN クラスタリングアルゴリズム

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、合成データセットをクラスタリングするために DBSCAN(Density-Based Spatial Clustering of Applications with Noise)アルゴリズムを使用します。DBSCAN は、高密度の領域にあるコアサンプルを識別し、それらからクラスタを拡大するクラスタリングアルゴリズムです。このアルゴリズムは、同じ密度のクラスタを含むデータに役立ちます。

VM のヒント

VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。

Jupyter Notebook が読み込み終わるまで数秒待つことがあります。Jupyter Notebook の制限により、操作の検証は自動化できません。

学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

データ生成

sklearn.datasets モジュールの make_blobs 関数を使って、3 つのクラスタを持つ合成データセットを生成します。このデータセットは、クラスタ標準偏差が 0.4 の 750 個のサンプルで構成されます。また、sklearn.preprocessing モジュールの StandardScaler を使ってデータを標準化します。

from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler

centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(
    n_samples=750, centers=centers, cluster_std=0.4, random_state=0
)

X = StandardScaler().fit_transform(X)

データ可視化

matplotlib.pyplot モジュールを使って、生成されたデータを可視化することができます。

import matplotlib.pyplot as plt

plt.scatter(X[:, 0], X[:, 1])
plt.show()

DBSCAN の計算

sklearn.cluster モジュールの DBSCAN クラスを使ってクラスタを計算します。eps パラメータを 0.3 に、min_samples パラメータを 10 に設定します。DBSCAN によって割り当てられたラベルには labels 属性を使ってアクセスできます。ノイズのサンプルには -1 のラベルが付けられます。また、クラスタの数とノイズポイントの数を計算します。

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics

db = DBSCAN(eps=0.3, min_samples=10).fit(X)
labels = db.labels_

n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_noise_ = list(labels).count(-1)

print("Estimated number of clusters: %d" % n_clusters_)
print("Estimated number of noise points: %d" % n_noise_)

評価指標

生成されたクラスタの品質を定量化するために、評価指標を使用することができます。同質性、完全性、V 尺度、調整ランド指数、調整相互情報、およびシルエット係数指標を使用します。これらの指標は sklearn.metrics モジュールからアクセスします。真のラベルがわからない場合、評価はモデル結果自体を使用してのみ行うことができます。その場合、シルエット係数が役に立ちます。

print(f"Homogeneity: {metrics.homogeneity_score(labels_true, labels):.3f}")
print(f"Completeness: {metrics.completeness_score(labels_true, labels):.3f}")
print(f"V-measure: {metrics.v_measure_score(labels_true, labels):.3f}")
print(f"Adjusted Rand Index: {metrics.adjusted_rand_score(labels_true, labels):.3f}")
print(f"Adjusted Mutual Information: {metrics.adjusted_mutual_info_score(labels_true, labels):.3f}")
print(f"Silhouette Coefficient: {metrics.silhouette_score(X, labels):.3f}")

結果のプロット

結果をプロットするために matplotlib.pyplot モジュールを使用します。コアサンプル(大きな点)と非コアサンプル(小さな点)は、割り当てられたクラスタに応じて色分けされます。ノイズとしてタグ付けされたサンプルは黒で表されます。

unique_labels = set(labels)
core_samples_mask = np.zeros_like(labels, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True

colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
    if k == -1:
        col = [0, 0, 0, 1]

    class_member_mask = labels == k

    xy = X[class_member_mask & core_samples_mask]
    plt.plot(
        xy[:, 0],
        xy[:, 1],
        "o",
        markerfacecolor=tuple(col),
        markeredgecolor="k",
        markersize=14,
    )

    xy = X[class_member_mask & ~core_samples_mask]
    plt.plot(
        xy[:, 0],
        xy[:, 1],
        "o",
        markerfacecolor=tuple(col),
        markeredgecolor="k",
        markersize=6,
    )

plt.title(f"Estimated number of clusters: {n_clusters_}")
plt.show()

まとめ

この実験では、合成データセットをクラスタリングするために DBSCAN クラスタリングアルゴリズムを使用しました。データセットを生成し、データを可視化し、クラスタを計算し、指標を評価し、結果をプロットしました。