k-means(k平均法)は、データを「k個のクラスタ」に分け、各クラスタの中心(重心)に最も近い点同士を集める教師なし学習の手法である。
目的は「クラスタ内のばらつきを最小化し、クラスタ間の分離を良くする」こと。分類器ではなく、分割・要約のための手法。
ここでの「クラスタ内平方和(SSE)を最小化」とは、次を意味する。
- 初期中心の設定:ランダムまたはk-means++でk個の中心を決める
- 割り当て:各点を最も近い中心に割り当てる
- 更新:割り当てられた点の平均を新しい中心にする
- 収束:中心がほぼ動かなくなるまで2〜3を繰り返す
graph LR
A[データ] --> B[中心の初期化]
B --> C[各点を最寄り中心へ割り当て]
C --> D[中心を平均で更新]
D --> E{収束?}
E -- No --> C
E -- Yes --> F[クラスタ確定]
前提・注意
- k(クラスタ数)は事前に決める必要がある
- 初期値により結果が変わる(局所解)
- 距離は通常ユークリッド距離(連続値が前提)
- スケールが違うと結果が歪むので標準化が基本
利点
- 実装が簡単で高速
- 大規模データに向く
- 結果が直感的(中心と距離)
欠点
- kを事前に決める必要がある
- 非凸形状のクラスタに弱い
- 外れ値に引っ張られやすい
- カテゴリ変数が扱いにくい
Python での実例
元データ + クラスタ中心
- 点群:元のデータ(x1, x2)
- 大きな点:各クラスタの中心
クラスタ割り当て後
- 色:割り当てられたクラスタ
- 中心:各クラスタの平均位置
import numpy as np
import matplotlib.pyplot as plt
# 分かりやすい人工データ(3クラスタ)
rng = np.random.RandomState(0)
X1 = rng.randn(100, 2) + np.array([0, 0])
X2 = rng.randn(100, 2) + np.array([3, 3])
X3 = rng.randn(100, 2) + np.array([0, 4])
X = np.vstack([X1, X2, X3])
def kmeans(X, k, max_iter=100):
# 初期中心をランダムに選ぶ
rng = np.random.RandomState(0)
centers = X[rng.choice(len(X), k, replace=False)]
for _ in range(max_iter):
# 各点を最も近い中心へ割り当て
dists = np.linalg.norm(X[:, None, :] - centers[None, :, :], axis=2)
labels = np.argmin(dists, axis=1)
# 新しい中心を計算
new_centers = np.array([X[labels == i].mean(axis=0) for i in range(k)])
# 収束判定
if np.allclose(centers, new_centers, atol=1e-4):
break
centers = new_centers
return labels, centers
labels, centers = kmeans(X, k=3)
# 図1:元データ + 初期中心
plt.figure()
plt.scatter(X[:, 0], X[:, 1], alpha=0.3)
plt.title("Original data")
plt.xlabel("x1")
plt.ylabel("x2")
plt.axis("equal")
plt.show()
# 図2:k-means後
plt.figure()
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap="tab10", alpha=0.5)
plt.scatter(centers[:, 0], centers[:, 1], c="black", s=120, marker="x")
plt.title("k-means clustering")
plt.xlabel("x1")
plt.ylabel("x2")
plt.axis("equal")
plt.show()
出力:

数学での使いどころ
数学・統計の文脈では、k-meansは以下の用途で使われる。
- データの代表点(プロトタイプ)抽出
- データの量子化(ベクトル量子化)
- 距離に基づく分割の理解
数学的には、以下で定式化される。
- 目的関数:クラスタ内平方和(SSE, Sum of Squared Errors)の最小化
- 「割り当て」と「中心更新」を交互に行う最適化
- k-meansはEMアルゴリズムの特例とみなせる
機械学習での使いどころ
機械学習では、k-meansは主に教師なし学習として使われる。
- クラスタリングの基礎手法
- 特徴量の要約・圧縮(Bag of Visual Wordsなど)
- セグメンテーション(画像や顧客のグルーピング)
具体的な利用例:
- 顧客の購買パターン分割
- 画像の色クラスタリング
- 文書のトピック概略の抽出
- k-meansでのクラスタラベルを特徴量として使う
適さないケース
- 非凸形状のクラスタ(同心円など)
- クラスタサイズ・密度が大きく違うデータ
- 外れ値が多いデータ
- 距離の意味が弱いカテゴリ中心のデータ