计算相似性百分比或两个以上对象之间的计算相关性

时间:2016-11-21 05:01:25

标签: r machine-learning statistics

考虑我有四个对象(a,b,c,d),我要求五个人根据他们的外貌或其他东西标记它们(类别1或2)。五个人为这些物体提供的标签显示为

df <- data.frame(a = c(1,2,1,2,1), b=c(1,2,2,1,1), c= c(2,1,2,2,2), d=c(1,2,1,2,1))

以表格格式,

 ---------
  a b c d
 ---------
  1 1 2 1
  2 2 1 2
  1 2 2 1
  2 1 2 2
  1 1 2 1
----------

现在我想计算一组对象被赋予相同标签(1或2)的百分比。例如,对象a,b和d由5个人中的3个人给出相同的标签。所以它的百分比是3/5(= 60%)。虽然对象a和d被所有人给予相同的标签,所以它的百分比是5/5(= 100%)

我可以手动计算这个统计数据,但在原始数据集中,我有50个这样的对象,人数为30,标签为4(1,2,3和4)。如何自动为这个更大的数据集计算此类统计数据? R中是否有可以计算此类统计信息的现有软件包/工具?

注意:一个组可以是任何大小。在第一个例子中,一个组由a,b和d组成,而第二个例子组由a和d组成。

6 个答案:

答案 0 :(得分:4)

如果您有数字评级,则可以使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <div class="clsname">scroll to here</div> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>检查每个评估者之间是否始终存在diff差异:

0

将函数应用于示例组时,结果与预期一致:

f <- function(cols, data) {
  sum(colSums(diff(t(data[cols]))==0)==(length(cols)-1)) / nrow(data)
}

答案 1 :(得分:3)

这里有两个任务:第一,列出所有相关组合,第二,评估和聚合行方向相似性。 combn可以启动第一项任务,但需要进行一些按摩才能将结果排列到整齐的列表中。第二个任务可以用prop.table来处理,但这里直接计算更简单。

这里我使用了tidyverse语法(主要是purrr,这对处理列表有帮助),但如果你愿意,可以转换成基数。

library(tidyverse)

map(2:length(df), ~combn(names(df), .x, simplify = FALSE)) %>%    # get combinations
    flatten() %>%    # eliminate nesting
    set_names(map_chr(., paste0, collapse = '')) %>%    # add useful names
    # subset df with combination, see if each row has only one unique value
    map(~apply(df[.x], 1, function(x){n_distinct(x) == 1})) %>% 
    map_dbl(~sum(.x) / length(.x))    # calculate TRUE proportion

##   ab   ac   ad   bc   bd   cd  abc  abd  acd  bcd abcd 
##  0.6  0.2  1.0  0.2  0.6  0.2  0.0  0.6  0.2  0.0  0.0 

答案 2 :(得分:2)

使用基本R函数,您可以:

 groupVec = c("a","b","d")

 transDF = t(as.matrix(DF))

 subDF  = transDF[rownames(transDF) %in% groupVec,]
 subDF
   # [,1] [,2] [,3] [,4] [,5]
 # a    1    2    1    2    1
 # b    1    2    2    1    1
 # d    1    2    1    2    1

 #if length of unique values is 1, it implies match across all objects, count unique values/total columns = match pct
 match_pct = sum(sapply(as.data.frame(subDF), function(x)  sum(length(unique(x))==1) ))/ncol(subDF)
 match_pct
 # [1] 0.6

将其包装成自定义功能:

 fn_matchPercent = function(groupVec =  c("a","d") ) {


 transDF = t(as.matrix(DF))

 subDF  = transDF[rownames(transDF) %in% groupVec,]

 match_pct = sum(sapply(as.data.frame(subDF), function(x)  sum(length(unique(x))==1) ))/ncol(subDF)


 outputDF = data.frame(groups = paste0(groupVec,collapse=",") ,match_pct = match_pct)

 return(outputDF)

 }

 fn_matchPercent(c("a","d"))
   # groups match_pct
 # 1    a,d         1
 fn_matchPercent(c("a","b","d"))
   # groups match_pct
 # 1  a,b,d       0.6

答案 3 :(得分:2)

试试这个:

find.unanimous.percentage <- function(df, at.a.time) {
  cols <- as.data.frame(t(combn(names(df), at.a.time)))
  names(cols) <- paste('O', 1:at.a.time, sep='')
  cols$percent.unanimous <- 100*colMeans(apply(cols, 1, function(x) apply(df[x], 1, function(y) length(unique(y)) == 1)))
  return(cols)
}

find.unanimous.percentage(df, 2) # take 2 at a time

  O1 O2 percent.unanimous
1  a  b                60
2  a  c                20
3  a  d               100
4  b  c                20
5  b  d                60
6  c  d                20

find.unanimous.percentage(df, 3) # take 3 at a time

  O1 O2 O3 percent.unanimous
1  a  b  c                 0
2  a  b  d                60
3  a  c  d                20
4  b  c  d                 0

find.unanimous.percentage(df, 4)  

  O1 O2 O3 O4 percent.unanimous
1  a  b  c  d                 0

答案 4 :(得分:1)

聚类相似性度量

如果您的实际问题需要评估群集相同数据的各种选项,您似乎可能想要计算与您现在建议的实质上不同(更好?)的指标。

http://cs.utsa.edu/~qitian/seminar/Spring11/03_11_11/IR2009.pdf概述了问题,但BCubed精确/召回指标通常用于NLP中的类似问题(例如http://alias-i.com/lingpipe/docs/api/com/aliasi/cluster/ClusterScore.html)。

答案 5 :(得分:0)

试试这段代码。它适用于您的示例,并且应该适用于扩展案例。

df <- data.frame(a = c(1,2,1,2,1), b=c(1,2,2,1,1), c= c(2,1,2,2,2), d=c(1,2,1,2,1))

# Find all unique combinations of the column names
group_pairs <- data.frame(t(combn(colnames(df), 2)))

# For each combination calculate the similarity
group_pairs$similarities <- apply(group_pairs, 1, function(x) {
  sum(df[x["X1"]] == df[x["X2"]])/nrow(df)
})