Thuật toán phân cụm không gian tăng dần


8

Tôi đang tìm kiếm một thuật toán phân cụm không gian gia tăng . Đây là trường hợp sử dụng của tôi:

  • người dùng tạo các mục với vị trí ban đầu
  • người dùng có thể thay đổi vị trí của các mục hiện có

Bây giờ tôi muốn triển khai một dịch vụ tách rời cung cấp thông tin phân cụm của những dữ liệu này. Dịch vụ sẽ được thông báo mỗi khi một mục mới được thêm vào hoặc một mục hiện có đã được di chuyển. Do đó, một thuật toán phân cụm tốt là gì? Lý tưởng nhất, nó nên mở rộng quy mô lên đến lượng dữ liệu cao và nếu có sự đánh đổi giữa chất lượng cụm và độ phức tạp thời gian chạy, tôi sẽ ổn với kết quả giảm dầncuối cùng kết quả ổn định (đôi khi kết quả ổn định).

Để tóm tắt các yêu cầu của tôi:

  • phân cụm không gian dựa trên các vị trí
  • sửa đổi gia tăng về thay đổi
  • thêm vị trí mới
  • thay đổi vị trí hiện có
  • hiệu suất thời gian chạy tốt

Cảm ơn trước!


1
Các cụm sẽ được sử dụng để làm gì? Họ có ý nghĩa gì? (Các câu trả lời cho những điều này cung cấp các cách cơ bản nhất để chọn thuật toán phân cụm.)
whuber

sự kiện cũng hiếm hay phổ biến? liên quan đến một dân số có nguy cơ? hoặc chỉ đơn giản là làm nổi bật các khu vực mà mọi người sống sẽ ổn?
Ian Turton

@whuber: Các cụm sẽ được sử dụng để làm cho các mục dễ khám phá hơn trên bản đồ (do đó có thể có các cụm khác nhau ở các mức thu phóng khác nhau); Chúng có nghĩa là một sự tập trung của các mặt hàng có sẵn trong các khu vực nhất định.
b_erb

@iant: Việc tạo ra các mặt hàng mới sẽ xảy ra rất thường xuyên, việc thay đổi vị trí của các mặt hàng hiện tại sẽ hiếm khi xảy ra. Không có mô hình chi tiết để dự kiến ​​làm thế nào các sự kiện xảy ra. Tuy nhiên, việc tạo ra đồng thời nhiều mặt hàng cùng một lúc ít có khả năng.
b_erb

@PartlyCloudy Tôi có ý tưởng, nhưng tôi vẫn không hiểu cách phân cụm sẽ giúp ích. OK, giả sử bạn xác định nội bộ các cụm điểm nhất định. Điều đó sẽ ảnh hưởng đến giao diện người dùng như thế nào (hay nói chung hơn là "tính khám phá" của dữ liệu)? Tùy thuộc vào cách bạn trả lời, có thể có các giải pháp (a) cực kỳ nhanh chóng và dễ thực hiện nhưng (b) thường không được coi là thuật toán "phân cụm".
whuber

Câu trả lời:


4

Mục đích của việc phân cụm này là để đơn giản hóa việc hiển thị các ký hiệu điểm: khi nhiều điểm gần nhau trên bản đồ, chúng sẽ được thay thế bằng một ký hiệu duy nhất để biểu thị một nhóm.

Các yêu cầu chỉ ra nhu cầu về một giải pháp thích ứng đơn giản : các biểu tượng điểm có thể được cập nhật và khi người dùng phóng to, các biểu tượng khác nhau sẽ xuất hiện ở các vị trí khác nhau trên phạm vi bản đồ (hoặc màn hình).

Một ứng cử viên xuất sắc rõ ràng là một phần tư khu vực .

Có một phương pháp đơn giản hơn sẽ hoạt động như một phần tư khu vực. Nó đòi hỏi ít mã hóa hơn, không tạo ra cấu trúc dữ liệu trước, nhưng bạn phải trả một mức giá (nhỏ) bằng cách thực hiện một số tính toán nhanh chóng trong quá trình phóng to và xoay. Chỉ cần lưới bản đồ . Cụ thể, giả sử có các ký hiệu điểm n được vẽ trong phạm vi hiện tại của bản đồ có chiều dài dx và chiều cao của dy . Liên quan đến nguồn gốc của bản đồ, các ký hiệu cần được vẽ tại tọa độ ( x [i] , y [i] ), i = 1, 2, ..., n . Chọn một ô lưới của c phân vùng bản đồ thành một lưới các ô. Các tế bào trong đó vị trí (x , y ) thuộc hàng j ( y ) = Tầng [ y / c ] và cột j ( x ) (đếm từ 0, với các hàng đi từ dưới lên trên và các cột từ trái sang phải). Bạn có thể coi bất kỳ ô nào nhận được hai hoặc nhiều điểm là một "cụm". Biểu tượng cụm có thể được vẽ ở trung tâm của ô, có tọa độ. ( J + c / 2, k + c / 2).

Điều này dẫn đến giải pháp sau đây, được trình bày dưới dạng mã giả:

m = Floor(dy/c)+1
n = Floor(dx/c)+1
Dimension a[m,n] = 0
For each (x[i], y[i]) to be displayed:
    Increment( a[ j(y[i]), j(x[i]) ] )
End for
For each (x[i], y[i]) to be displayed:
    row = j(y[i])
    col = j(x[i])
    If  a[row, col] > 1:
        Draw a symbol for a cluster of k points at (c*(col+0.5), c*(row+0.5))
        a[row, col] = 0
    Else
        Draw a point symbol at (x[i], y[i])
    End if
End for

Rõ ràng gánh nặng tính toán của thuật toán là O (# điểm) trong thời gian và O (dx * dy / c ^ 2) trong bộ lưu trữ. Sự đánh đổi liên quan đến việc chọn các tế bào c là:

  1. c nên càng lớn càng tốt: Dung lượng lưu trữ tỷ lệ nghịch với c ^ 2: giá trị nhỏ của c có nghĩa là lượng RAM lớn. (Lưu trữ có thể được giảm xuống O (# điểm) bằng cách sử dụng các mảng hoặc từ điển thưa thớt.)

  2. c nên càng lớn càng tốt: Hai ký hiệu (điểm hoặc cụm) sẽ không bao giờ gần hơn c / 2.

  3. c nên càng nhỏ càng tốt: mọi ký hiệu cụm đại diện cho các vị trí không quá c / sqrt (2) cách xa nó.

  4. c nên càng nhỏ càng tốt: Các giá trị lớn của c có xu hướng tạo ra nhiều cụm và cho phép một vài điểm riêng lẻ xuất hiện.

Hãy phân tích nhanh về (4). Như một điểm khởi hành, giả sử các vị trí được ánh xạ xảy ra thống nhất ngẫu nhiên và độc lập với nhau. Số lượng ô là N ( c ) = (Tầng ( dx / c ) +1) * (Tầng ( dy / c ) +1), trong đó - ít nhất là đối với các giá trị lớn hơn của c - là tỷ lệ trực tiếp với c ^ 2. Sự phân bố số lượng tế bào sẽ theo một định luật Poisson với cường độ lambda = n / N ( c ) = n * c ^ 2 / ( dx * dy). Số lượng cụm dự kiến ​​bằng

e ( c ) = n (1 - exp (- lambda ) (1 + lambda )).

Điều này trở nên nhỏ hơn khi lambda co lại thành 0; đó là, khi các tế bào c ngày càng nhỏ hơn. Điểm của phân tích này là công thức trước cho phép bạn dự đoán có bao nhiêu cụm, vì vậy bạn có thể chọn giá trị ban đầu của ce ( c ) dưới giá trị chấp nhận được (trong khi vẫn đủ lớn để giới hạn RAM yêu cầu). Không có giải pháp dạng đóng, nhưng một vài bước Newton-Raphson sẽ hội tụ nhanh chóng.

Cách tiếp cận này rất năng động - đủ nhanh để có thể tính toán phân cụm và kết quả phân cụm theo từng mức thu phóng và pan, và không yêu cầu cấu trúc dữ liệu được tính toán trước - rằng "sửa đổi gia tăng" mong muốn khi dữ liệu được cập nhật sẽ tự động xảy ra.


Điều gì sẽ xảy ra nếu trực quan bạn có một nhóm các điểm tập trung gần khu vực 4 góc. Bạn sẽ không có 4 cụm sao?
Kirk Kuykendall

@Kirk Trên thực tế, tình huống này có thể chia một cụm lớn thành hai đến bốn cụm hoặc các điểm riêng lẻ; nó sẽ không tạo ra các cụm nhân tạo. Điều này có thể xảy ra với một phần tư khu vực, quá. Có một số giải pháp. Một là bù điểm gốc của lưới bằng một lượng ngẫu nhiên trong khoảng từ 0 đến -c (ở cả hai tọa độ), để các điều kiện như vậy không giữ được vĩnh viễn. Một cách khác là tạo ra một góc phần tư một cách linh hoạt, điều chỉnh nó theo các điểm (thay vì sử dụng các điểm cắt cố định). Rõ ràng điều này cần nhiều mã hóa hơn. Một giải pháp tốt là bỏ qua tình huống: nó có thực sự là một vấn đề như vậy không?
whuber

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.