R 中的成对 K 均值
Pairwise K-Means in R
我有一个dataset
,我想申请K-means clustering
来创建群组。但是,我只想考虑成对的变量。
dataset
有一个class变量,所以我希望这个class变量不参与聚类,用它来评估算法性能。
我想自动完成,因此必须尝试两个变量的所有可能组合,并且只返回最好的组合。
我如何在 R 中执行此操作?
您可以使用 Iris 数据集作为示例。
欢迎来到 SO!这样的事情怎么样,拥有所有模型(以及关于它们的一切,只有最好的组合,看答案的底部):
# first the pairwise combination of column, without the labels
comb <- combn(names(iris[,-5]),2,simplify=FALSE)
# an empty list to populate with kmeans
listed <- list()
然后是一个 for 循环,将 kmeans 应用于每个子集,并将输出放入列表中:
for (i in c(1:length(comb))){
names_ <- comb[[i]]
df <-iris[ , which(names(iris) %in% names_)]
listed[[i]] <- kmeans(df,3)
}
例如,这里
listed[[2]]
K-means clustering with 3 clusters of sizes 51, 58, 41
Cluster means:
Sepal.Length Petal.Length
1 5.007843 1.492157
2 5.874138 4.393103
3 6.839024 5.678049
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 1 1 1 1 1 1 1 1 1 1 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2
[66] 2 2 2 2 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 3 2 3 3 3 3 2 3 3 3 3 3 3 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 3 3
[131] 3 3 3 3 3 3 3 3 2 3 3 3 2 3 3 3 2 3 3 2
Within cluster sum of squares by cluster:
[1] 9.893725 23.508448 20.407805
(between_SS / total_SS = 90.5 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
如果你只想要 "best" 模型,在这种情况下是具有最佳 purity 索引的模型(注意:我从未使用过它,所以请检查公式)比率,在这里另一个循环:
# combinations
comb <- combn(names(iris[,-5]),2,simplify=FALSE)
# another list
listed_1 <- list()
library(dplyr) # external package to make it simpler
for (i in c(1:length(comb))){
names_ <- comb[[i]]
df <-iris[ , which(names(iris) %in% names_)]
km <- kmeans(df,3)
df <- data.frame(cl = km$cluster, spec =iris$Species, cnt = 1)
df <- aggregate(df$cnt,list(cl = df$cl,spec= df$spec),sum )
df <- df %>% group_by(spec) %>% filter(x == max(x))
listed_1[[i]] <- round(sum(df$x)/nrow(iris),2)*100
}
现在你得到了一个结果列表:以下命令将把 (cbind
) 放在一个 data.frame 列表中,结果 (do.call(rbind, listed_1)
) 和组合(do.call(rbind, comb)
):
res <- cbind(do.call(rbind, listed_1),do.call(rbind, comb))
res[which.max(res[,1]),]
[1] "95" "Petal.Length" "Petal.Width"
我有一个dataset
,我想申请K-means clustering
来创建群组。但是,我只想考虑成对的变量。
dataset
有一个class变量,所以我希望这个class变量不参与聚类,用它来评估算法性能。
我想自动完成,因此必须尝试两个变量的所有可能组合,并且只返回最好的组合。
我如何在 R 中执行此操作? 您可以使用 Iris 数据集作为示例。
欢迎来到 SO!这样的事情怎么样,拥有所有模型(以及关于它们的一切,只有最好的组合,看答案的底部):
# first the pairwise combination of column, without the labels
comb <- combn(names(iris[,-5]),2,simplify=FALSE)
# an empty list to populate with kmeans
listed <- list()
然后是一个 for 循环,将 kmeans 应用于每个子集,并将输出放入列表中:
for (i in c(1:length(comb))){
names_ <- comb[[i]]
df <-iris[ , which(names(iris) %in% names_)]
listed[[i]] <- kmeans(df,3)
}
例如,这里
listed[[2]]
K-means clustering with 3 clusters of sizes 51, 58, 41
Cluster means:
Sepal.Length Petal.Length
1 5.007843 1.492157
2 5.874138 4.393103
3 6.839024 5.678049
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 1 1 1 1 1 1 1 1 1 1 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2
[66] 2 2 2 2 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 3 2 3 3 3 3 2 3 3 3 3 3 3 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 3 3
[131] 3 3 3 3 3 3 3 3 2 3 3 3 2 3 3 3 2 3 3 2
Within cluster sum of squares by cluster:
[1] 9.893725 23.508448 20.407805
(between_SS / total_SS = 90.5 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
如果你只想要 "best" 模型,在这种情况下是具有最佳 purity 索引的模型(注意:我从未使用过它,所以请检查公式)比率,在这里另一个循环:
# combinations
comb <- combn(names(iris[,-5]),2,simplify=FALSE)
# another list
listed_1 <- list()
library(dplyr) # external package to make it simpler
for (i in c(1:length(comb))){
names_ <- comb[[i]]
df <-iris[ , which(names(iris) %in% names_)]
km <- kmeans(df,3)
df <- data.frame(cl = km$cluster, spec =iris$Species, cnt = 1)
df <- aggregate(df$cnt,list(cl = df$cl,spec= df$spec),sum )
df <- df %>% group_by(spec) %>% filter(x == max(x))
listed_1[[i]] <- round(sum(df$x)/nrow(iris),2)*100
}
现在你得到了一个结果列表:以下命令将把 (cbind
) 放在一个 data.frame 列表中,结果 (do.call(rbind, listed_1)
) 和组合(do.call(rbind, comb)
):
res <- cbind(do.call(rbind, listed_1),do.call(rbind, comb))
res[which.max(res[,1]),]
[1] "95" "Petal.Length" "Petal.Width"