K-meansクラスタリングの基礎と実装
K-meansクラスタリングは、教師なし学習の代表的な手法の一つであり、データをいくつかのクラスタに分割するアルゴリズムです。このアルゴリズムは、データセットをK個のグループに分け、各クラスタの中心を計算しながらクラスタの最適化を行います。ここでは、K-meansの基本的な概念から実装方法まで、詳しく解説します。
K-meansクラスタリングとは?
K-meansクラスタリングは、与えられたデータをあらかじめ指定したK個のクラスタに分割するアルゴリズムです。各データ点は、その点から最も近いクラスタの中心に割り当てられます。アルゴリズムは以下のステップで実行されます。
- K個の初期クラスタ中心(セントロイド)をランダムに選択する
- 各データ点を最も近いセントロイドに割り当てる
- 各クラスタの重心を計算し、新しいセントロイドを更新する
- セントロイドの移動が小さくなるまで、または一定の回数を繰り返す
K-meansの基本的な実装
以下に、Pythonを使ったK-meansクラスタリングの実装例を示します。この例では、Scikit-learnライブラリを使って簡単にK-meansを実装します。
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# データの生成
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=0)
# K-meansモデルの作成
kmeans = KMeans(n_clusters=4)
kmeans.fit(X)
# 予測ラベルの取得
y_kmeans = kmeans.predict(X)
# クラスタのプロット
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
# クラスタの中心をプロット
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75)
plt.show()
このコードでは、Scikit-learnの `make_blobs` 関数を使ってサンプルデータを生成し、K-meansアルゴリズムを実行しています。結果として、各データ点がクラスタに分類され、そのクラスタごとに異なる色でプロットされます。また、各クラスタの中心も赤い点として表示されています。
Elbow法による最適なクラスタ数の決定
クラスタリングでは、適切なクラスタ数(K)を選ぶことが重要です。Elbow法は、異なるKに対するコスト関数(SSE: Sum of Squared Errors)を計算し、最適なKを見つけるための手法です。
distortions = []
K = range(1, 10)
for k in K:
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
distortions.append(kmeans.inertia_)
# Elbow法のプロット
plt.plot(K, distortions, 'bx-')
plt.xlabel('クラスタ数')
plt.ylabel('SSE')
plt.title('Elbow法を用いた最適クラスタ数の決定')
plt.show()
このコードでは、クラスタ数を1から9まで変え、それぞれのKに対するSSEをプロットしています。グラフの”肘”の部分でクラスタ数が最適であると考えられます。
K-means++による初期化の改善
標準のK-meansアルゴリズムでは、初期クラスタ中心の選択がランダムで行われるため、局所最適に陥る可能性があります。この問題を改善するために、K-means++アルゴリズムが導入されました。K-means++では、初期のクラスタ中心をより均等に選ぶことができます。
# K-means++の実装
kmeans_plus = KMeans(n_clusters=4, init='k-means++')
kmeans_plus.fit(X)
# 予測ラベルの取得
y_kmeans_plus = kmeans_plus.predict(X)
# プロット
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans_plus, s=50, cmap='viridis')
plt.scatter(kmeans_plus.cluster_centers_[:, 0], kmeans_plus.cluster_centers_[:, 1], c='red', s=200, alpha=0.75)
plt.show()
K-means++を使用することで、初期クラスタの中心選びが改善され、より安定したクラスタリング結果が得られることが期待されます。
K-meansの応用
K-meansは、クラスタリングだけでなく、画像の圧縮やセグメンテーション、顧客セグメンテーション、マーケティングキャンペーンの分析など、多くの分野で利用されています。例えば、画像圧縮では、ピクセルをK個のクラスタにグループ化し、色数を減らすことでデータ量を削減することができます。
画像の圧縮の例
from sklearn.cluster import MiniBatchKMeans
import numpy as np
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 画像のリシェイプ
pixel_values = image.reshape((-1, 3))
pixel_values = np.float32(pixel_values)
# K-meansによる画像圧縮
k = 16 # クラスタ数
kmeans = MiniBatchKMeans(n_clusters=k)
kmeans.fit(pixel_values)
compressed_image = kmeans.cluster_centers_[kmeans.labels_]
# 圧縮画像のリシェイプ
compressed_image = compressed_image.reshape(image.shape)
compressed_image = np.uint8(compressed_image)
# 圧縮画像の表示
plt.imshow(compressed_image)
plt.show()
この例では、K-meansを使用して画像の色を16色に減らし、圧縮しています。MiniBatchKMeansは、K-meansのメモリ使用量を削減し、大規模なデータセットに対しても効率的にクラスタリングを実行することができます。
まとめ
K-meansクラスタリングは、教師なし学習の基本的なアルゴリズムであり、多くの応用があります。データセットをK個のクラスタに分け、それぞれのクラスタの重心に基づいてデータを分類します。Elbow法やK-means++といった手法を使ってクラスタ数を決定し、初期化の問題を解決することが重要です。さらに、K-meansは画像圧縮など、さまざまな応用分野で活用されています。