Ваш код работает нормально, и результат соответствует ожидаемому.Проблема заключается в том, что поскольку вы используете случайные числа для генерации данных, а средства находятся рядом, кластеры объединяются в 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 ]
ОБНОВЛЕНИЕ:
И я убедился, что реальная проблема - вторая (т.е. ваши данные упорядочены).Вам не нужно менять средства.Вы можете использовать те же средства (что и ваш исходный код), и пока вы тасуете данные, вы должны видеть точки, назначенные нескольким кластерам.