Menu
CoddyTech

Tự thực hiện K-Means

Thuộc phần Học không giám sát trong hành trình Machine Learning của Coddy. Bài học 3 trên 51.

K-means lặp lại một vòng gồm hai bước để tìm k cụm. Gán: mỗi điểm thuộc về tâm gần nhất. Di chuyển: mỗi tâm chuyển đến vị trí trung bình của các điểm thuộc về nó. Ba xe bán kem:

150 chiếc khăn trên bãi biển được chia thành ba đám đông ở bên trái, giữa và bên phải. Ba xe bán kem bắt đầu ở gần nhau, gần khu vực giữa; các đường màu đen nối đường đi của từng xe qua từng vòng đến một ngôi sao ở giữa đám đông riêng của xe đó

Một lượt trong NumPy, trong đó dists là bảng khoảng cách với một cột cho mỗi tâm:

labels = dists.argmin(axis=1)  # Gán nhãn
for c in range(k):
    centers[c] = X[labels == c].mean(axis=0)  # Di chuyển tâm cụm

argmin(axis=1) cho biết cột có giá trị nhỏ nhất trong mỗi hàng: tâm gần nhất của hàng đó. Qua từng vòng, các tâm dần ổn định; khi không tâm nào di chuyển, thuật toán k-means hoàn tất.

challenge icon

Thử thách

Dễ

Một nhà sản xuất áo phông điều chỉnh lại các cỡ S, M và L cho khách hàng hiện nay. Bảng cỡ cũ dùng để khởi tạo các tâm, distances(people, centers) trả về bảng khoảng cách, và chương trình đọc số vòng lặp cần chạy.

  1. Mỗi vòng lặp: gán cỡ cho từng người, sau đó di chuyển từng tâm.
  2. In tâm của từng cỡ và số người được gán vào cỡ đó ở vòng lặp cuối, như bên dưới.

Với một nhà sản xuất khác:

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

Tự làm thử

import numpy as np

# Đừng thay đổi các dòng bên dưới
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 khách hàng, mỗi người một hàng: số đo vòng ngực và chiều dài tính bằng cm
people = np.round(np.column_stack([chest, length]), 1)

# Bảng kích cỡ cũ xác định các tâm ban đầu: 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())


# Bảng khoảng cách: mỗi người một hàng, mỗi tâm một cột
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


# Viết code bên dưới
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Học không giám sát

Tự luyện tập: Trình biên dịch Python online