Her kümenin eşit sayıda puana sahip olduğu kümeleme prosedürü?


25

Bazı noktalar var içinde ve ben böylece noktaları küme istiyorum:X={x1,...,xn}R,p

  1. Her kümede eşit sayıda elemanı bulunur . (Bu kümeler böler sayısı varsayalım .)Xn

  2. Her küme, bir anlamda, araçlarından gelen kümeler gibi, "uzamsal olarak yapışkandır" .k

Bunlardan birini veya diğerini tatmin eden birçok kümelenme prosedürünü düşünmek kolaydır, ancak bir anda ikisini birden almanın bir yolunu bilen var mı?


2
Küme boyutu da belirtilmiş mi? Sonra, belirtildiği gibi, sorun bana çözülemez gibi görünüyor. ile aşağıdaki durumu göz önünde bulundurun : X = { - 1 , 0.99 , 1 , 1.01 } . 2 küme istiyorsanız, farklı boyutlarda olsun veya olmasın "uzamsal olarak yapışkan". Veya, "küme içi maksimum mesafeyi en aza indirgeyen" mümkün olduğunca uzamsal olarak yapışkan "gibi bir şey mi istiyorsunuz? Diğer çözüm n'nin herhangi bir böleninin küme büyüklüğüne izin vermesi olacaktır - fakat o zaman her zaman n büyüklükteki 1 kümenin önemsiz çözümü vardır.n=4,p=1X={-1,0.99,1,1.01}nn1.
Erik P.,

1
İyi bir nokta. İdeal olarak, eşit kardinalite kısıtını yerine getirirken "mümkün olduğunca uzamsal olarak uyumlu" bir şey istiyorum. Fakat belki de adapte edilebildiklerinden, burada başka travmalar yapan prosedürleri de duymak isterim.
Durrett değil

Verileri niceliklere bölmek yeterli midir? Değerler birbirine göre monotonik değilse, başkalarının 'uzamsal olarak yapışkan' olabileceğini göremiyorum.
celenius

4
Sınırlandırılmış kümelenme üzerine yakın zamanda yapılmış bazı araştırmalar olmuştur. Google google.com/search?q=constrained+k-means .
whuber

Sadece bir tanesi test edilmedi. Kümelemede, sıkça siluet adı verilen bir istatistik kullanılır. Bir nesne kümelenmiş ne kadar iyi olduğunu gösterir ve ne. So kayıtlı olabilir iyi diğer komşu küme, K-ARAÇLARININ veya farklı küme ile diğer sınıflandırma ile başlayabileceğini olduğu n 'in. Daha sonra çok iyi sınıflandırılmamış nesneleri (istatistiklere göre) eşit n elde edene kadar en az n ile en iyi komşu kümelerine taşıyın . Yinelemeler bekliyorum: bazı nesneleri hareket ettir, istatistikleri yeniden hesapla, bazı nesneleri hareket ettir, vb.
ttnphns

Yanıtlar:


6

İki aşamalı bir yaklaşım öneririm:

  1. küme merkezlerinin iyi bir başlangıç ​​tahminini elde edin, örneğin sert veya bulanık K araçları kullanın.

  2. Noktaları küme merkezleriyle ilişkilendirmek için Global En Yakın Komşu atamasını kullanın: Her nokta ve her küme merkezi arasındaki bir mesafe matrisini hesaplayın (sorunu yalnızca makul mesafeleri hesaplayarak biraz daha küçük yapabilirsiniz), her küme merkezini X kez çoğaltın ve doğrusal çözümü yapın atama problemi . Her küme merkezi için tam olarak X'in veri noktalarıyla eşleştiğini göreceksiniz; böylece, genel olarak, veri noktaları ile küme merkezleri arasındaki mesafe en aza indirgenecek.

Küme merkezlerini 2. adımdan sonra güncelleyebileceğinizi ve K-araçlarını küme başına sabit sayıda noktayla çalıştırmak için 2. adımı tekrarlayabileceğinizi unutmayın. Yine de, ilk önce iyi bir tahminde bulunmak iyi bir fikir olacaktır.


4

Bu k-aracı varyasyonunu deneyin:

Başlatma :

  • kveri kümesinden merkezleri rasgele veya kmeans ++ stratejisini kullanarak daha iyi merkezler seçmek
  • Her nokta için, en yakın küme merkezine olan mesafeyi hesaplayın ve bunun için bir öbek oluşturun
  • öbekten noktalar çizin ve küme zaten fazla dolu olmadıkça bunları en yakın kümeye atayın. Öyleyse, en yakın küme merkezini hesaplayın ve yığına yeniden yerleştirin

Sonunda, küme başına + -1 aynı sayıda nesne için gereksinimlerinizi karşılayan bir bölüme sahip olmalısınız (son birkaç kümenin de doğru sayıya sahip olduğundan emin olun. İlk mkümelerin ceilnesneleri, kalanların tam olarak floornesneleri olması gerekir ).

Yineleme adım :

Gereksinimler: “takas önerileri” olan her küme için bir liste (farklı bir kümede olmayı tercih eden nesneler).

E basamağı: güncellenmiş küme merkezlerini normal k-araçları gibi hesaplayın

M adımı: Tüm noktalarda yineleme (yalnızca bir veya bir partide hepsi)

Geçerli kümelerden daha yakın olan tüm küme merkezlerine nesne / yakın küme merkezlerini hesaplayın. Farklı bir küme ise:

  • Diğer küme geçerli kümeden daha küçükse, yeni kümeye taşıyın
  • Diğer kümeden (veya daha az mesafeli herhangi bir kümeden) bir takas teklifi varsa, iki eleman kümesi atamasını değiştirin (birden fazla teklif varsa, en büyük iyileştirme olanı seçin)
  • aksi takdirde, diğer küme için bir takas teklifini belirtin

Küme büyüklükleri değişmez (+ - tavan / kat farkı), nesneler yalnızca bir kümeden diğerine taşınır ve tahminde bir iyileşme sağlanır. Bu nedenle k-aracı gibi bir noktada birleşmelidir. Yine de biraz daha yavaş (yani daha fazla yineleme) olabilir.

Bunun daha önce yayınlanıp yayınlanmadığını bilmiyorum. Sadece deneyeceğim şey (eğer k-aracı deneyecek olursam. Çok daha iyi kümeleme algoritmaları var.)

Başlamak için iyi bir yer , üç farklı başlatmayı (k-araçları ++ dahil) desteklediği anlaşılan ELKI'deki k-aracı uygulaması olabilir ve yazarlar , tüm farklı ortakları kapsayacak şekilde farklı yineleme stratejilerine sahip olmak istediklerini söyledi. modüler bir şekilde değişkenler (örneğin, Lloyd, MacQueen, ...).


2
Benzer bir yaklaşım ELKI’de bir öğretici olarak ve “genişletme” modülünde eklenmiştir
Erich Schubert

3

Bu bir optimizasyon problemidir. Bu problemi çözen açık kaynak kodlu bir java kütüphanemiz var (küme başına miktarın kümelenmiş aralıklar arasında olması gereken kümeleme). Toplam puan sayınızın en fazla birkaç bin olması gerekir - 5000 veya 10000'den fazla değil.

Kütüphane burada:

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

Kütüphanenin kendisi coğrafi / GIS tipi problemler için kuruludur - böylece X ve Y'ler, enlemler ve boylamlar, müşteriler, mesafe ve zaman, vb. Referansları görürsünüz. Ancak 'coğrafi' elementleri görmezden gelebilir ve onu saf olarak kullanabilirsiniz clusterer.

Her biri min ve maksimum hedef miktarı olan bir başlangıçta boş giriş kümeleri sağlarsınız. Clusterer, sezgisel tabanlı bir optimizasyon algoritması (takaslar, hamle vb.) Kullanarak giriş kümelerinize noktalar atayacaktır. Optimizasyonda öncelikle her bir kümeyi minimum ve maksimum miktar aralığında tutmayı öncelikli hale getirir ve daha sonra ikinci olarak kümedeki tüm noktalar ile kümenin merkezi noktası arasındaki mesafeleri en aza indirir, böylece bir küme uzamsal olarak yapışır.

Bu arayüzü kullanarak çözücüye noktalar arasında bir metrik fonksiyon (yani mesafe fonksiyonu) veriniz:

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/TravelMatrix.java

Metrik aslında hem mesafeyi hem de zamanı geri döndürecek şekilde yapılandırılmıştır, çünkü seyahat tabanlı coğrafi problemler için tasarlanmıştır, ancak rastgele kümelenme problemleri için 'zamanı' sadece sıfır olarak ve aralarında kullandığınız gerçek metrik olarak mesafeyi ayarlayın puan.

Sorununuzu bu sınıfa yerleştirirsiniz:

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/Problem.java

Puanlarınız 'Müşteriler' olur ve miktarları 1 olur. Müşteri sınıfında, metrik mesafenizi TravelMatrix'in döndürdüğü 'mesafe' alanına döndürdüğünüzü farz ederek, costPerUnitTime = 0 ve costPerUnitDistance = 1 olarak ayarladığınızdan emin olun.

https://github.com/PGWelch/territorium/blob/master/territorium.core/src/main/java/com/opendoorlogistics/territorium/problem/Customer.java

Çözücüyü çalıştırmanın bir örneği için buraya bakın:

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



2

Son zamanlarda çok büyük olmayan bir veri kümesi için buna ihtiyacım vardı. Cevabım, nispeten uzun bir çalışma süresine sahip olmasına rağmen, yerel bir optimum seviyeye yakınlaşma garantisi veriyor.

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
Bu katkı için teşekkür ederiz, @ user2341646. Bu çözümün ne olduğunu, nasıl çalıştığını ve neden çözüm olduğunu açıklayan bir açıklama ekler misiniz?
dediklerinin - Eski Monica

TAMAM. Temel olarak, algoritma rastgele olan üyelik atamalarıyla başlar, ancak bir kümedeki G üyelerine yakındır ve genel olarak K kümeleri vardır. Tüm kümelerin ortalaması alınarak, bir kümedeki veriler arasındaki ortalama mesafeleri ölçen hata fonksiyonunu tanımlarız. Tüm veri çiftlerini sistematik olarak takip ederek, bu iki verinin üyeliğini değiştirmenin daha düşük bir hatayla sonuçlanıp sonuçlanmadığını görüyoruz. Olursa, olası en düşük hatayı güncelleriz, aksi takdirde üyelik anahtarını geri alırız. Bunu, tüm pas için başka hamle kalmayacak kadar yapalım.
Alexander Kain
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.