查找相同组的数量

时间:2019-05-22 08:47:48

标签: r

考虑一个聚类问题,其中知道真正的类标签(例如g)。

假设p表示预测的聚类标签(可以通过任何聚类方法获得)。

因此,gp都将数据集分成一些组,尽管在两种情况下组的数量不必相同。

在这两组分组中,尽管在两种情况下它们的标签可能不同,但在某些情况下,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_byg分别使用p并以某种方式比较这两个对象的组。我猜想还有其他更好的方法,我将非常感谢这些答案。

谢谢。

2 个答案:

答案 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)

根据gp在向量中的出现,将factorlevels转换为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