Cách Mình Quản Lý Clustering

Nguyên tắc tạo ra clusters nhất quán, hữu dụng từ noisy data

Clustering algorithms cho ra nhóm toán học, chưa chắc khớp với kỳ vọng con người. Data thật thì luôn có outliers không biết xếp đâu, clusters quá to để xài được, clusters quá bé chẳng mang ý nghĩa gì. Chạy algorithm xong mới là bắt đầu -- phần post-processing mới quyết định output có dùng được không.

Câu hỏi cốt lõi: "Mỗi item có kết thúc trong một cluster có ý nghĩa semantic không?"

Outliers -- tính năng chứ không phải lỗi

Nhiều người thấy outliers là cố nhét hết vào cluster nào đó cho gọn. Sai.

Phải phân biệt hai loại: "true outliers" (items thực sự unique, không giống ai) và "orphans" (items lẽ ra thuộc cluster nào đó nhưng bị bỏ sót). Orphans thì reassign vào nearest cluster dùng cosine similarity và k-NN voting. True outliers thì giữ riêng trong category "Other" rõ ràng.

Force-assign item unique vào cluster không liên quan thì cluster coherence giảm, user nhìn vào bối rối. Nhưng để orphans lang thang unassigned thì lãng phí data. Phải cân bằng.

Kiểm soát size distribution

Algorithm cho ra một cluster 500 items và mấy cluster 3 items -- kiểu phân phối này không ai xài được. Cluster 500 items thì quá rộng, phân tích chẳng có insight gì. Cluster 2 items thì thường là noise.

Định nghĩa size bounds chấp nhận được (minimum và maximum). Subdivide oversized clusters, merge undersized clusters vào nearest neighbors. Quan trọng: làm các bounds này configurable theo use case, vì mỗi dataset có đặc thù riêng.

Validate trước khi reassign

Reassign outliers thuần túy bằng distance mà không kiểm tra semantic fit thì hay ra kết quả vô lý -- kiểu đặt "apple" vào cluster "automotive parts" vì nó gần nhất về toán.

Khi reassign, verify similarity vượt ngưỡng. Dùng k-NN voting giữa neighbors chứ đừng chỉ nearest-neighbor. Chỉ reassign khi point thực sự fit. Nearest trong vector space không phải lúc nào cũng là semantically related, nhất là sau dimensionality reduction.

Lặp cho đến khi ổn định

Chạy post-processing một lần rồi dừng thì thường chưa đủ. Sau khi merge small clusters, có thể cluster mới lại quá lớn. Subdivide xong, có thể tạo ra clusters quá nhỏ. Các thao tác tương tác qua lại với nhau.

Chạy size correction iterative cho đến khi sizes ổn định hoặc đạt maximum iterations (10 là thường đủ). Log thay đổi mỗi iteration để debug. Đừng quên set giới hạn -- không thì edge cases chạy vô hạn luôn =))

Labels phải reflect nội dung thật

"Cluster 1", "Cluster 2" -- nhìn vào chẳng biết trong đó có gì. Labels tệ thì toàn bộ công sức clustering coi như bỏ.

Generate labels từ cluster content: sample representative items rồi dùng LLM tạo labels ngắn gọn, có ý nghĩa. Quan trọng là generate labels ở bước cuối cùng, sau khi tất cả post-processing xong. Labels mà generate trước cleanup thì merge/split xong labels cũ thành sai hết.

Khung quyết định

Reassign outliers hay giữ riêng?

Reassign khi:

  • Similarity cao với cluster centroid (>0.7 cosine similarity)
  • Nhiều nearest neighbors thuộc cùng cluster (k-NN consensus)
  • Outlier có vẻ borderline, không thực sự unique
  • User ưu tiên complete assignment hơn precision

Giữ riêng khi:

  • Similarity với tất cả clusters thấp (dưới 0.5)
  • Nearest neighbors chia đều qua nhiều clusters (không consensus)
  • Point thực sự unique hoặc ambiguous
  • User ưu tiên precision hơn complete assignment

Khi nào subdivide cluster lớn?

Subdivide khi:

  • Size vượt maximum threshold (50+ items chẳng hạn)
  • Cluster chứa sub-groups semantically distinct
  • Hierarchical structure giúp user hiểu hơn
  • Granularity setting yêu cầu fine-grained

Giữ nguyên khi:

  • Items thực sự similar (intra-cluster similarity cao)
  • Subdivision tạo ra sub-clusters nhìn tùy tiện
  • User muốn broad, high-level clustering
  • Cluster đại diện cho large category hợp lý

Khi nào merge small clusters?

Merge khi:

  • Size dưới minimum threshold (3 items chẳng hạn)
  • Centroids gần nhau, similarity cao giữa clusters
  • Merged cluster vẫn coherent
  • Small cluster có vẻ là noise

Giữ riêng khi:

  • Cluster nhỏ nhưng đại diện category distinct, có ý nghĩa
  • Merge sẽ kết hợp items không liên quan
  • User muốn granular clustering
  • Precision quan trọng hơn coverage

Mấy lỗi hay gặp

Threshold cố định cho mọi dataset. 100 items chạy ngon, 10,000 items thì tệ. Parameters cho English mà áp cho tiếng Việt cũng không ổn. Scale thresholds theo dataset size, test trên data representative, và làm key thresholds configurable.

Subdivision bỏ qua semantics. Cluster lớn bị chia đôi kiểu arbitrary, sub-clusters không có meaningful distinction gì. Dùng hierarchical clustering hoặc semantic-aware subdivision -- chia theo natural semantic boundaries, đừng cắt bừa.

Reassign quá mạnh tay. Mọi point đều phải có nhà, không ai được là outlier. Kết quả là clusters chứa items rõ ràng không thuộc về. Thêm similarity threshold, chấp nhận rằng một số points là genuine outliers, và surface category "Other" cho user thấy.

Không giới hạn iteration. Post-processing loop chạy mãi trên edge cases, system treo. Set maximum iterations, log khi đạt limit. Kết quả "đủ tốt" còn hơn chạy mãi không xong.

Labels generate trước cleanup. Merge/split xong thì labels cũ mô tả nội dung đã bị di chuyển -- sai hết. Luôn generate labels ở bước cuối, sau khi post-processing hoàn tất. Labels phản ánh cluster membership cuối cùng mới đúng.

Checklist đánh giá

Đang ổn nếu:

  • Clusters nằm trong size bounds chấp nhận được (5-50 items chẳng hạn)
  • Random samples từ mỗi cluster nhất quán về semantic
  • Outliers được reassign có ý nghĩa hoặc tách riêng rõ ràng
  • Labels mô tả chính xác nội dung cluster
  • Chạy lại với cùng config cho kết quả nhất quán

Cần xem lại nếu:

  • Một số clusters lớn hơn rất nhiều so với phần còn lại
  • Clusters chứa items rõ ràng không liên quan
  • Quá nhiều items kết thúc là unassigned outliers
  • Labels không khớp nội dung thật trong cluster
  • Kết quả mỗi lần chạy ra khác nhau, không ổn định

Tham khảo nhanh

Raw Clustering Output
         |
         v
+-------------------+
| Outlier Handling  |
| - k-NN voting     |
| - Similarity check|
| - Reassign or keep|
+-------------------+
         |
         v
+-------------------+
| Size Correction   |   <----- Lặp cho đến khi ổn định
| - Subdivide large |          (tối đa 10 iterations)
| - Merge small     |
+-------------------+
         |
         v
+-------------------+
| Final Cleanup     |
| - Renumber IDs    |
| - Sort by size    |
+-------------------+
         |
         v
+-------------------+
| Label Generation  |
| - Sample items    |
| - LLM labeling    |
| - Validate fit    |
+-------------------+
Vấn đềPhát hiệnGiải pháp
Clusters quá lớnSize > max_thresholdRecursive bisection, hierarchical split
Clusters quá nhỏSize < min_thresholdMerge vào nearest theo centroid distance
Outliers (recoverable)Similarity cao với clusterk-NN voting + threshold reassignment
Outliers (genuine)Similarity thấp với tất cảGiữ trong category "Other"
Labels kémKiểm tra thủ côngRegenerate với nhiều samples hơn, prompt tốt hơn