क्या आर में एक फ़ंक्शन है जो समूहों के केंद्रों को लेता है जो पाया गया था और क्लस्टर को एक नए डेटा सेट में असाइन करता है


14

मेरे पास एक बहुआयामी डेटा सेट के दो भाग हैं, चलो उन्हें कॉल करें trainऔर test। और मैं ट्रेन डेटा सेट के आधार पर एक मॉडल बनाना चाहता हूं और फिर परीक्षण डेटा सेट पर इसे मान्य करता हूं। समूहों की संख्या ज्ञात है।

मैंने आर में क्लस्टरिंग के साधनों को लागू करने की कोशिश की और मुझे एक ऐसी वस्तु मिली जिसमें समूहों के केंद्र शामिल हैं:

kClust <- kmeans(train, centers=N, nstart=M)

क्या आर में एक फ़ंक्शन है जो समूहों के केंद्रों को लेता है जो मेरे परीक्षण डेटा सेट में क्लस्टर पाए गए और असाइन किए गए हैं?

अन्य तरीके / एल्गोरिदम क्या हैं जो मैं कोशिश कर सकता हूं?


साइट पर आपका स्वागत है, @ user2598356 क्या आप इसे अधिक सामान्य (गैर-आर विशिष्ट) तरीके से फ्रेम कर सकते हैं? यदि आप केवल एक आर फ़ंक्शन के लिए पूछ रहे हैं, तो यह प्रश्न सीवी के लिए ऑफ-टॉपिक होगा (हमारे सहायता पृष्ठ देखें )। इसके अलावा, यह स्टैक ओवरफ्लो पर भी ऑफ-टॉपिक होगा , क्योंकि इसमें एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण नहीं है । यदि आप इसे यहाँ या SO पर विषय बनाने के लिए संपादित कर सकते हैं, तो कृपया ऐसा करें। अन्यथा, यह क्यू बंद हो सकता है।
गूँग - मोनिका

यह प्रश्न ऑफ़-टॉपिक प्रतीत होता है क्योंकि यह R फ़ंक्शन खोजने के बारे में है।
गूँग - मोनिका

1
लेकिन आखिरी सवाल के बारे में क्या है: "अन्य तरीके / एल्गोरिदम क्या हैं जो मैं कोशिश कर सकता हूं?"। वास्तव में जवाब है कि मुझे उन तरीकों के कार्यान्वयन की चिंता है जो सीवी का विषय है, या क्या मैं गलत हूं?
user2598356

1
@gung आप सही हो सकते हैं, जिस स्थिति में मैं user259 को आमंत्रित करता हूं ... माइग्रेशन के लिए इस प्रश्न को चिह्नित करने के लिए। हालांकि, अन्य तरीकों और एल्गोरिदम के बारे में सवाल का आखिरी हिस्सा हमारे समुदाय को उपयोगी मदद और सलाह देने के लिए एक अच्छी स्थिति में हो सकता है।
whuber

धन्यवाद! फ़ंक्शन अच्छी तरह से काम करता है, लेकिन अगर आपके पास 50k से अधिक पंक्तियां हैं, तो बहुत अधिक समय लगता है। इसे हल्का बनाने के लिए कोई विचार?

जवाबों:


11

आप निम्नलिखित फ़ंक्शन के साथ सेट किए गए नए डेटा के लिए क्लस्टर असाइनमेंट की गणना कर सकते हैं:

clusters <- function(x, centers) {
  # compute squared euclidean distance from each sample to each cluster center
  tmp <- sapply(seq_len(nrow(x)),
                function(i) apply(centers, 1,
                                  function(v) sum((x[i, ]-v)^2)))
  max.col(-t(tmp))  # find index of min distance
}

# create a simple data set with two clusters
set.seed(1)
x <- rbind(matrix(rnorm(100, sd = 0.3), ncol = 2),
           matrix(rnorm(100, mean = 1, sd = 0.3), ncol = 2))
colnames(x) <- c("x", "y")
x_new <- rbind(matrix(rnorm(10, sd = 0.3), ncol = 2),
               matrix(rnorm(10, mean = 1, sd = 0.3), ncol = 2))
colnames(x_new) <- c("x", "y")

cl <- kmeans(x, centers=2)

all.equal(cl[["cluster"]], clusters(x, cl[["centers"]]))
# [1] TRUE
clusters(x_new, cl[["centers"]])
# [1] 2 2 2 2 2 1 1 1 1 1

plot(x, col=cl$cluster, pch=3)
points(x_new, col= clusters(x_new, cl[["centers"]]), pch=19)
points(cl[["centers"]], pch=4, cex=2, col="blue")

क्लस्टर असाइनमेंट

या आप flexclust पैकेज का उपयोग कर सकते हैं , जिसमें predictk- साधनों के लिए एक कार्यान्वित विधि है:

library("flexclust")
data("Nclus")

set.seed(1)
dat <- as.data.frame(Nclus)
ind <- sample(nrow(dat), 50)

dat[["train"]] <- TRUE
dat[["train"]][ind] <- FALSE

cl1 = kcca(dat[dat[["train"]]==TRUE, 1:2], k=4, kccaFamily("kmeans"))
cl1    
#
# call:
# kcca(x = dat[dat[["train"]] == TRUE, 1:2], k = 4)
#
# cluster sizes:
#
#  1   2   3   4 
#130 181  98  91 

pred_train <- predict(cl1)
pred_test <- predict(cl1, newdata=dat[dat[["train"]]==FALSE, 1:2])

image(cl1)
points(dat[dat[["train"]]==TRUE, 1:2], col=pred_train, pch=19, cex=0.3)
points(dat[dat[["train"]]==FALSE, 1:2], col=pred_test, pch=22, bg="orange")

flexclust साजिश

क्लस्टर फ़ंक्शंस से stats::kmeansया cluster::pamकक्षा की वस्तुओं से kccaऔर इसके विपरीत परिणामों को परिवर्तित करने के लिए रूपांतरण विधियाँ भी हैं:

as.kcca(cl, data=x)
# kcca object of family ‘kmeans’ 
#
# call:
# as.kcca(object = cl, data = x)
#
# cluster sizes:
#
#  1  2 
#  50 50 

आपका बहुत बहुत धन्यवाद! बस एक सवाल: कैसेका तरीका शुरू की संख्या से संबंधित है (क्या यह शुरुआती बिंदुओं के संबंध में विश्लेषण का अनुकूलन करता है)?
user2598356

शुरुआत की संख्या के साथ आपका क्या मतलब है? stepFlexclustसमारोह समूहों की अलग नंबरों के लिए बार-बार एल्गोरिदम clustering चलाता है और प्रत्येक के लिए क्लस्टर दूरी समाधान के भीतर कम से कम देता है।
rcs

1

चरण 1: वेक्टर के बीच एक फ़ंक्शन कंप्यूटिंग दूरी और मैट्रिक्स की प्रत्येक पंक्ति

calc_vec2mat_dist = function(x, ref_mat) {
    # compute row-wise vec2vec distance 
    apply(ref_mat, 1, function(r) sum((r - x)^2))
}

चरण 2: एक फ़ंक्शन जो इनपुट_मेट्रिक्स की प्रत्येक पंक्ति में vec2mat कंप्यूटर को लागू करता है

calc_mat2mat_dist = function(input_mat, ref_mat) {

    dist_mat = apply(input_mat, 1, function(r) calc_vec2mat_dist(r, ref_mat))

    # transpose to have each row for each input datapoint
    # each column for each centroids
    cbind(t(dist_mat), max.col(-t(dist_mat)))
}

चरण 3। mat2mat फ़ंक्शन लागू करें

calc_mat2mat_dist(my_input_mat, kmeans_model$centers)

चरण 4। वैकल्पिक रूप से plyr :: ddply और doMC का उपयोग बड़े डेटासेट के लिए mat2mat को समानांतर करने के लिए करें

library(doMC)
library(plyr)

pred_cluster_para = function(input_df, center_mat, cl_feat, id_cols, use_ncore = 8) {
    # assign cluster lables for each individual (row) in the input_df 
    # input: input_df   - dataframe with all features used in clustering, plus some id/indicator columns
    # input: center_mat - matrix of centroid, K rows by M features
    # input: cl_feat    - list of features (col names)
    # input: id_cols    - list of index cols (e.g. id) to include in output 
    # output: output_df - dataframe with same number of rows as input, 
    #         K columns of distances to each clusters
    #         1 column of cluster_labels
    #         x column of indices in idx_cols

    n_cluster = nrow(center_mat)
    n_feat = ncol(center_mat)
    n_input = nrow(input_df)

    if(!(typeof(center_mat) %in% c('double','interger') & is.matrix(center_mat))){
        stop('The argument "center_mat" must be numeric matrix')
    } else if(length(cl_feat) != n_feat) {
        stop(sprintf('cl_feat size: %d , center_mat n_col: %d, they have to match!',length(cl_feat), n_feat))
    } else {
        # register MultiCore backend through doMC and foreach package
        doMC::registerDoMC(cores = use_ncore)

        # create job_key for mapping/spliting the input data
        input_df[,'job_idx'] = sample(1:use_ncore, n_input, replace = TRUE)

        # create row_key for tracing the original row order which will be shuffled by mapreduce
        input_df[,'row_idx'] = seq(n_input)

        # use ddply (df input, df output) to split-process-combine
        output_df = ddply(
            input_df[, c('job_idx','row_idx',cl_feat,id_cols)], # input big data 
            'job_idx',                       # map/split by job_idx
            function(chunk) {                # work on each chunk
                dist = data.frame(calc_mat2mat_dist(chunk[,cl_feat], center_mat))
                names(dist) = c(paste0('dist2c_', seq(n_cluster)), 'pred_cluster')
                dist[,id_cols] = chunk[,id_cols]
                dist[,'row_idx'] = chunk[,'row_idx']
                dist                        # product of mapper
                        }, .parallel = TRUE) # end of ddply
        # sort back to original row order

        output_df = output_df[order(output_df$row_idx),]
        output_df[c('job_idx')] = NULL
        return(output_df)
    }

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