नाममात्र / परिपत्र चर के लिए SOM क्लस्टरिंग


11

बस सोच रहा था कि कोई भी नाममात्र इनपुट क्लस्टरिंग से परिचित है। मैं एसओएम को एक समाधान के रूप में देख रहा हूं लेकिन जाहिर तौर पर यह केवल संख्यात्मक विशेषताओं के साथ काम करता है। क्या श्रेणीबद्ध विशेषताओं के लिए कोई एक्सटेंशन हैं? विशेष रूप से मैं संभावित दिनों के रूप में 'डेज ऑफ द वीक' के बारे में सोच रहा था। बेशक, इसे एक संख्यात्मक विशेषता में बदलना संभव है (यानी सोम - सूर्य 1-7 से nos पर) लेकिन फिर सूर्य और सोम (1 और 7) के बीच यूक्लिडियन दूरी सोम से मंगल (1 & 2) की दूरी के समान नहीं होगी। )। किसी भी सुझाव या विचारों की बहुत सराहना की जाएगी।


(+1) एक बहुत ही दिलचस्प सवाल है
स्टीफेन

2
कॉम्प्लेक्स प्लेन में यूनिट सर्कल के तत्वों के रूप में चक्रीय चर को सबसे अच्छा माना जाता है। इस प्रकार, सप्ताह के दिनों को पॉइंट्स , कहना स्वाभाविक होगा ; अर्थात , , , ... । j = 0 , ... , 6exp(2jπi/7)j=0,,6( क्योंकि ( 2 π / 7 ) , पाप ( 2 π / 7 ) ) ( क्योंकि ( 12 π / 7 ) , पाप ( 12 π / 7 ) )(cos(0),sin(0))(cos(2π/7),sin(2π/7))(cos(12π/7),sin(12π/7))
whuber

1
क्या मुझे अपनी खुद की दूरी मैट्रिक्स को फिर से चक्रीय चर के लिए विशिष्ट करना होगा? बस इस प्रकार के क्लस्टरिंग के लिए पहले से मौजूद एल्गोरिदम थे, तो सोच रहे थे। thx
माइकल

@ मिचेल: मेरा मानना ​​है कि आप अपनी दूरी की मीट्रिक को निर्दिष्ट करना चाहेंगे जो आपके आवेदन के लिए उपयुक्त हो, और यह कि आपके डेटा के सभी आयामों पर परिभाषित हो , न कि केवल डॉव में। औपचारिक रूप से, आपके डेटा स्थान में x, y को इंगित करने वाले बिंदुओं को देते हुए, आपको सामान्य गुणों के साथ एक मीट्रिक फ़ंक्शन d (x, y) को परिभाषित करने की आवश्यकता है: d (x, x) = 0, d (x, y) = d (y , x), और d (x, z) <= d (x, y) + d (y, z)। एक बार जब आप ऐसा कर लेते हैं, तो SOM बनाना यांत्रिक होता है। रचनात्मक चुनौती एक तरह से d () को परिभाषित करना है जो आपके आवेदन के लिए उपयुक्त "समानता" की धारणा को पकड़ता है।
आर्थर स्मॉल

जवाबों:


7

पृष्ठभूमि:

घंटे को बदलने का सबसे तार्किक तरीका दो चर में है जो सिंक से आगे और पीछे स्विंग करता है। 24-घंटे की घड़ी के घंटे के हाथ के अंत की स्थिति की कल्पना करें। xस्थिति झूलों के साथ आगे और पीछे सिंक्रनाइज़ेशन से बाहर yस्थिति। एक 24 घंटे की घड़ी के लिए आप के साथ ऐसा कर सकते हैं x=sin(2pi*hour/24), y=cos(2pi*hour/24)

समय के माध्यम से आपको चर या उचित आंदोलन की आवश्यकता होती है। यह इस तथ्य के कारण है कि पाप या व्युत्पन्न के व्युत्पन्न समय में बदल जाते हैं जबकि (x,y)स्थिति सुचारू रूप से बदलती है क्योंकि यह यूनिट सर्कल के चारों ओर घूमती है।

अंत में, विचार करें कि क्या रैखिक समय का पता लगाने के लिए एक तीसरी विशेषता जोड़ना उचित है, जिसे पहले रिकॉर्ड या यूनिक्स समय की मुहर या कुछ इसी तरह की शुरुआत से घंटों (या मिनट या सेकंड) के रूप में निर्मित किया जा सकता है। ये तीन विशेषताएं तब समय की चक्रीय और रैखिक प्रगति दोनों के लिए परदे के पीछे प्रदान करती हैं जैसे आप लोगों के आंदोलन में नींद चक्र जैसे चक्रीय घटना को भी बाहर निकाल सकते हैं और जनसंख्या बनाम समय की तरह रैखिक विकास भी कर सकते हैं।

यदि पूरा किया जा रहा है, तो इसका उदाहरण:

# Enable inline plotting
%matplotlib inline

#Import everything I need...

import numpy as np
import matplotlib as mp

import matplotlib.pyplot as plt
import pandas as pd

# Grab some random times from here: https://www.random.org/clock-times/
# put them into a csv.
from pandas import DataFrame, read_csv
df = read_csv('/Users/angus/Machine_Learning/ipython_notebooks/times.csv',delimiter=':')
df['hourfloat']=df.hour+df.minute/60.0
df['x']=np.sin(2.*np.pi*df.hourfloat/24.)
df['y']=np.cos(2.*np.pi*df.hourfloat/24.)

df

यहाँ छवि विवरण दर्ज करें

def kmeansshow(k,X):

    from sklearn import cluster
    from matplotlib import pyplot
    import numpy as np

    kmeans = cluster.KMeans(n_clusters=k)
    kmeans.fit(X)

    labels = kmeans.labels_
    centroids = kmeans.cluster_centers_
    #print centroids

    for i in range(k):
        # select only data observations with cluster label == i
        ds = X[np.where(labels==i)]
        # plot the data observations
        pyplot.plot(ds[:,0],ds[:,1],'o')
        # plot the centroids
        lines = pyplot.plot(centroids[i,0],centroids[i,1],'kx')
        # make the centroid x's bigger
        pyplot.setp(lines,ms=15.0)
        pyplot.setp(lines,mew=2.0)
    pyplot.show()
    return centroids

चलिए अब इसे आजमाते हैं:

kmeansshow(6,df[['x', 'y']].values)

यहाँ छवि विवरण दर्ज करें

आप बस मुश्किल से देख सकते हैं कि आधी रात के बाद के कुछ समय हैं जिनमें मध्यरात्रि के पहले हरे रंग के क्लस्टर शामिल हैं। अब चलो समूहों की संख्या को कम करते हैं और बताते हैं कि आधी रात से पहले और बाद में एक ही क्लस्टर में अधिक विस्तार से जोड़ा जा सकता है:

kmeansshow(3,df[['x', 'y']].values)

यहाँ छवि विवरण दर्ज करें

यह देखें कि नीले क्लस्टर में मध्यरात्रि से पहले और बाद में एक ही क्लस्टर में एक साथ क्लस्टर किए गए समय कैसे होते हैं ...

आप इसे समय, या सप्ताह के दिन, या सप्ताह के महीने, या महीने के दिन, या मौसम, या कुछ भी कर सकते हैं।


सहायक (+1)। यह एक ऐसा अनुप्रयोग है, जिसमें रेखांकन वास्तव में महत्वपूर्ण नहीं है। मुझे आपके सॉफ़्टवेयर का पता नहीं है, लेकिन मुझे लगता है कि आप डिफ़ॉल्ट से दूर, 1 के लिए पहलू अनुपात सेट कर सकते हैं।
निक कॉक्स

यह सच है @NickCox। या आप बस अपने सिर में रैखिक परिवर्तन कर सकते हैं ;-)
user1745038

2

आमतौर पर नाममात्र चर डमी कोडित होते हैं जब एसओएम में उपयोग किया जाता है (उदाहरण के लिए, सोमवार को 0 के लिए 1 के साथ एक चर सोमवार के लिए नहीं, मंगलवार के लिए दूसरा, आदि)।

आप आसन्न दिनों की संयुक्त श्रेणियां बनाकर अतिरिक्त जानकारी शामिल कर सकते हैं। उदाहरण के लिए: सोमवार और मंगलवार, मंगलवार और बुधवार, आदि, यदि आपका डेटा मानव व्यवहार से संबंधित है, तो अक्सर वीक एंड वीकेंड को श्रेणियों के रूप में उपयोग करना अधिक उपयोगी होता है।


2

नाममात्र चर के लिए, एक तंत्रिका नेटवर्क या इलेक्ट्रिकल इंजीनियरिंग संदर्भ में विशिष्ट एन्कोडिंग को "एक-गर्म" कहा जाता है - सभी 0 के एक वेक्टर, चर के लिए मूल्य के लिए उपयुक्त स्थिति में 1 के साथ। सप्ताह के दिनों के लिए, उदाहरण के लिए, सात दिन हैं, इसलिए आपके एक-गर्म वैक्टर की लंबाई सात होगी। फिर सोमवार को [1 0 0 0 0 0 0], मंगलवार के रूप में [0 1 0 0 0 0 0] आदि के रूप में दर्शाया जाएगा।

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

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

चक्रीय चर बहुत पेचीदा होते हैं। जैसा कि आर्थर ने टिप्पणियों में कहा, आपको एक दूरी मीट्रिक को स्वयं परिभाषित करना होगा जो चर की चक्रीय प्रकृति को शामिल करता है।


1

सप्ताह के दिन (डॉव) मानकर [0, 6] से जाना जाता है, इसके बजाय एक सर्कल पर डेटा प्रोजेक्ट करने के लिए दूसरा विकल्प उपयोग करना है:

dist = min(abs(dow_diff), 7 - abs(dow_diff))

यह समझने के लिए कि, दहेज को एक घड़ी क्यों माना जाए

  6  0
5      1
4      2
    3

6 और 1 के बीच अंतर 6 - 1 = 5 हो सकता है (1 से 6 तक दक्षिणावर्त जा रहा है) या 7 - (6 - 1) = 2. दोनों विकल्पों का न्यूनतम लेना चाल करना चाहिए।

सामान्य तौर पर आप इसका उपयोग कर सकते हैं: min(abs(diff), range - abs(diff))


0

मैंने अपनी टिप्पणी में हाइब्रिड के रूप में (कॉस, सिन) के टपल के रूप में सप्ताह के दिनों (और महीने के महीने) को सफलतापूर्वक एन्कोड किया है। यूक्लिडियन दूरी से अधिक का उपयोग किया।

यह r में कोड का एक उदाहरण है:

circularVariable = function(n, r = 4){
 #Transform a circular variable (e.g. Month so the year or day of the week) into two new variables (tuple).
 #n = upper limit of the sequence. E.g. for days of the week this is 7.
 #r =  number of digits to round generated variables.
 #Return
 #
 coord = function(y){
   angle = ((2*pi)/n) *y
   cs = round(cos(angle),r)
   s = round(sin(angle),r)
   c(cs,s)
 }
 do.call("rbind", lapply((0:(n-1)), coord))
}

यूक्लिडियन 0 और 6 के बीच की दूरी 0 और 1 के बराबर है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.