Menu
CoddyTech

K-Means a mano

Parte de la sección Aprendizaje no supervisado del Journey de Machine Learning de Coddy. Lección 3 de 51.

K-means repite una ronda de dos pasos para encontrar k grupos. Asignación: cada punto se une al centro más cercano. Movimiento: cada centro se desplaza a la media de sus puntos. Tres carritos de helados:

150 toallas en una playa, agrupadas en tres multitudes a la izquierda, en el medio y a la derecha. Tres carritos empiezan muy cerca entre sí, cerca del medio; unas líneas negras trazan el recorrido de cada carrito ronda tras ronda hasta una estrella en el medio de su propia multitud

Una ronda en NumPy, donde dists es una tabla de distancias con una columna por centro:

labels = dists.argmin(axis=1)  # asignar
for c in range(k):
    centers[c] = X[labels == c].mean(axis=0)  # mover

argmin(axis=1) da la columna más pequeña de cada fila: su centro más cercano. Ronda tras ronda, los centros se estabilizan; cuando ninguno se mueve, k-means ha terminado.

challenge icon

Desafío

Fácil

Un fabricante de camisetas reajusta sus tallas S, M y L para los clientes de hoy. Su antigua tabla de tallas proporciona los centros iniciales, distances(people, centers) proporciona la tabla de distancias y el programa lee cuántas rondas ejecutar.

  1. En cada ronda: asigna a cada persona y después mueve cada centro.
  2. Imprime el centro de cada talla y cuántas personas le correspondieron en la última ronda, como se muestra a continuación.

Para otro fabricante:

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

Pruébalo tú mismo

import numpy as np

# No cambies las líneas siguientes
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 clientes, una fila por cada uno: contorno de pecho y largo en cm
people = np.round(np.column_stack([chest, length]), 1)

# La tabla de tallas anterior establece los centros iniciales: 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())


# Tabla de distancias: una fila por persona, una columna por centro
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


# Escribe tu código a continuación
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Aprendizaje no supervisado

Practica por tu cuenta: Compilador de Python online