考虑一个聚类问题,其中知道真正的类标签(例如g
)。
假设p
表示预测的聚类标签(可以通过任何聚类方法获得)。
因此,g
和p
都将数据集分成一些组,尽管在两种情况下组的数量不必相同。
在这两组分组中,尽管在两种情况下它们的标签可能不同,但在某些情况下,g
的一组将与p
的另一组相同。我想找到这样的组的数量,即,我想找到聚类方法能够完美检测到一个类的情况的数量。
我知道这不是评估聚类的标准方法(建议使用兰德指数,邓恩指数等),但是对此我很感兴趣。我还了解到,在大多数现实生活数据中,这个数字将非常小,甚至可能是0
,但是我目前正在使用的数据集具有大量(大约1500个)类,其中最大的类一类中的观测值最多为15。因此,在这种情况下,这个数字可能会很高。
这是一个可复制的示例,我在解决方案上的尝试(正在努力):
# true labels
g <- c(1, 1, 2, 2, 2, 1, 3, 3, 3, 4)
# predicted labels
p <- c(3, 3, 1, 1, 1, 3, 4, 4, 1, 2)
# correctly detected groups
n_correct <- 2 # (1st class and 3rd cluster), (4th class and 2nd cluster)
# attempt
distinct_class_labels <- unique(x = g)
counter <- 0
for (i in seq_along(along.with = distinct_class_labels))
{
cluster_labels_of_obs_in_ith_class <- subset(x = p,
subset = (g == distinct_class_labels[i]))
unique_cluster_labels_of_obs_in_ith_class <- unique(x = cluster_labels_of_obs_in_ith_class)
if (length(x = unique_cluster_labels_of_obs_in_ith_class) == 1)
{
class_labels_of_obs_in_this_cluster <- subset(x = g,
subset = (p == unique_cluster_labels_of_obs_in_ith_class))
if (length(x = unique(x = class_labels_of_obs_in_this_cluster)) == 1)
{
counter <- (counter + 1)
}
}
}
counter
#> [1] 2
由reprex package(v0.3.0)于2019-05-22创建
这正常工作,但是需要时间(我不喜欢这种方法)。我想可以将dplyr::group_by
和g
分别使用p
并以某种方式比较这两个对象的组。我猜想还有其他更好的方法,我将非常感谢这些答案。
谢谢。
答案 0 :(得分:2)
如果您也对正确检测到的组的组合感兴趣,则可以尝试
library(tidyverse)
tibble(g = g, p=p) %>%
distinct(g,p) %>% # unique combinations of g and p
add_count(g, name="g_count") %>% # count how often each class/label occurs in g and p. When it is unambiguous assigned it should be 1
add_count(p, name="p_count") %>%
filter(g_count == 1 & p_count == 1) %>%
select(g,p)
# A tibble: 2 x 2
g p
<dbl> <dbl>
1 1 3
2 4 2
行数(您可以使用nrow()
)将为您提供正确检测到的组数
答案 1 :(得分:1)
根据g
和p
在向量中的出现,将factor
和levels
转换为sum(table(factor(p, levels = unique(p))) == table(factor(g, levels = unique(g))))
#[1] 2
,并计算匹配的频率。
table(factor(p, levels = unique(p)))
#3 1 4 2
#3 4 2 1
table(factor(g, levels = unique(g)))
#1 2 3 4
#3 3 3 1
要了解,请参见
inds <- table(factor(p, levels = unique(p))) == table(factor(g, levels = unique(g)))
unique(p)[inds]
#[1] 3 2
unique(g)[inds]
#[1] 1 4
我们可以忽略标签(因为组标签不同),而只关注频率。我们可以看到第一个和第四个值具有相同的频率,因此计数为2。
如果您想找出哪些组相似,可以这样做
p
这表示g
中的组3与table
中的组1相似,分别与2和4相同。
在使用split
解决它之前,我使用sum(lengths(split(p, factor(p, levels = unique(p)))) ==
lengths(split(g, factor(g, levels = unique(g)))))
完成了它,尽管基本逻辑是相同的。
g1 <- c(g, 5)
p1 <- c(p, 1)
sum(table(factor(p1, levels = unique(c(p1, g1)))) ==
table(factor(g1, levels = unique(c(g1, p1)))))
#[1] 2
编辑
如果有阶级失衡的可能,我们需要将各个等级结合起来以涵盖所有等级。例如,
JObject