Menu
CoddyTech

K-Means вручную

Часть раздела Обучение без учителя путешествия по Machine Learning на Coddy. Урок 3 из 51.

K-means повторяет раунд из двух шагов, чтобы найти k кластеров. Назначение: каждая точка присоединяется к ближайшему центру. Перемещение: каждый центр перемещается к среднему значению своих точек. Три тележки с мороженым:

150 полотенец на пляже, расположенных тремя группами: слева, посередине и справа. Три тележки начинают движение рядом друг с другом недалеко от середины; чёрные линии показывают путь каждой тележки от раунда к раунду до звезды в середине её собственной группы

Один раунд в NumPy, где dists — таблица расстояний с одним столбцом на каждый центр:

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

Задание

Легко

Производитель футболок подгоняет размеры 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 покупателей, по одной строке на каждого: обхват груди и длина в см
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())


# Таблица расстояний: одна строка на человека, один столбец на центр
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