आप सही कह रहे हैं कि k-mean क्लस्टरिंग को मिश्रित प्रकारों के डेटा के साथ नहीं किया जाना चाहिए। चूँकि k- साधन अनिवार्य रूप से एक विभाजन को खोजने के लिए एक सरल खोज एल्गोरिथ्म है जो क्लस्टर किए गए अवलोकनों और क्लस्टर सेंटीरोइड के बीच के क्लस्टर-वर्ग वाले यूक्लिडियन दूरी को कम करता है, इसका उपयोग केवल उन डेटा के साथ किया जाना चाहिए जहाँ स्क्वेर्ड यूक्लिडियन दूरी सार्थक होगी।
जब आपके डेटा में मिश्रित प्रकार के चर होते हैं, तो आपको गोवर की दूरी का उपयोग करने की आवश्यकता होती है। CV उपयोगकर्ता @ttnphns में यहां गोवर की दूरी का शानदार अवलोकन है । संक्षेप में, आप बदले में प्रत्येक चर के लिए अपनी पंक्तियों के लिए एक दूरी मैट्रिक्स की गणना करते हैं, एक प्रकार की दूरी का उपयोग करते हैं जो उस प्रकार के चर के लिए उपयुक्त है (जैसे, निरंतर डेटा के लिए यूक्लिडियन, आदि); पंक्ति से की अंतिम दूरी प्रत्येक चर के लिए दूरी का (संभवतः भारित) औसत है। एक बात का ध्यान रखें कि गोवर की दूरी वास्तव में मीट्रिक नहीं है । बहरहाल, मिश्रित आंकड़ों के साथ, गोवर की दूरी काफी हद तक शहर का एकमात्र खेल है। मैंमैं'
इस बिंदु पर, आप किसी भी क्लस्टरिंग विधि का उपयोग कर सकते हैं जो मूल डेटा मैट्रिक्स की आवश्यकता के बजाय दूरी मैट्रिक्स पर काम कर सकती है। (ध्यान दें कि k- साधन को बाद की आवश्यकता है।) सबसे लोकप्रिय विकल्प मेडोइड्स के आसपास विभाजन कर रहे हैं (PAM, जो अनिवार्य रूप से k- साधनों के समान है, लेकिन केन्द्रक के बजाय सबसे केंद्रीय अवलोकन का उपयोग करता है), विभिन्न पदानुक्रमित क्लस्टरिंग दृष्टिकोण (जैसे , मध्ययुगीन, एकल-लिंकेज, और पूर्ण-लिंकेज; पदानुक्रमिक क्लस्टरिंग के साथ आपको यह तय करने की आवश्यकता होगी कि अंतिम क्लस्टर असाइनमेंट प्राप्त करने के लिए ' पेड़ कहाँ काटें '), और डीबीएससीएएन जो बहुत अधिक लचीली क्लस्टर आकृतियों की अनुमति देता है।
यहाँ एक सरल R
डेमो है (nb, वास्तव में 3 क्लस्टर हैं, लेकिन डेटा ज्यादातर ऐसे दिखते हैं जैसे 2 क्लस्टर उपयुक्त हैं):
library(cluster) # we'll use these packages
library(fpc)
# here we're generating 45 data in 3 clusters:
set.seed(3296) # this makes the example exactly reproducible
n = 15
cont = c(rnorm(n, mean=0, sd=1),
rnorm(n, mean=1, sd=1),
rnorm(n, mean=2, sd=1) )
bin = c(rbinom(n, size=1, prob=.2),
rbinom(n, size=1, prob=.5),
rbinom(n, size=1, prob=.8) )
ord = c(rbinom(n, size=5, prob=.2),
rbinom(n, size=5, prob=.5),
rbinom(n, size=5, prob=.8) )
data = data.frame(cont=cont, bin=bin, ord=factor(ord, ordered=TRUE))
# this returns the distance matrix with Gower's distance:
g.dist = daisy(data, metric="gower", type=list(symm=2))
हम PAM के साथ समूहों की विभिन्न संख्याओं की खोज करके शुरू कर सकते हैं:
# we can start by searching over different numbers of clusters with PAM:
pc = pamk(g.dist, krange=1:5, criterion="asw")
pc[2:3]
# $nc
# [1] 2 # 2 clusters maximize the average silhouette width
#
# $crit
# [1] 0.0000000 0.6227580 0.5593053 0.5011497 0.4294626
pc = pc$pamobject; pc # this is the optimal PAM clustering
# Medoids:
# ID
# [1,] "29" "29"
# [2,] "33" "33"
# Clustering vector:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 2 1 2 2
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 1 2 1 2 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2
# Objective function:
# build swap
# 0.1500934 0.1461762
#
# Available components:
# [1] "medoids" "id.med" "clustering" "objective" "isolation"
# [6] "clusinfo" "silinfo" "diss" "call"
उन परिणामों की तुलना पदानुक्रमित क्लस्टरिंग के परिणामों से की जा सकती है:
hc.m = hclust(g.dist, method="median")
hc.s = hclust(g.dist, method="single")
hc.c = hclust(g.dist, method="complete")
windows(height=3.5, width=9)
layout(matrix(1:3, nrow=1))
plot(hc.m)
plot(hc.s)
plot(hc.c)
मंझला विधि 2 (संभवतः 3) समूहों का सुझाव देती है, एकल केवल 2 का समर्थन करता है, लेकिन पूर्ण विधि मेरी आंख को 2, 3 या 4 का सुझाव दे सकती है।
अंत में, हम DBSCAN की कोशिश कर सकते हैं। इसके लिए दो मापदंडों को निर्दिष्ट करने की आवश्यकता होती है: eps, 'रीचैबिलिटी डिस्टेंस' (कैसे दो अवलोकनों को एक साथ जोड़ा जाना है) और minPts (अंकों की न्यूनतम संख्या जो आपको कॉल करने के लिए तैयार होने से पहले एक-दूसरे से कनेक्ट होने की आवश्यकता होती है) 'क्लस्टर')। मिन्ट्स के लिए अंगूठे का एक नियम आयामों की संख्या (हमारे मामले में 3 + 1 = 4) की तुलना में एक से अधिक का उपयोग करना है, लेकिन एक संख्या होने के लिए अनुशंसित नहीं है। के लिए डिफ़ॉल्ट मान dbscan
5 है; हम उसी के साथ रहेंगे। रीचैबिलिटी दूरी के बारे में सोचने का एक तरीका यह देखना है कि किसी भी दिए गए मूल्य से कितने प्रतिशत दूरियां कम हैं। हम दूरियों के वितरण की जाँच करके ऐसा कर सकते हैं:
windows()
layout(matrix(1:2, nrow=1))
plot(density(na.omit(g.dist[upper.tri(g.dist)])), main="kernel density")
plot(ecdf(g.dist[upper.tri(g.dist)]), main="ECDF")
दूरियां स्वयं 'निकट' और 'आगे दूर' के दृष्टिहीन समूहों में क्लस्टर होने लगती हैं। .3 का मान दूरियों के दो समूहों के बीच सबसे अधिक स्पष्ट रूप से अंतर करता है। ईपीएस के विभिन्न विकल्पों के लिए आउटपुट की संवेदनशीलता का पता लगाने के लिए, हम .2 और .4 के साथ भी कोशिश कर सकते हैं:
dbc3 = dbscan(g.dist, eps=.3, MinPts=5, method="dist"); dbc3
# dbscan Pts=45 MinPts=5 eps=0.3
# 1 2
# seed 22 23
# total 22 23
dbc2 = dbscan(g.dist, eps=.2, MinPts=5, method="dist"); dbc2
# dbscan Pts=45 MinPts=5 eps=0.2
# 1 2
# border 2 1
# seed 20 22
# total 22 23
dbc4 = dbscan(g.dist, eps=.4, MinPts=5, method="dist"); dbc4
# dbscan Pts=45 MinPts=5 eps=0.4
# 1
# seed 45
# total 45
उपयोग करने से eps=.3
एक बहुत ही साफ समाधान मिलता है, जो (गुणात्मक रूप से कम से कम) जो हम ऊपर अन्य तरीकों से देखते हैं उससे सहमत हैं।
चूँकि कोई सार्थक क्लस्टर 1-नेस नहीं है , इसलिए हमें यह ध्यान रखने की कोशिश करनी चाहिए कि कौन सी टिप्पणियों को क्लस्टर क्लस्टरिंग से 'क्लस्टर 1' कहा जाता है। इसके बजाय, हम तालिकाओं का निर्माण कर सकते हैं और यदि एक फिट में 'क्लस्टर 1' नामक अधिकांश टिप्पणियों को दूसरे में 'क्लस्टर 2' कहा जाता है, तो हम देखेंगे कि परिणाम अभी भी समान हैं। हमारे मामले में, अलग-अलग क्लस्टरिंग ज्यादातर बहुत स्थिर हैं और हर बार एक ही क्लस्टर में समान टिप्पणियों को डालते हैं; केवल पूर्ण लिंकेज श्रेणीबद्ध क्लस्टरिंग भिन्न है:
# comparing the clusterings
table(cutree(hc.m, k=2), cutree(hc.s, k=2))
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), pc$clustering)
# 1 2
# 1 22 0
# 2 0 23
table(pc$clustering, dbc3$cluster)
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), cutree(hc.c, k=2))
# 1 2
# 1 14 8
# 2 7 16
बेशक, इसमें कोई गारंटी नहीं है कि कोई भी क्लस्टर विश्लेषण आपके डेटा में वास्तविक अव्यक्त समूहों को पुनर्प्राप्त करेगा। सही क्लस्टर लेबलों की अनुपस्थिति (जो कि, एक लॉजिस्टिक रिग्रेशन की स्थिति में उपलब्ध होगी) का अर्थ है कि भारी मात्रा में जानकारी अनुपलब्ध है। बहुत बड़े डेटासेट के साथ भी, क्लस्टर पूरी तरह से ठीक होने के लिए पर्याप्त रूप से अच्छी तरह से अलग नहीं हो सकते हैं। हमारे मामले में, चूंकि हम सही क्लस्टर सदस्यता जानते हैं, इसलिए हम इसकी तुलना आउटपुट से कर सकते हैं कि यह कितना अच्छा है। जैसा कि मैंने ऊपर उल्लेख किया है, वास्तव में 3 अव्यक्त क्लस्टर हैं, लेकिन डेटा इसके बजाय 2 समूहों की उपस्थिति देते हैं:
pc$clustering[1:15] # these were actually cluster 1 in the data generating process
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1
pc$clustering[16:30] # these were actually cluster 2 in the data generating process
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# 2 2 1 1 1 2 1 2 1 2 2 1 2 1 2
pc$clustering[31:45] # these were actually cluster 3 in the data generating process
# 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2