确定聚类相似性/集重叠

时间:2017-11-25 20:20:17

标签: r for-loop cluster-analysis similarity

我要做的是运行两个集群算法(让他们称之为A和B),然后比较结果(即算法对同一集群中80%的模型进行分类)。一个简单的例子有3个模型:

cl_A = c(1,2,1) #the result from Algorithm A
cl_B = c(2,1,2) #the result from Algorithm B

我希望从中获得什么解决方案?好吧,100%。为什么?因为我可以重命名"我头脑中的簇(将模型B的簇1重命名为2,簇2重命名为1),然后发现簇完全相同。
换句话说,群集中的模型是相同的,这就是我们所关心的(我们不关心群集的名称和#34;并且没有固有的排序在里面)。

这个例子怎么样?

cl_A = c(1,2,1,3)
cl_B = c(2,1,2,2)

(注意:两个矢量的长度总是相同,但值可以在不同的范围内)
在这种情况下,我想得到3/4作为答案(即"重命名" cl_B到c(1,2,1,1)然后说有3个元素,其中cl_A和cl_B是相同的。)

现在,我已经编写了一个函数,我手工检查了简单的例子(例如上面的例子),但是我不能帮助他感觉对于更复杂的例子来说它不起作用... <登记/> 如果你们中的任何人有想法和/或解决方案随时评论他们。

这是我的功能,但我首先要解释一下我的所作所为: 我通过&#34;簇矢量&#34; (集群分配的向量)到它(上例中的cl_A和cl_B)。然后,我基本上循环遍历第一个向量的所有聚类,并为第二个向量的所有聚类循环,并选择&#34; best&#34;交叠。因为我只想选择每个集群一次(即我不能说我将所有&#34; 1&#34; s重命名为&#34; 2&#34; s,但后来决定我&#39; d也想将一些&#34; 1&#34; s重命名为&#34; 3&#34; s(然后我总是得到一个完美的契合))我保留一个&#34; taboo_list&#34; 。
而这基本上就是它的全部内容。但是,感觉它没有100%正确地工作,我希望在这里找到一些帮助。谢谢!

#'  cluster similarity
#' 
#' calculate how "similar" two methods / clusters are:
#' sum(kmeans_cluster_similarity(cluster1, cluster2))/length(cluster1)
#' is the % of objects that are in a cluster with the same objects as before
#' 
#' @param cluster_vector_1 the first cluster object, as for example returned by knn() 
#' @param cluster_vector_2 the second cluster object
#' @export
#' 
cluster_similarity = function(cluster_vector_1, cluster_vector_2){
  taboo_list_2 <<- rep(NA, length(unique(cluster_vector_1)))
  overall_similarity <<- rep(NA, length(unique(cluster_vector_1)))

  for(i in unique(cluster_vector_1)){
    cl1 = which(cluster_vector_1 == i)
    similarity <- rep(NA, length(unique(cluster_vector_1)))
    for(j in unique(cluster_vector_2)){
      if(!(j %in% taboo_list_2)){
        cl2 = which(cluster_vector_2 == j)
        similarity[j] <- sum(cl1 %in% cl2)
      }
    }
    best_j <- which.max(similarity)
    taboo_list_2[i] <<- best_j
    overall_similarity[i] <<- max(similarity, na.rm = TRUE)
    #print(overall_similarity)
  }
  #print(overall_similarity)
  return(overall_similarity)
}

一个例子:

cl_A = c(1,2,1)
cl_B = c(2,1,2)
cluster_similarity(cl_A,cl_B)

的工作原理。但我很确定其他一些东西不起作用......

修改

为什么我这样做似乎有些混乱,所以让我试着澄清一下:我有数据(现在没有人),我显然无法从哪里说出来,但我想到了一个很好的类比:想想几个Kaggle案例竞赛(称之为comp_A,comp_B,......)。 对于每个比赛,你有几个参与者交出一些结果(分别称为part_1,... part_n和inp_1,...,inp_n)。
现在显然并非所有参与者都为每场比赛提供一些东西。比赛A可能会有来自参赛者1-20的参赛者,而比赛2可能只有1-10和20-25的参赛者 我想做的是找出哪些&#34;参与者&#34;是相似的。
例如,part_1类似于part_2和part_10,依此类推

没有任何验证设置(甚至不是小验证),并且对于每个&#34;竞争&#34;大约有20个参与者,每个参与者有1个输入。这些输入是巨大的(好吧,每个20MB,但它加起来)

然后我的想法是为每个竞赛聚集参与者(或者更确切地说,他们的输入),并查看哪些参与者通常在同一个集群中(例如,如果part_1和part_2在comp_A和comp_B的同一集群中comp_C,也许它们是相似的)
好吧,我不知道使用一种集群方法比另一种集群方法有任何理论上的理由,所以我让它们全部运行(并且没有验证集,它很难评估),现在想要看看@Logister是否正确识别了每个聚类算法的稳健性,以确定哪一个可能是最好的 我希望澄清我的问题的背景,并且我总是愿意接受更具建设性的想法!

2 个答案:

答案 0 :(得分:2)

这是群集验证的主题。 R中已有函数可以为您提供集群之间“相似性”的值,例如Rand Index和Adjusted Rand Index。我建议你使用它们。

调整兰德指数是衡量集群之间协议的最佳方法。

  

ARI不仅测量属于不同类的元素的正确分离,还测量同一类元素之间的关系(   who said that

ARI功能可以找到here

ARI背后的数学并不是基本的。因此,我建议你查看兰德指数测量,这很容易理解,并实现它。

注意:当 similarity 向量具有几个最大值时,您的函数不会考虑。在那种情况下该怎么办?我建议你看this video

答案 1 :(得分:1)

通常在不同算法之间“比较结果”并未参考它们之间的一致程度来完成。那么如果算法有协议怎么办?我建议退后一步,问你想要完成什么。

通常重要的是您的群集预测或识别其他现象的程度。例如。如果您尝试使用聚类进行某种分类,评估模型的好方法是查看classification entropy

我能想到为什么有人想要做你正在做的事情的唯一原因是检查集群是否“健壮”。如果这是你想要评估的,那么比较两种不同的算法就不会得到你想要的;你必须比较喜欢。我建议做一些交叉验证/子抽样检查,如果算法与在不同迭代中自身协议相同。 R应该有内置函数来为你做这件事。