Цикл или нет? - PullRequest
       19

Цикл или нет?

1 голос
/ 20 сентября 2019

Я хотел бы запустить kmean() в наборе данных.Но я хотел бы установить второй аргумент в kmean() на 1:10, то есть я хочу установить K от 1 до 10.

Набор данных, сгенерированный из кода ниже:

 data.frame( grps  = 1:5,
                           gsize = c(1000, 500, 750, 900, 800),
                           m1    = c(  -2,  -1,   0,   1,   2),
                           m2    = c(   0,   3,   1,   2,   4),
                           m3    = c(   1,   4,   2,   5,  -1),
                           m4    = c(   2,  -3,   4,  -1,   1) )

# training set generation
kd          <- centers        %>%
  group_by(grps) %>%
  do(data.frame( v1= rnorm(.$gsize[1], .$m1[1]),
                 v2= rnorm(.$gsize[1], .$m2[1]),
                 v3= rnorm(.$gsize[1], .$m3[1]),
                 v4= rnorm(.$gsize[1], .$m4[1])) ) 
minClusters <- 1
maxClusters <- 10

kclust  <- kd                                   %>%
  crossing(k= minClusters:maxClusters) %>%
  group_by(k)                          %>%
  do(clust= kmeans(select(., v1, v2, v3, v4), 
                   .$k[1], 
                   nstart=5) )

Итак, я не понимаю, получен ли объект kclust из цикла?Я думаю, что это НЕ, потому что второй аргумент в функции kmeans() является фиксированным числом, «1».Может я что то не так понял?Спасибо!

1 Ответ

1 голос
/ 20 сентября 2019

Ваш код работает нормально, и результат соответствует ожидаемому.Проблема заключается в том, что поскольку вы используете случайные числа для генерации данных, а средства находятся рядом, кластеры объединяются в 1 большой кластер, поэтому большинство точек присваивается одному кластеру.Например, вы можете проверить 4-ую запись в переменной kclust $ clust и увидите, что есть 4 центра кластера, но чуть ниже вы увидите, что большинство точек назначено кластеру 1.

library(tidyverse)
centers = data.frame( grps  = 1:5,
        gsize = c(1000, 500, 750, 900, 800),
        m1    = c(  -2,  -1,   0,   1,   2),
        m2    = c(   0,   3,   1,   2,   4),
        m3    = c(   1,   4,   2,   5,  -1),
        m4    = c(   2,  -3,   4,  -1,   1) )

# training set generation
kd = centers %>%
  group_by(grps) %>%
  do(data.frame( v1= rnorm(.$gsize[1], .$m1[1]),
                 v2= rnorm(.$gsize[1], .$m2[1]),
                 v3= rnorm(.$gsize[1], .$m3[1]),
                 v4= rnorm(.$gsize[1], .$m4[1])) ) 

minClusters = 1
maxClusters = 10

kclust  <- kd %>%
  crossing(k = minClusters:maxClusters) %>%
  group_by(k) %>%
  do(clust = kmeans(select(., v1, v2, v3, v4), .$k[1], nstart=5))enter code here

> kclust$clust[4]
[[1]]
K-means clustering with 4 clusters of sizes 982, 771, 1399, 798

Cluster means:
          v1         v2         v3         v4
1 -2.0413678 0.01394798  0.9787409  1.9646186
2 -0.0179719 1.05571578  2.0228387  4.0233226
3  0.2979344 2.34438159  4.6230947 -1.6822656
4  1.9941418 4.03159297 -1.0617125  0.9776119

Clustering vector:
   [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  [69] 1 1 1 1 1 2 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [137] 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1
 [205] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [273] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [341] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [409] 1 1 2 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2
 [477] 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
 [545] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [613] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1
 [681] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [749] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1
 [817] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
 [885] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[953] 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1
 [ reached getOption("max.print") -- omitted 2950 entries ]

Попробуйте увеличить средние значения (* см. ОБНОВЛЕНИЕ ниже), и результаты должны быть лучше.Другая проблема заключается в том, что данные упорядочены по группам, поэтому это также вызывает проблемы в представлении, когда вы просматриваете только первые несколько выборок (они должны быть назначены одному и тому же кластеру).Попробуйте перетасовать точки данных, и результаты будут выглядеть более разумно.

centers = data.frame( grps  = 1:5,
                      gsize = c(1000, 500, 750, 900, 800),
                      m1    = c(-10, -5, 0, 5, 10),
                      m2    = c(-10, -5, 0, 5, 10),
                      m3    = c(-10, -5, 0, 5, 10),
                      m4    = c(-10, -5, 0, 5, 10) )

# training set generation
kd = centers %>%
  group_by(grps) %>%
  do(data.frame( v1= rnorm(.$gsize[1], .$m1[1]),
                 v2= rnorm(.$gsize[1], .$m2[1]),
                 v3= rnorm(.$gsize[1], .$m3[1]),
                 v4= rnorm(.$gsize[1], .$m4[1])) ) %>%
  ungroup()

minClusters = 1
maxClusters = 10

kclust  <- kd %>%
  sample_frac(size=1) %>%
  crossing(k = minClusters:maxClusters) %>%
  group_by(k) %>%
  do(clust = kmeans(select(., v1, v2, v3, v4), .$k[1], nstart=5))


> kclust$clust[5]
[[1]]
K-means clustering with 5 clusters of sizes 900, 1000, 800, 750, 500

Cluster means:
             v1           v2          v3          v4
1   4.947859954  4.990537346  4.96409669  5.02513562
2 -10.014275191 -9.990181395 -9.96969088 -9.96127717
3  10.054780835  9.942738199 10.03617191 10.01820661
4   0.005084275 -0.003034476 -0.03353889 -0.01343343
5  -5.056184108 -5.004413465 -5.00059546 -5.06765925

Clustering vector:
   [1] 2 4 4 2 4 2 4 1 4 4 5 4 1 3 1 3 1 1 2 2 2 2 4 2 4 5 2 4 2 2 4 3 2 1 3 1 2 2 3 4 1 4 1 3 3 5 2 3 3 1 1 4 5 2 4 2 4 2 2 2 2 5 3 2 5 2 1 5
  [69] 2 3 1 1 1 2 2 1 4 2 1 1 2 2 4 4 2 2 5 5 4 2 3 4 5 2 5 3 5 5 4 3 3 3 1 3 5 3 4 1 3 4 1 2 2 3 4 1 1 3 3 1 2 3 5 2 3 1 2 3 5 3 2 2 2 2 1 4
 [137] 4 3 1 4 5 2 3 1 4 1 3 3 1 2 3 3 1 3 1 4 4 2 1 1 5 3 3 2 4 3 5 3 1 3 1 4 4 2 1 3 1 2 3 5 2 1 3 1 3 2 1 2 1 1 2 1 1 3 2 2 5 2 3 3 1 5 3 2
 [205] 5 3 2 2 3 5 2 4 5 4 1 1 2 2 3 1 4 2 4 1 5 3 3 3 5 4 1 2 3 3 5 1 1 5 1 3 3 2 2 5 3 2 2 1 2 4 2 5 4 5 5 2 4 5 3 4 5 3 1 1 2 1 1 2 4 2 4 1
 [273] 2 3 4 5 2 3 1 5 3 3 3 3 5 4 3 4 2 3 2 4 1 4 4 1 1 2 2 3 2 2 3 5 4 5 2 1 4 2 1 3 2 3 4 4 2 2 2 4 3 3 1 4 1 3 5 1 3 3 1 3 3 2 4 1 2 4 2 3
 [341] 2 3 3 2 3 1 5 3 2 5 2 3 4 4 1 2 5 3 1 3 1 1 1 1 3 3 4 1 2 3 1 2 4 1 2 3 5 4 1 4 3 4 3 4 1 4 5 5 5 4 2 4 3 1 2 3 2 3 1 3 2 4 5 4 2 1 1 1
 [409] 4 1 5 2 4 2 1 2 3 4 3 4 5 2 3 5 2 3 1 4 1 1 4 3 3 1 1 1 3 2 2 5 1 3 2 2 2 5 4 4 5 4 1 3 2 2 3 2 2 3 5 1 4 4 4 4 4 2 2 3 1 1 1 2 3 2 3 4
 [477] 2 3 4 2 5 2 4 2 3 1 5 4 3 4 3 3 2 4 3 3 5 2 5 4 4 1 1 2 3 1 5 4 3 1 2 5 2 2 4 2 3 3 2 4 1 3 5 2 1 3 5 5 2 1 3 1 1 5 5 2 1 5 3 2 2 3 3 2
 [545] 2 1 4 4 4 1 2 1 5 5 2 1 4 3 3 2 5 5 2 4 3 2 4 1 3 3 1 3 4 3 2 4 2 5 4 4 3 1 4 5 4 2 1 4 4 2 3 1 2 2 2 4 1 2 2 1 5 5 2 2 4 4 1 5 4 4 4 4
 [613] 2 3 3 1 1 3 3 1 4 4 5 1 2 1 1 4 3 2 5 4 2 5 3 3 3 1 4 1 2 3 5 2 2 4 4 5 2 3 3 1 3 4 3 5 2 2 2 2 4 3 3 2 3 2 4 3 2 2 1 3 3 3 4 3 2 3 3 1
 [681] 3 2 2 5 4 2 4 4 5 2 1 3 1 2 4 1 3 3 4 1 4 4 3 2 2 4 4 3 5 4 1 1 5 2 2 3 5 4 1 1 4 2 5 3 3 1 2 1 2 4 4 2 1 3 2 2 2 3 1 4 1 1 1 4 3 2 3 5
 [749] 1 4 4 3 4 4 4 2 4 2 3 3 1 1 1 4 2 3 1 4 1 4 3 2 3 2 2 4 1 5 1 4 2 4 2 2 1 4 3 4 5 2 3 4 4 2 2 1 5 1 2 1 2 1 1 5 1 5 2 4 1 2 1 2 2 3 1 4
 [817] 5 1 4 2 4 4 4 5 3 2 1 4 1 3 4 2 1 5 2 1 2 5 1 1 1 2 1 4 1 4 5 1 2 5 3 5 4 1 4 1 4 1 3 2 4 3 1 3 5 4 3 1 5 4 3 2 4 3 3 4 4 3 5 4 2 4 2 1
 [885] 1 1 4 2 4 5 1 2 5 4 2 2 3 3 3 3 2 4 1 5 4 2 2 2 4 1 4 3 4 1 2 4 2 1 4 3 5 1 1 5 5 4 1 2 2 2 2 2 3 4 5 1 2 3 2 1 1 1 1 3 2 4 1 1 4 2 5 2
 [953] 3 4 5 2 5 4 1 3 5 2 4 3 4 4 2 4 2 4 1 1 1 1 2 2 4 1 1 3 2 4 3 1 5 1 2 5 4 2 3 2 3 1 2 1 2 1 5 4
 [ reached getOption("max.print") -- omitted 2950 entries ]

ОБНОВЛЕНИЕ:

И я убедился, что реальная проблема - вторая (т.е. ваши данные упорядочены).Вам не нужно менять средства.Вы можете использовать те же средства (что и ваш исходный код), и пока вы тасуете данные, вы должны видеть точки, назначенные нескольким кластерам.

...