kmeans聚类分组数据

时间:2018-03-06 01:34:52

标签: r machine-learning dplyr k-means

目前,我尝试在分组数据中找到群集的中心。通过使用示例数据集和问题定义,我可以创建包含每个组的kmeans集群。但是,当谈到给定组的每个群集中心时,我不知道如何获取它们。 https://rdrr.io/cran/broom/man/kmeans_tidiers.html

示例数据为from(添加gr列几乎没有修改) 样本数据

library(dplyr)
library(broom)
library(ggplot2)

set.seed(2015)

sizes_1 <- c(20, 100, 500)
sizes_2 <- c(10, 50, 100)

centers_1 <- data_frame(x = c(1, 4, 6), 
                        y = c(5, 0, 6), 
                        n = sizes_1,
                        cluster = factor(1:3))
centers_2 <- data_frame(x = c(1, 4, 6), 
                        y = c(5, 0, 6), 
                        n = sizes_2,
                        cluster = factor(1:3))

points1 <- centers_1 %>% 
    group_by(cluster) %>%
    do(data_frame(x = rnorm(.$n, .$x), 
                  y = rnorm(.$n, .$y), 
                  gr="1"))

points2 <- centers_2 %>% 
    group_by(cluster) %>%
    do(data_frame(x = rnorm(.$n, .$x), 
                  y = rnorm(.$n, .$y), 
                  gr="2"))

combined_points <- rbind(points1, points2)

> combined_points
# A tibble: 780 x 4
# Groups:   cluster [3]
   cluster           x        y    gr
    <fctr>       <dbl>    <dbl> <chr>
 1       1  3.66473833 4.285771     1
 2       1  0.51540619 5.565826     1
 3       1  0.11556319 5.592178     1
 4       1  1.60513712 5.360013     1
 5       1  2.18001557 4.955883     1
 6       1  1.53998887 4.530316     1
 7       1 -1.44165622 4.561338     1
 8       1  2.35076259 5.408538     1
 9       1 -0.03060973 4.980363     1
10       1  2.22165205 5.125556     1
# ... with 770 more rows

ggplot(combined_points, aes(x, y)) +
    facet_wrap(~gr) +
    geom_point(aes(color = cluster))

enter image description here

好的,直到这里我的一切都很棒。当我想在每个组中提取每个集群中心时

clust <- combined_points %>% 
    group_by(gr) %>% 
    dplyr::select(x, y) %>% 
    kmeans(3)

> clust
K-means clustering with 3 clusters of sizes 594, 150, 36

Cluster means:
        gr        x         y
1 1.166667 6.080832 6.0074885
2 1.333333 4.055645 0.0654158
3 1.305556 1.507862 5.2417670

我们可以看到gr号码已更改,我不知道这些中心属于哪个群组。

我们向前迈出一步,看tidy

clust格式
> tidy(clust)
        x1       x2        x3 size  withinss cluster
1 1.166667 6.080832 6.0074885  594 1095.3047       1
2 1.333333 4.055645 0.0654158  150  312.4182       2
3 1.305556 1.507862 5.2417670   36  115.2484       3

我仍然看不到gr 2中心信息。

我希望问题解释清楚。如果您有任何遗漏,请告诉我!提前谢谢!

1 个答案:

答案 0 :(得分:4)

el.addEventListener( 'drop', function(e) { // Stops some browsers from redirecting. if (e.stopPropagation){ e.stopPropagation(); } this.classList.remove('over'); var binId = this.id; var item = document.getElementById(e.dataTransfer.getData('Text')); this.appendChild(item); // call the passed drop function scope.$apply(function(scope) { var fn = scope.drop(); if ('undefined' !== typeof fn) { fn(item.id, binId); } }); return false; }, false 并不了解dplyr分组,所以它只是找到三个整体中心而不是每个群组。此时优选的习惯用法是输入数据的列表列,例如

kmeans

请注意,library(tidyverse) points_and_models <- combined_points %>% ungroup() %>% select(-cluster) %>% # cleanup, remove cluster name so data will collapse nest(x, y) %>% # collapse input data into list column mutate(model = map(data, kmeans, 3), # iterate model over list column of input data centers = map(model, broom::tidy)) # extract data from models points_and_models #> # A tibble: 2 x 4 #> gr data model centers #> <chr> <list> <list> <list> #> 1 1 <tibble [620 × 2]> <S3: kmeans> <data.frame [3 × 5]> #> 2 2 <tibble [160 × 2]> <S3: kmeans> <data.frame [3 × 5]> points_and_models %>% unnest(centers) #> # A tibble: 6 x 6 #> gr x1 x2 size withinss cluster #> <chr> <dbl> <dbl> <int> <dbl> <fct> #> 1 1 4.29 5.71 158 441. 1 #> 2 1 3.79 0.121 102 213. 2 #> 3 1 6.39 6.06 360 534. 3 #> 4 2 5.94 5.88 100 194. 1 #> 5 2 4.01 -0.127 50 97.4 2 #> 6 2 1.07 4.57 10 15.7 3 列来自模型结果,而不是输入数据。

你也可以用cluster做同样的事情,例如

do

但是combined_points %>% group_by(gr) %>% do(model = kmeans(.[c('x', 'y')], 3)) %>% ungroup() %>% group_by(gr) %>% do(map_df(.$model, broom::tidy)) %>% ungroup() 和rowwise的分组在这一点上有点软弃用,代码变得有点笨拙,正如你可以看到显式do的需要那么多。