Menu
CoddyTech

手作業で行うK-Means

CoddyのMachine Learningジャーニー「教師なし学習」セクションの一部。レッスン 3/51。

K-means は、k個のクラスターを見つけるために、2つのステップからなるラウンドを繰り返します。割り当て:各点は最も近い中心に属します。移動:各中心は、その中心に属する点の平均の位置に移動します。アイスクリームカートが3台あります:

ビーチに150枚のタオルがあり、左・中央・右の3つの集まりになっている。3台のカートは中央付近で互いに近い位置から出発し、黒い線が、各ラウンドで各カートが自分の集まりの中央にある星まで進む経路を示している

NumPyでの1ラウンド。distsは、中心ごとに1列を持つ距離テーブルです。

labels = dists.argmin(axis=1)  # 割り当てる
for c in range(k):
    centers[c] = X[labels == c].mean(axis=0)  # 移動する

argmin(axis=1) は各行で最小の列、つまり最も近い中心を返します。繰り返すうちに中心が落ち着き、どの中心も動かなくなったら k-means は完了です。

challenge icon

チャレンジ

簡単

Tシャツメーカーが、現在の顧客に合わせてサイズS、M、Lを調整します。古いサイズ表を中心の初期値とし、distances(people, centers)で距離表を作成し、プログラムは実行する反復回数を読み取ります。

  1. 各反復で、すべての人を割り当ててから、すべての中心を移動します。
  2. 以下のように、各サイズの中心と、最後の反復でそのサイズに割り当てられた人数を出力します。

別のメーカーの場合:

Rounds run: 2
S: chest 87.3 cm, length 65.1 cm, 14 people
M: chest 95.0 cm, length 68.9 cm, 31 people
L: chest 104.8 cm, length 72.6 cm, 45 people

自分で試してみよう

import numpy as np

# 以下の行は変更しないでください
rng = np.random.default_rng(12)
chest = np.concatenate([rng.normal(88, 3, 30), rng.normal(98, 3.5, 35), rng.normal(110, 4, 25)])
length = np.concatenate([rng.normal(66, 1.8, 30), rng.normal(70, 2, 35), rng.normal(75, 2.2, 25)])
# 90人の顧客を1人につき1行で表す:胸囲と丈の単位はcm
people = np.round(np.column_stack([chest, length]), 1)

# 従来のサイズ表をもとに、中心を設定する:S、M、L
sizes = ["S", "M", "L"]
centers = np.array([[85.0, 64.0], [90.0, 67.0], [96.0, 69.0]])
rounds = int(input())


# 距離の表:1人につき1行、中心1つにつき1列
def distances(X, centers):
    table = np.zeros((len(X), len(centers)))
    for c in range(len(centers)):
        table[:, c] = np.sqrt(((X - centers[c]) ** 2).sum(axis=1))
    return table


# 以下にコードを書いてください
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

教師なし学習のすべてのレッスン

自分で練習してみよう: Pythonオンラインコンパイラ