Menu
CoddyTech

Điểm số Silhouette

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 8 trên 51.

Quán tính luôn cải thiện khi k tăng, nên cần tìm điểm khuỷu tay. Hệ số silhouette đặt ra một câu hỏi công bằng hơn cho từng điểm: điểm đó gần nhóm của mình hơn hay nhóm kế bên?

Một điểm màu đen được nối bằng các đường liền nét với 8 điểm thuộc nhóm của nó, độ dài trung bình a = 1.3, và bằng các đường nét đứt với 8 điểm thuộc nhóm gần nhất khác, độ dài trung bình b = 3.4. Hệ số silhouette của điểm đó là 0.62

Một điểm có điểm số (b - a) / max(a, b): gần 1 nghĩa là nằm khít trong cụm của nó, gần 0 nghĩa là nằm ở ranh giới, dưới 0 nghĩa là nằm sai cụm. Điểm trung bình đánh giá một phép phân cụm:

from sklearn.metrics import silhouette_score
for k in [2, 3, 4]:
    km = KMeans(n_clusters=k, n_init=10, random_state=0)
    km.fit(X)
    print(k, f"{silhouette_score(X, km.labels_):.3f}")

Với táo, đoạn này in ra:

2 0.534
3 0.657
4 0.545

Điểm này đạt đỉnh ở k tốt nhất, ở đây là 3, khi các điểm dữ liệu có vẻ phù hợp nhất.

challenge icon

Thử thách

Dễ

Hai nhà dự báo bất đồng về số loại bão đổ bộ vào vùng ven biển của họ. Đoạn khởi đầu có 150 cơn bão, gồm tốc độ gió cực đại và lượng mưa, rồi đọc k của Ana, sau đó đến k của Ben.

  1. Chấm điểm từng k bằng hệ số silhouette, đến 3 chữ số thập phân.
  2. In ra k nào phù hợp hơn.
  3. In ra k tốt nhất từ 2 đến 8, cùng với điểm số.

Với một vùng ven biển khác:

Ana, k = 2: 0.512
Ben, k = 3: 0.574
Ben's k fits better
Best from 2 to 8: k = 3 (0.574)

Tự làm thử

import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# Đừng thay đổi các dòng bên dưới
rng = np.random.default_rng(6)
# Bốn loại bão: tốc độ gió, lượng mưa điển hình và số cơn bão mỗi loại
kinds = [(30, 8, 40), (12, 34, 35), (21, 21, 30), (11, 9, 45)]
parts = []
for w, r, n in kinds:
    parts.append(np.column_stack([rng.normal(w, 2.5, n), rng.normal(r, 3, n)]))
# 150 cơn bão ở cùng một vùng ven biển, mỗi cơn một hàng: tốc độ gió cực đại (m/s) và lượng mưa (mm mỗi giờ)
storms = np.round(np.concatenate(parts), 1)

# Số loại bão theo dự đoán của hai người dự báo thời tiết
k_ana = int(input())
k_ben = int(input())

# 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