क्लस्टरिंग प्रक्रिया जहां प्रत्येक क्लस्टर में समान अंक होते हैं?


25

मेरे पास में कुछ बिंदु , और मैं चाहता हूं कि अंक मिले:X={x1,...,xn}Rp

  1. प्रत्येक क्लस्टर में के तत्वों की बराबर संख्या होती है । (मान लें कि क्लस्टर की संख्या विभाजित करती है ।)Xn

  2. प्रत्येक क्लस्टर कुछ अर्थों में "स्थानिक रूप से सामंजस्यपूर्ण" है, जैसे -means से क्लस्टर ।k

यह बहुत सी क्लस्टरिंग प्रक्रियाओं के बारे में सोचना आसान है जो इनमें से किसी एक या दूसरे को संतुष्ट करते हैं, लेकिन क्या किसी को एक बार दोनों को प्राप्त करने का तरीका पता है?


2
क्या क्लस्टर का आकार भी निर्दिष्ट है? फिर, जैसा कि कहा गया है, समस्या मुझे असहनीय लगती है। निम्नलिखित मामले पर : X = { - 1 , 0.99 , 1 , 1.01 } के साथ विचार करें । यदि आप 2 क्लस्टर चाहते हैं, तो आपको अलग-अलग आकार मिलते हैं या "स्थानिक रूप से सामंजस्यपूर्ण" नहीं है। या क्या आप कुछ ऐसा चाहते हैं, जैसे "संभव के रूप में स्थानिक रूप से सामंजस्यपूर्ण" - अधिकतम इंट्रा-क्लस्टर दूरी या तो कम से कम? अन्य समाधान क्लस्टर आकार के रूप में n के किसी भी भाजक को अनुमति देने के लिए होगा - लेकिन फिर हमेशा आकार के समूहों का तुच्छ समाधान होता हैn=4,p=1X={1,0.99,1,1.01}nn1
एरिक पी।

1
अच्छी बात। आदर्श रूप से मैं कुछ ऐसा चाहूंगा जो समान कार्डिनैलिटी बाधा को संतुष्ट करते हुए "यथासंभव स्थानिक रूप से सामंजस्यपूर्ण" हो। लेकिन मैं किसी भी प्रक्रिया के बारे में सुनना चाहूंगा जो अन्य ट्रेडऑफ़्स को यहां भी बनाती है, क्योंकि शायद उन्हें अनुकूलित किया जा सकता है।
ड्यूरेट

क्वांटाइल पर्याप्त द्वारा डेटा का विभाजन होगा? यदि मूल्य एक-दूसरे के सापेक्ष नीरस नहीं हैं, तो मैं यह देखने में विफल रहता हूं कि वे 'स्थानिक रूप से सामंजस्यपूर्ण' कैसे हो सकते हैं।
celenius

4
विवश क्लस्टरिंग पर हाल ही में कुछ शोध हुए हैं। गूगल google.com/search?q=constrained+k-means
whuber

सिर्फ एक परीक्षण विचार नहीं है। क्लस्टरिंग में, एक तथाकथित सिल्हूट सांख्यिकीय का उपयोग अक्सर किया जाता है। यह आपको दिखाता है कि किसी वस्तु को कितनी अच्छी तरह से क्लस्टर किया गया है और सबसे अच्छा अन्य क्या है, पड़ोसी क्लस्टर में इसे दर्ज किया जा सकता है। इसलिए, आप के-एमईएएनएस या अन्य वर्गीकरण के साथ अलग क्लस्टर एन के साथ शुरू कर सकते हैं । तब वस्तुओं को बहुत अच्छी तरह से वर्गीकृत न करें (सांख्यिकीय के लिए उच्चारण) कम एन के साथ अपने सबसे अच्छे पड़ोसी समूहों के लिए जब तक आप बराबर एन प्राप्त न करें । मैं पुनरावृत्तियों की अपेक्षा करता हूं: कुछ वस्तुओं को स्थानांतरित करना, आंकड़ों को पुनर्गणना करना, कुछ वस्तुओं को स्थानांतरित करना, आदि जो व्यापार-बंद प्रक्रिया होगी।
ttnphns

जवाबों:


6

मैं दो-चरणीय दृष्टिकोण सुझाता हूं:

  1. क्लस्टर केंद्रों का एक अच्छा प्रारंभिक अनुमान प्राप्त करें, जैसे कि कठिन या फजी के-साधनों का उपयोग करना।

  2. क्लस्टर केंद्रों के साथ संबद्ध बिंदुओं के लिए वैश्विक निकटतम पड़ोसी असाइनमेंट का उपयोग करें: प्रत्येक बिंदु और प्रत्येक क्लस्टर केंद्र के बीच एक दूरी मैट्रिक्स की गणना करें (आप केवल उचित दूरी की गणना करके समस्या को थोड़ा छोटा कर सकते हैं), प्रत्येक क्लस्टर केंद्र को दोहराएं, और रैखिक को हल करें असाइनमेंट की समस्या । आपको प्रत्येक क्लस्टर केंद्र के लिए, डेटा बिंदुओं के बिल्कुल एक्स से मिलान होगा, ताकि, वैश्विक स्तर पर, डेटा बिंदुओं और क्लस्टर केंद्रों के बीच की दूरी कम से कम हो।

ध्यान दें कि आप चरण 2 के बाद क्लस्टर केंद्रों को अपडेट कर सकते हैं और चरण 2 को मूल रूप से प्रति क्लस्टर की निश्चित संख्या के साथ K- साधन चलाने के लिए दोहरा सकते हैं। फिर भी, पहले एक अच्छा अनुमान लगाना एक अच्छा विचार होगा।


4

इस k- साधन भिन्नता का प्रयास करें:

आरंभ :

  • kयादृच्छिक पर डेटासेट से केंद्र चुनें , या kmeans ++ रणनीति का उपयोग करके भी बेहतर
  • प्रत्येक बिंदु के लिए, अपने निकटतम क्लस्टर केंद्र के लिए दूरी की गणना करें, और इसके लिए एक ढेर का निर्माण करें
  • ढेर से अंक बनाएं, और उन्हें निकटतम क्लस्टर में असाइन करें, जब तक कि क्लस्टर पहले से ही ओवरफ्लो न हो। यदि ऐसा है, तो अगले निकटतम क्लस्टर केंद्र की गणना करें और ढेर में पुनः स्थापित करें

अंत में, आपके पास एक पैरामीटिंग होना चाहिए जो प्रति क्लस्टर + वस्तुओं की -1 -1 संख्या की आपकी आवश्यकताओं को पूरा करता है (सुनिश्चित करें कि अंतिम कुछ समूहों में भी सही संख्या है। पहले mक्लस्टर में ceilऑब्जेक्ट्स होना चाहिए , शेष बिल्कुल floorऑब्जेक्ट्स।)

Iteration चरण :

आवश्यक वस्तुएँ: "स्वैप प्रस्तावों" (प्रत्येक ऑब्जेक्ट जो एक अलग क्लस्टर में रहना पसंद करेंगे) के साथ प्रत्येक क्लस्टर के लिए एक सूची।

स्टेप: अपडेट किए गए क्लस्टर केंद्रों की गणना नियमित के-साधनों के रूप में करें

एम चरण: सभी बिंदुओं के माध्यम से Iterating (या तो सिर्फ एक, या सभी एक बैच में)

ऑब्जेक्ट के लिए निकटतम क्लस्टर केंद्र की गणना करें / सभी क्लस्टर केंद्र जो वर्तमान क्लस्टर की तुलना में करीब हैं। यदि यह एक अलग क्लस्टर है:

  • यदि अन्य क्लस्टर वर्तमान क्लस्टर से छोटा है, तो बस इसे नए क्लस्टर में स्थानांतरित करें
  • यदि अन्य क्लस्टर (या कम दूरी के साथ कोई क्लस्टर) से स्वैप प्रस्ताव है, तो दो तत्व क्लस्टर असाइनमेंट स्वैप करें (यदि एक से अधिक ऑफ़र हैं, तो सबसे बड़ा सुधार वाला एक चुनें)
  • अन्यथा, अन्य क्लस्टर के लिए स्वैप प्रस्ताव का संकेत दें

क्लस्टर आकार अपरिवर्तनीय (+ - छत / फर्श का अंतर) रहता है, एक ऑब्जेक्ट को केवल एक क्लस्टर से दूसरे तक ले जाया जाता है जब तक कि यह अनुमान में सुधार होता है। इसलिए इसे कुछ बिंदुओं जैसे k- साधनों में परिवर्तित करना चाहिए। हालांकि यह थोड़ा धीमा (यानी अधिक पुनरावृत्तियों) हो सकता है।

मुझे नहीं पता कि यह पहले प्रकाशित या कार्यान्वित किया गया है। यह सिर्फ वही है जो मैं कोशिश करूँगा (यदि मैं के-साधनों की कोशिश करूंगा। बहुत बेहतर क्लस्टरिंग एल्गोरिदम हैं।)

शुरू करने के लिए एक अच्छी जगह ईएलकेआई में के- मीन्स कार्यान्वयन के साथ हो सकती है , जो पहले से ही तीन अलग-अलग इनिशियलाइज़ेशन (के-मतलब ++ सहित) का समर्थन करने के लिए लगता है, और लेखकों ने कहा कि वे सभी विभिन्न सामान्य को कवर करने के लिए अलग-अलग पुनरावृत्ति रणनीतियाँ भी चाहते हैं। एक मॉड्यूलर फैशन में वेरिएंट (जैसे लॉयड, मैकक्वीन, ...)।


2
एक समान दृष्टिकोण ELKI में एक ट्यूटोरियल और ट्यूटोरियल "एक्सटेंशन" मॉड्यूल में शामिल है: elki.dbs.ifi.lmu.de/wiki/Tutorial/SameSizeKMeans
Erich Schubert

3

यह एक अनुकूलन समस्या है। हमारे पास एक ओपन सोर्स जावा लाइब्रेरी है जो इस समस्या को हल करती है (क्लस्टरिंग जहां प्रति क्लस्टर मात्रा सेट रेंज के बीच होनी चाहिए)। आपको अपने कुल अंकों की आवश्यकता होगी कि कुछ हजार अधिकतम हों - 5000 या शायद 10000 से अधिक नहीं।

पुस्तकालय यहाँ है:

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

पुस्तकालय स्वयं भौगोलिक / जीआईएस प्रकार की समस्याओं के लिए सेटअप है - इसलिए आप एक्स और वाईएस, अक्षांश और देशांतर, ग्राहकों, दूरी और समय आदि के संदर्भ देखेंगे। आप सिर्फ 'भौगोलिक' तत्वों को नजरअंदाज कर सकते हैं और इसे एक शुद्ध के रूप में उपयोग कर सकते हैं। clusterer।

आप एक न्यूनतम और अधिकतम लक्ष्य मात्रा के साथ शुरू में खाली इनपुट समूहों का एक सेट प्रदान करते हैं। लिपिक आपके इनपुट क्लस्टर्स को अंक प्रदान करेगा, एक हेयुरिस्टिक-आधारित अनुकूलन एल्गोरिथ्म (स्वैप, मूव्स आदि) का उपयोग करके। अनुकूलन में यह पहली बार प्रत्येक क्लस्टर को उसकी न्यूनतम और अधिकतम मात्रा सीमा के भीतर रखने को प्राथमिकता देता है और फिर दूसरी और क्लस्टर के सभी बिंदुओं के बीच की दूरी को न्यूनतम करता है, इसलिए क्लस्टर एक स्थानिक रूप से सामंजस्यपूर्ण होता है।

आप इस इंटरफ़ेस का उपयोग करके पॉइंट के बीच सॉल्वर को एक मीट्रिक फंक्शन (यानी डिस्टेंस फंक्शन) देते हैं:

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

मीट्रिक वास्तव में एक दूरी और 'समय' दोनों को लौटाने के लिए संरचित है, क्योंकि इसकी यात्रा-आधारित भौगोलिक समस्याओं के लिए डिज़ाइन की गई है, लेकिन मनमाने ढंग से क्लस्टरिंग समस्याओं के लिए 'समय' को शून्य मानने और आपके वास्तविक मीट्रिक का उपयोग करने के लिए दूरी निर्धारित करने के लिए जिसका आप उपयोग कर रहे हैं। अंक।

आप अपनी समस्या इस वर्ग में सेट करेंगे:

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

आपके बिंदु 'ग्राहक' होंगे और उनकी मात्रा 1. होगी। ग्राहक वर्ग में सुनिश्चित करें कि आपने costPerUnitTime = 0 और costPerUnitDistance = 1 सेट किया है, यह मानकर कि आप अपने मीट्रिक दूरी को TravelMatrix द्वारा लौटाए गए 'दूरी' क्षेत्र में वापस कर रहे हैं।

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

सॉल्वर चलाने के उदाहरण के लिए यहां देखें:

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


2

मैं सुझाव देता हूं कि हाल ही के पेपर डिस्क्रिमिनटिव क्लस्टरिंग रेगुलराइज्ड इन्फॉर्मेशन मैक्सिमाइजेशन (और उसमें रेफरेंस)। विशेष रूप से, धारा 2 वर्ग संतुलन और क्लस्टर धारणा के बारे में बात करता है।


2

हाल ही में मुझे इसकी आवश्यकता थी एक बहुत बड़े डेटासेट के लिए नहीं। मेरा उत्तर, हालांकि इसमें एक अपेक्षाकृत लंबा समय है, एक स्थानीय इष्टतम में परिवर्तित होने की गारंटी है।

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
इस योगदान के लिए धन्यवाद, @ user2341646 क्या आप कुछ एक्सपेक्टेशन को जोड़ने का मन बना लेंगे जो यह बताता है कि यह समाधान क्या है, यह कैसे काम करता है, और यह एक समाधान क्यों है?
गूँज - मोनिका

ठीक है। मूल रूप से, एल्गोरिथ्म सदस्यता कार्यों के साथ शुरू होता है जो यादृच्छिक होते हैं, लेकिन एक क्लस्टर में जी सदस्यों के करीब होते हैं, और कुल मिलाकर K क्लस्टर होते हैं। हम उस त्रुटि फ़ंक्शन को परिभाषित करते हैं जो एक क्लस्टर में औसतन एक क्लस्टर में डेटा के बीच की दूरी को मापता है। व्यवस्थित रूप से सभी जोड़े डेटा के माध्यम से जा रहे हैं, हम देखते हैं कि क्या कम त्रुटि में उन दो डेटा परिणामों की सदस्यता का आदान-प्रदान होता है। यदि ऐसा होता है, तो हम सबसे कम संभव त्रुटि को अपडेट करते हैं, अन्यथा हम सदस्यता स्विच को पूर्ववत करते हैं। हम ऐसा तब तक करते हैं जब तक कि पूरे एक पास के लिए अधिक चालें नहीं बची हों।
अलेक्जेंडर केन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.