Phân cụm Dữ liệu Vector K-Means++ & Đánh giá Inertia
Phân cụm K-Means là thuật toán học máy không giám sát (Unsupervised Learning) cốt lõi dùng để phân nhóm khách hàng, phân đoạn ảnh, hoặc nén vector dữ liệu (Vector Quantization). Kh…
Tiến độ của tôi ở bài này
Điểm được lưu vào tài khoản sau khi chấm bài.
Đang tải điểm của bạn…
Kiến thức và chủ đề
Kiến thức tiên quyết: kmeans pp initialization, lloyd algorithm, inertia computation, broadcasting distance.
Nội dung đề bài
Mục tiêu kiến thức
- Hiểu sâu và tự cài đặt thuật toán Phân cụm K-Means kinh điển (Thuật toán Lloyd).
- Khắc phục nhược điểm nhạy cảm với khởi tạo ban đầu bằng kỹ thuật khởi tạo thông minh K-Means++ (Arthur & Vassilvitskii, 2007).
- Tối ưu hóa tính toán ma trận khoảng cách giữa các điểm dữ liệu và các tâm cụm bằng Broadcasting NumPy O(1) loop.
- Tính toán chỉ số đánh giá độ kết tụ của cụm: Tổng bình phương khoảng cách nội cụm (Inertia / WCSS).
Mô tả bài toán
Phân cụm K-Means là thuật toán học máy không giám sát (Unsupervised Learning) cốt lõi dùng để phân nhóm khách hàng, phân đoạn ảnh, hoặc nén vector dữ liệu (Vector Quantization). Khởi tạo ngẫu nhiên thông thường rất dễ bị rơi vào cực tiểu cục bộ (Local Minima). K-Means++ giải quyết triệt để vấn đề này bằng cách chọn các tâm cụm trải rộng tối đa trong không gian.
Hãy xây dựng lớp:
class VectorizedKMeans:
def __init__(self, n_clusters: int = 3, max_iter: int = 100, tol: float = 1e-4, random_state: int = 42):
...
def fit(self, X: np.ndarray) -> "VectorizedKMeans":
...
def predict(self, X: np.ndarray) -> np.ndarray:
...
@property
def cluster_centers_(self) -> np.ndarray:
...
@property
def inertia_(self) -> float:
...Quy trình thuật toán:
- Khởi tạo K-Means++:
- Thiết lập
rng = np.random.RandomState(random_state). - Chọn ngẫu nhiên tâm cụm đầu tiên c0 từ tập X theo phân phối đều.
- Với các tâm tiếp theo c1, …, cK-1:
- Với mỗi điểm dữ liệu xi, tính khoảng cách bình phương nhỏ nhất tới các tâm đã chọn:
D(xi)2 = minj < k |xi - cj|2
- Tính xác suất chọn điểm tiếp theo: P(xi) = D(xi)2∑m=1N D(xm)2.
- Chọn tâm tiếp theo bằng
rng.choice(N, p=P). - Vòng lặp tối ưu hóa Lloyd:
- Ở mỗi bước lặp:
- Gán nhãn (Assignment): Tính khoảng cách bình phương từ mỗi điểm X tới tất cả các tâm hiện tại C bằng broadcasting. Gán nhãn cho mỗi điểm:
labelsi = argmink |xi - ck|2
- Cập nhật tâm (Update): Tính tâm mới bằng trung bình cộng các điểm trong cụm:
cknew = mean(X[labels == k], axis=0) *(Nếu một cụm không có điểm nào rơi vào, gán lại tâm đó bằng một điểm ngẫu nhiên trong X)*.
- Kiểm tra hội tụ: Tính khoảng cách di chuyển cực đại của các tâm:
shift = maxk |cknew - ck|2. Nếu shift ≤ tol, dừng vòng lặp sớm. Cập nhật tâm cụm và lặp tiếp tối đa max_iter lần.
- Tính quán tính (Inertia):
- Quán tính (Within-Cluster Sum of Squares) là tổng khoảng cách bình phương từ mọi điểm tới tâm cụm tương ứng của nó:
Inertia = ∑i=1N |xi - clabelsi|2
- Lưu trữ dưới dạng thuộc tính
self.inertia_(kiểu float làm tròn số học).
Input
- Các tham số truyền vào hàm/lớp VectorizedKMeans hoặc dữ liệu đầu vào theo định dạng mô tả.
Output
- Kết quả trả về của hàm/lớp VectorizedKMeans hoặc dữ liệu in ra màn hình theo đúng đặc tả.
Ràng buộc
- Số cụm K ≥ 1, số điểm dữ liệu N ≥ K.
- Tuyệt đối không dùng thư viện ngoài ngoại trừ
numpy.
Ví dụ 1
Input
VectorizedKMeans(data=[[-1.0, -1.0], [0.0, 0.0], [1.0, 1.0], [-0.5, 0.5], [99.0, 99.0], [100.0, 100.0], [101.0, 101.0], [100.5, 99.5]], n_clusters=2, test_points=[[0.2, 0.2], [99.8, 100.2]])Output
[0, 1]Giải thích
Hàm được gọi với các tham số mẫu trên và trả về kết quả chính xác theo yêu cầu.
Ví dụ 2
Input
VectorizedKMeans(data=[[0.0, 0.0], [0.1, 0.1], [0.2, 0.0], [50.0, 50.0], [50.1, 50.1], [50.2, 50.0]], n_clusters=2, test_points=[[0.05, 0.05], [0.15, 0.05]])Output
[0, 1]Giải thích
Hàm được gọi với bộ tham số thứ hai và trả về kết quả tương ứng theo thiết kế.
Gợi ý và lời giải chỉ mở sau khi bạn bấm Nộp bài. Giáo viên và quản trị viên mở được ngay.
Góp ý & báo lỗi bài tập
Đề bài chưa rõ, test có vấn đề hay bạn có ý tưởng giúp bài tốt hơn? Gửi cho đội ngũ AI Empire nhé — mỗi góp ý đều được đọc.
