Có một chức năng nào trong R lấy trung tâm của các cụm được tìm thấy và gán các cụm cho một tập dữ liệu mới không


14

Tôi có hai phần của tập dữ liệu đa chiều, hãy gọi cho họ traintest. Và tôi muốn xây dựng một mô hình dựa trên tập dữ liệu tàu và sau đó xác nhận nó trên tập dữ liệu thử nghiệm. Số lượng các cụm được biết đến.

Tôi đã thử áp dụng phân cụm k-nghĩa trong R và tôi nhận được một đối tượng chứa các trung tâm của cụm:

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

Có chức năng nào trong R lấy trung tâm của các cụm được tìm thấy và gán các cụm cho tập dữ liệu thử nghiệm của tôi không?

Các phương pháp / thuật toán khác mà tôi có thể thử là gì?


Chào mừng đến với trang web, @ user2598356. Bạn có thể đóng khung này theo cách tổng quát hơn (không phải R cụ thể) không? Nếu bạn chỉ yêu cầu một chức năng R, câu hỏi này sẽ lạc đề về CV (xem trang trợ giúp của chúng tôi ). Hơn nữa, nó cũng sẽ lạc đề trên Stack Overflow , vì nó không có ví dụ tái tạo . Nếu bạn có thể chỉnh sửa nó để làm cho nó theo chủ đề ở đây hoặc trên SO, vui lòng làm như vậy. Nếu không, Q này có thể bị đóng.
gung - Phục hồi Monica

Câu hỏi này dường như lạc đề vì đó là về việc tìm kiếm hàm R.
gung - Phục hồi Monica

1
Nhưng những gì về câu hỏi cuối cùng: "Các phương pháp / thuật toán khác mà tôi có thể thử là gì?". Trên thực tế, câu trả lời mà tôi quan tâm khi thực hiện các phương pháp là một chủ đề của CV, hoặc tôi sai?
dùng2598356

1
@gung Bạn có thể đúng, trong trường hợp đó tôi mời người dùng259 ... để gắn cờ câu hỏi này để di chuyển. Tuy nhiên, phần cuối của câu hỏi về các phương pháp và thuật toán khác cho thấy cộng đồng của chúng tôi có thể ở một vị trí tốt để cung cấp trợ giúp và lời khuyên hữu ích.
whuber

Cảm ơn! Hàm hoạt động tốt, nhưng mất quá nhiều thời gian nếu bạn có hơn 50k hàng. Bất kỳ ý tưởng để làm cho nó nhẹ hơn?

Câu trả lời:


11

Bạn có thể tính toán các phép gán cụm cho một tập dữ liệu mới với chức năng sau:

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")

phân công cụm

hoặc bạn có thể sử dụng gói flexclust , có predictphương thức được triển khai cho k- mean :

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")

cốt truyện flexclust

Ngoài ra còn có các phương thức chuyển đổi để chuyển đổi kết quả từ các hàm cụm như stats::kmeanshoặc cluster::pamsang các đối tượng của lớp kccavà ngược lại:

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

Cảm ơn rât nhiều! Chỉ cần một câu hỏi: làm thế nào các phương pháp kcca xử lý số lần bắt đầu (nó có tối ưu hóa phân tích liên quan đến điểm bắt đầu không)?
dùng2598356

Bạn có ý nghĩa gì với số lượng bắt đầu? Các stepFlexclustchức năng chạy phân nhóm các thuật toán lặp đi lặp lại cho các số khác nhau của các cụm và trả mức tối thiểu trong giải pháp khoảng cách cụm cho mỗi.
rcs

1

bước 1: khoảng cách tính toán hàm giữa một vectơ và mỗi hàng của ma trận

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

Bước 2: một chức năng áp dụng máy tính vec2mat cho mỗi hàng của input_matrix

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)))
}

bước 3. áp dụng hàm mat2mat

calc_mat2mat_dist(my_input_mat, kmeans_model$centers)

bước 4. Tùy chọn sử dụng plyr :: ddply và doMC để song song hóa mat2mat cho tập dữ liệu lớn

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)
    }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.