【问题标题】:Find the first N elements shared between two vectors of correlation scores找到两个相关分数向量之间共享的前 N ​​个元素
【发布时间】:2021-11-29 07:14:24
【问题描述】:

我有两个数据表,train 和 target,由行中的样本和列中的化学物质组成,表中的值是样本中化学物质的相对丰度。两个数据集之间的化学物质是相同的。我已经找到了训练数据和目标数据中的值之间的 Spearman 相关性的绝对值,现在 我想找到最小的 i 使得第一个 i 两个数组的元素包含 n 个共同的元素。

示例:假设我们正在查看化学物质 Y1,训练和目标与化学物质 Y1 到 Y10 的相关值为:

     train
     Y1  Y2  Y3  Y4  Y5  Y6  Y7  Y8  Y9  Y10
Y1:   1  -1 -.2  .5 -.9  .7  .1  .1 -.2  -.5

     target
     Y1  Y2  Y3  Y4  Y5  Y6  Y7  Y8  Y9  Y10
Y1:   1  .1  .2  -.7 .6  .4  .2  .5 -.5  -.2

每个绝对值的排名顺序为:

     train
Y1:  Y1  Y2  Y5  Y6  Y4  Y10 Y9  Y3  Y7  Y8  
     target
Y1:  Y1  Y4  Y5  Y8  Y9  Y6  Y3  Y7  Y10 Y2

那么train和target之间的前5个共享元素是:

Y1:  Y1, Y5, Y4, Y6, Y9

所以对于 n = 5,两个数组的前 7 个元素具有共同的 Y1、Y5、Y4、Y6 和 Y9。并且比较它们的算法必须找到第 7 个元素才能找到两个列表中的 5 个。最坏的情况是,它必须到达第 10 个元素。

这是我尝试过的:

  • 对 train 和 target 的每种化学物质的绝对相关性列表进行排序,取两个列表的交集,并取结果的前 N ​​个元素。失败是因为 train 和 target 的化学物质相同,所以交集只是化学物质的整个列表,结果的顺序完全取决于 train 或 target 是 intersect() 的第一个参数

  • 一次去一种化学,取train和target的前N个相关分数的交集,检查交集的长度是否小于N,如果是,取前N+1个分数的交集, 重复直到交叉点是 N 长。准确,但假设集合交集为 O(n),这将是一个 O(n^2) 算法。我想做得更好。当前的 R 代码如下:

        common = c()
        num = 10
        i = num
        while(length(common)<(num)){
            common = intersect(corr_train[2:(i+1)], corr_target[2:(i+1)])
            i = i + 1
        }
    

有什么想法吗?

【问题讨论】:

  • abs(trainY2-tragetY2) 和 Y6 的特征有什么区别,使得 Y2 不会出现在结果向量上?
  • 是什么让您在 5 个第一个共享元素的列表中选择 Y9 而不是 Y2?如果您对 2 个排序集之间的每个 Y 的顺序求和,则可以选择具有 5 个最小值的元素来获得最终列表(在您的示例中为 2、6、7、10、12)。这将是 O(n + log(n)) 复杂度。
  • @marcguery 哎呀。我把问题表述错了。我应该说“找到最小的 i,使得两个数组的前 i 个元素包含共同的 n 个元素。”因此对于 n = 5,两个数组的前 7 个元素具有共同的 Y1、Y5、Y4、Y6 和 Y9。对困惑感到抱歉;我将编辑问题。
  • 如果在所有情况下,Y1=1,你只是把它留在里面,使你的前进选择变得复杂。你可以进一步澄清最小的网络i,这样它就会导致上面的评论如果需要最小,则排序,这将导致 Y1、Y9、Y6、Y4、Y5... 在将 Y1 连接回去之后。虽然按照目前的逻辑,Y2 很差。
  • 对不起,我不遵循“您可能会进一步澄清最小的网络 i,这样如果需要最小的,就会产生上述注释顺序,这将导致 Y1、Y9、Y6、Y4 , Y5 ...在将 Y1 连接回后。”但是你删除 Y1 是对的,它完全相同 1(这就是当前代码所做的;我只是想让示例保持简单)。

标签: r data-structures statistics


【解决方案1】:

该算法将使用 2 个大小相等的 'train' 和 'target' 集合中的 i 个最小排名元素构建包含 n 个公共元素的集合 复杂度为O(log(m)+m).

基本上,每个有序集合中的每个元素的排名相等的分数被计算出来,并在对应的元素之间进行比较。这个想法是只有在另一个列表中的相应元素排名不高时才将一个元素添加到公共列表中。

当将两个集合的不同元素相加得到相同的i时(例如n = 7,可以选择Y7或Y10),'train'集合将是任意的喜欢。

#Calculate the rank of each element in each set
trainrank <- rank(train)
targetrank <- rank(target)

#Sort both sets and attribute each element their rank
trainscores <- order(trainrank)
targetscores <- order(targetrank)

#Include elements of the train set if their ranking is
# superior or equal to those of the target set
includetrain <- trainscores>=targetscores
includetrain <- includetrain[trainrank]

#Include elements of the target set if their ranking is
# strictly superior to those of the train set
includetarget <- targetscores>trainscores
includetarget <- includetarget[targetrank]

#To get a set containing n common elements 
# from 2 sets of equal size m,
# this code will take 2*m operations at most
commonset <- c()
m = length(train)
n = 5

i = 1
while (length(commonset) < n){
  newelement <- NA
  while(i <= m & is.na(newelement)){
    #If the selection of train or target elements
    # gave the same i first elements,
    # this would favor the train element
    if(includetrain[i]){
      newelement <- train[i]
      includetrain[i] <- FALSE
    }
    else if (includetarget[i]){
      newelement <- target[i]
      includetarget[i] <- FALSE
    }
    else{
      i = i+1 #Next element if both are false
    }
  }
    commonset <- c(commonset, newelement)
}
commonset #Common set of n elements
# "Y1" "Y5" "Y4" "Y6" "Y9"
print(i) #First i elements used to build the common set
# 7

原始数据

#Train and target data sets
train <- c("Y1","Y2","Y5","Y6","Y4","Y10","Y9","Y3","Y7","Y8")
target <- c("Y1","Y4","Y5","Y8","Y9","Y6","Y3","Y7","Y10","Y2")

【讨论】:

  • 我喜欢你在这里的方法,虽然指定一个理想的ties.methodrank 避免了我的names(commonset) [1] "y1" "y3" "y4" "y6" "y7",我认为,在新环境中两次到达。在这种情况下,看起来ties.method = 'first' 会起作用……但仍然有点追寻 OP 的最终逻辑。
  • 无论如何,关于达到原始数据值的一些话似乎是有序的。
  • 原始数据值是 OP 提供的值。 OP 没有要求对他的相关值进行排序。
  • @Chris,使用的原始数据值 marcguery 是化学品 Y1 与化学品 Y1 到 Y10 的相关分数的绝对值的等级排序。我问题中的第一个代码框有数值相关分数;第二个是化学品的排名。
  • sort(rank(abs(target)), decreasing = TRUE) 表现得很好,只是说,对我来说,sort(rank(abs(train)), decreasing = TRUE) 仍然很滑,即使没有被要求,尽可能多地影响结果。
猜你喜欢
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 2021-08-03
  • 1970-01-01
相关资源
最近更新 更多