Kmeans clustering in grouped data

I am currently trying to find cluster centers in grouped data. Using a trial dataset and problem determination, I can create a cluster kmeanswith each group. However, when it comes to each cluster center for these groups, I do not know how to get them. https://rdrr.io/cran/broom/man/kmeans_tidiers.html

Sample data is taken from (with minor changes to the add column gr) Sample data

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

Ok, I'm fine while here. When I want to extract each center of the cluster in each group

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

As we can see, the number is grchanged, and I do not know that these centers belong to which group.

when we take one step forward to see the format 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.

, . , ! !

+4
2

kmeans dplyr, , . , .

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

do -, , - ungroup .

+4

@alistaire , . ,

"Error in numeric(nrowz) : invalid 'length' argument"

centers = map(model, broom::tidy))    # extract data from models

, unnest

"Error: All nested columns must have the same number of elements."

- ?

0

Source: https://habr.com/ru/post/1694501/


All Articles