Thủ tục phân cụm trong đó mỗi cụm có số điểm bằng nhau?


25

Tôi có một số điểm trong và tôi muốn phân cụm các điểm sao cho:R pX= ={x1,...,xn}Rp

  1. Mỗi cụm có chứa một số lượng tương đương của các yếu tố của . (Giả sử rằng số cụm chia .)nXn

  2. Mỗi cụm được "gắn kết không gian" theo một nghĩa nào đó, giống như các cụm từ -means.k

Thật dễ dàng để nghĩ ra rất nhiều thủ tục phân cụm thỏa mãn cái này hay cái kia, nhưng có ai biết cách để có được cả hai cùng một lúc không?


2
Là kích thước cụm cũng được chỉ định? Sau đó, như đã nêu, vấn đề dường như không thể giải quyết được với tôi. Xét trường hợp sau với : X = { - 1 , 0.99 , 1 , 1.01 } . Nếu bạn muốn có 2 cụm, bạn sẽ có kích thước khác nhau hoặc không "gắn kết không gian". Hoặc bạn có muốn một cái gì đó như, "càng gắn kết không gian càng tốt" - giảm thiểu khoảng cách nội cụm tối đa hay không? Giải pháp khác là cho phép mọi ước số của n là kích thước cụm - nhưng sau đó luôn có giải pháp tầm thường của n cụm có kích thước 1n=4,p=1X={1,0.99,1,1.01}nn1.
Erik P.

1
Điểm tốt. Lý tưởng nhất là tôi muốn một cái gì đó "càng gắn kết không gian càng tốt" trong khi đáp ứng các ràng buộc về số lượng bằng nhau. Nhưng tôi rất muốn nghe về bất kỳ thủ tục nào tạo ra sự đánh đổi khác ở đây, vì có lẽ chúng có thể được điều chỉnh.
Không phải Durrett

Sẽ chia dữ liệu bằng lượng tử đủ? Nếu các giá trị không đơn điệu so với nhau, tôi không biết làm thế nào khác chúng có thể 'gắn kết không gian'.
celenius

4
Đã có một số nghiên cứu gần đây về phân cụm hạn chế. Google google.com/search?q=constrained+k-means .
whuber

Chỉ là một ý tưởng không được thử nghiệm. Trong phân cụm, một thống kê Silhouette được gọi là thường xuyên được sử dụng. Nó cho bạn thấy một đối tượng được nhóm tốt như thế nào và những gì là cụm khác, người hàng xóm tốt nhất nó có thể được đăng ký. Vì vậy, bạn có thể bắt đầu với K-PHƯƠNG TIỆN hoặc phân loại khác với cụm khác nhau n 's. Sau đó di chuyển các đối tượng không được phân loại tốt (tích lũy theo thống kê) đến các cụm lân cận tốt nhất của chúng với n nhỏ hơn cho đến khi bạn có được n bằng nhau . Tôi mong đợi các lần lặp: di chuyển một số đối tượng, tính toán lại các số liệu thống kê, di chuyển một số đối tượng, v.v ... Đó sẽ là quá trình đánh đổi.
ttnphns

Câu trả lời:


6

Tôi đề nghị một cách tiếp cận hai bước:

  1. có được ước tính ban đầu tốt về các trung tâm cụm, ví dụ sử dụng phương tiện K cứng hoặc mờ.

  2. Sử dụng phép gán Hàng xóm gần nhất toàn cầu để liên kết các điểm với các trung tâm cụm: Tính toán ma trận khoảng cách giữa mỗi điểm và từng trung tâm cụm (bạn có thể làm cho vấn đề nhỏ hơn một chút bằng cách chỉ tính khoảng cách hợp lý), sao chép từng trung tâm cụm X và giải tuyến tính bài toán giao . Bạn sẽ nhận được, đối với mỗi trung tâm cụm, chính xác X khớp với các điểm dữ liệu, do đó, trên toàn cầu, khoảng cách giữa các điểm dữ liệu và trung tâm cụm được giảm thiểu.

Lưu ý rằng bạn có thể cập nhật các trung tâm cụm sau bước 2 và lặp lại bước 2 để cơ bản chạy phương tiện K với số điểm cố định trên mỗi cụm. Tuy nhiên, sẽ là một ý tưởng tốt để có được một dự đoán ban đầu tốt.


4

Hãy thử biến thể k-mean này:

Khởi tạo :

  • chọn kcác trung tâm từ bộ dữ liệu một cách ngẫu nhiên, hoặc thậm chí tốt hơn bằng cách sử dụng chiến lược kmeans ++
  • đối với mỗi điểm, hãy tính khoảng cách đến trung tâm cụm gần nhất của nó và tạo một đống cho việc này
  • vẽ các điểm từ heap và gán chúng cho cụm gần nhất, trừ khi cụm đã quá đầy. Nếu vậy, hãy tính trung tâm cụm gần nhất tiếp theo và đặt lại vào heap

Cuối cùng, bạn nên có một phép phân nhóm thỏa mãn các yêu cầu của bạn về + -1 số lượng đối tượng giống nhau trên mỗi cụm (đảm bảo một số cụm cuối cùng cũng có số đúng. Các mcụm đầu tiên phải có ceilcác đối tượng, các floorđối tượng chính xác còn lại .)

Bước lặp :

Yêu cầu: một danh sách cho mỗi cụm với "đề xuất hoán đổi" (các đối tượng muốn ở trong một cụm khác nhau).

Bước E : tính toán các trung tâm cụm được cập nhật như trong phương tiện k thông thường

Bước M : Lặp qua tất cả các điểm (chỉ một hoặc tất cả trong một đợt)

Tính toán trung tâm cụm gần nhất với đối tượng / tất cả các trung tâm cụm gần hơn so với các cụm hiện tại. Nếu đó là một cụm khác nhau:

  • Nếu cụm khác nhỏ hơn cụm hiện tại, chỉ cần di chuyển nó sang cụm mới
  • Nếu có một đề xuất hoán đổi từ cụm khác (hoặc bất kỳ cụm nào có khoảng cách thấp hơn), hãy trao đổi các phép gán cụm hai phần tử (nếu có nhiều hơn một đề nghị, hãy chọn một cụm có cải tiến lớn nhất)
  • mặt khác, chỉ ra một đề xuất hoán đổi cho cụm khác

Các kích thước cụm vẫn bất biến (+ - chênh lệch trần / sàn), một đối tượng chỉ được di chuyển từ cụm này sang cụm khác miễn là nó dẫn đến sự cải thiện của ước tính. Do đó, nó nên hội tụ tại một số điểm như k-nghĩa. Nó có thể chậm hơn một chút (tức là nhiều lần lặp hơn).

Tôi không biết nếu điều này đã được xuất bản hoặc thực hiện trước đó. Đó chỉ là những gì tôi sẽ thử (nếu tôi sẽ thử k-mean. Có nhiều thuật toán phân cụm tốt hơn nhiều.)

Một nơi tốt để bắt đầu có thể là với việc triển khai k- mean trong ELKI , dường như đã hỗ trợ ba khởi tạo khác nhau (bao gồm k-nghĩa ++), và các tác giả cho biết họ cũng muốn có các chiến lược lặp khác nhau, để bao quát tất cả các phổ biến khác nhau các biến thể theo kiểu mô-đun (ví dụ Lloyd, MacQueen, ...).


2
Một cách tiếp cận tương tự được đưa vào ELKI như một hướng dẫn và trong mô-đun "mở rộng" hướng dẫn: elki.dbs.ifi.lmu.de/wiki/Tutorial/SameSizeKMeans
Erich Schubert

3

Đây là một vấn đề tối ưu hóa. Chúng tôi có một thư viện java mã nguồn mở để giải quyết vấn đề này (phân cụm trong đó số lượng trên mỗi cụm phải nằm giữa các phạm vi được đặt). Mặc dù vậy, bạn cần tổng số điểm của mình tối đa là vài nghìn - không quá 5000 hoặc có thể 10000.

Thư viện ở đây:

https://github.com/PGWelch/territorium/tree/master/territorium.core

Bản thân thư viện được thiết lập cho các vấn đề về loại địa lý / GIS - vì vậy bạn sẽ thấy các tham chiếu đến X và Ys, vĩ độ và kinh độ, khách hàng, khoảng cách và thời gian, v.v. Bạn chỉ có thể bỏ qua các yếu tố 'địa lý' và sử dụng nó như một cách thuần túy cụm.

Bạn cung cấp một tập hợp các cụm đầu vào trống ban đầu, mỗi cụm có số lượng mục tiêu tối thiểu và tối đa. Trình phân cụm sẽ gán các điểm cho các cụm đầu vào của bạn, sử dụng thuật toán tối ưu hóa dựa trên kinh nghiệm (hoán đổi, di chuyển, v.v.). Trong tối ưu hóa, trước tiên, ưu tiên giữ cho mỗi cụm trong phạm vi số lượng tối thiểu và tối đa của nó và sau đó tối thiểu hóa khoảng cách giữa tất cả các điểm trong cụm và điểm trung tâm của cụm, do đó, một cụm được gắn kết theo không gian.

Bạn cung cấp cho người giải một hàm số liệu (tức là hàm khoảng cách) giữa các điểm bằng giao diện này:

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistic/territorium/probols/TravelMatrix.java

Số liệu thực sự được cấu trúc để trả về cả khoảng cách và 'thời gian', bởi vì nó được thiết kế cho các vấn đề địa lý dựa trên du lịch, nhưng đối với các vấn đề phân cụm tùy ý chỉ đặt 'thời gian' thành 0 và khoảng cách là số liệu thực tế của bạn mà bạn đang sử dụng điểm.

Bạn sẽ thiết lập vấn đề của mình trong lớp này:

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistic/territorium/probols/Pro Hiệu.java

Điểm của bạn sẽ là 'Khách hàng' và số lượng của họ sẽ là 1. Trong lớp khách hàng, đảm bảo bạn đặt costPerUnitTime = 0 và costPerUnitDistance = 1 giả sử bạn trả về khoảng cách số liệu của mình trong trường 'khoảng cách' được TravelMatrix trả về.

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistic/territorium/probols/Customer.java

Xem ở đây để biết ví dụ về việc chạy bộ giải:

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/test/java/com/opendoorlogistic/territorium/TestSolver.java



2

Gần đây tôi cần điều này cho một bộ dữ liệu không lớn. Câu trả lời của tôi, mặc dù nó có thời gian chạy tương đối dài, được đảm bảo để hội tụ đến mức tối ưu cục bộ.

def eqsc(X, K=None, G=None):
    "equal-size clustering based on data exchanges between pairs of clusters"
    from scipy.spatial.distance import pdist, squareform
    from matplotlib import pyplot as plt
    from matplotlib import animation as ani    
    from matplotlib.patches import Polygon   
    from matplotlib.collections import PatchCollection
    def error(K, m, D):
        """return average distances between data in one cluster, averaged over all clusters"""
        E = 0
        for k in range(K):
            i = numpy.where(m == k)[0] # indeces of datapoints belonging to class k
            E += numpy.mean(D[numpy.meshgrid(i,i)])
        return E / K
    numpy.random.seed(0) # repeatability
    N, n = X.shape
    if G is None and K is not None:
        G = N // K # group size
    elif K is None and G is not None:
        K = N // G # number of clusters
    else:
        raise Exception('must specify either K or G')
    D = squareform(pdist(X)) # distance matrix
    m = numpy.random.permutation(N) % K # initial membership
    E = error(K, m, D)
    # visualization
    #FFMpegWriter = ani.writers['ffmpeg']
    #writer = FFMpegWriter(fps=15)
    #fig = plt.figure()
    #with writer.saving(fig, "ec.mp4", 100):
    t = 1
    while True:
        E_p = E
        for a in range(N): # systematically
            for b in range(a):
                m[a], m[b] = m[b], m[a] # exchange membership
                E_t = error(K, m, D)
                if E_t < E:
                    E = E_t
                    print("{}: {}<->{} E={}".format(t, a, b, E))
                    #plt.clf()
                    #for i in range(N):
                        #plt.text(X[i,0], X[i,1], m[i])
                    #writer.grab_frame()
                else:
                    m[a], m[b] = m[b], m[a] # put them back
        if E_p == E:
            break
        t += 1           
    fig, ax = plt.subplots()
    patches = []
    for k in range(K):
        i = numpy.where(m == k)[0] # indeces of datapoints belonging to class k
        x = X[i]        
        patches.append(Polygon(x[:,:2], True)) # how to draw this clock-wise?
        u = numpy.mean(x, 0)
        plt.text(u[0], u[1], k)
    p = PatchCollection(patches, alpha=0.5)        
    ax.add_collection(p)
    plt.show()

if __name__ == "__main__":
    N, n = 100, 2    
    X = numpy.random.rand(N, n)
    eqsc(X, G=3)

1
Cảm ơn sự đóng góp này, @ user2341646. Bạn có phiền khi thêm một số giải thích giải thích giải pháp này là gì, cách thức hoạt động và tại sao nó là một giải pháp?
gung - Phục hồi Monica

ĐƯỢC. Về cơ bản, thuật toán bắt đầu với các bài tập thành viên là ngẫu nhiên, nhưng có gần các thành viên G trong một cụm và có tổng số K cụm. Chúng tôi xác định hàm lỗi đo khoảng cách trung bình giữa các dữ liệu trong một cụm, tính trung bình trên tất cả các cụm. Đi qua tất cả các cặp dữ liệu một cách có hệ thống, chúng tôi thấy nếu trao đổi thành viên của hai dữ liệu đó sẽ dẫn đến lỗi thấp hơn. Nếu có, chúng tôi cập nhật lỗi thấp nhất có thể, nếu không chúng tôi sẽ hoàn tác chuyển đổi thành viên. Chúng tôi làm điều này cho đến khi không còn di chuyển nữa cho toàn bộ một lượt.
Alexander Kain
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.