批量计算调整后的 p 值

数据挖掘 Python r 统计数据 相关性
2022-02-24 00:06:49

数据

为简单起见,我提出以下方案:

  1. 我有两个DataFrame,一个带基因,另一个带miRNA(这是一个简单的例子,DF不是这样的),数据是连续的:
             Gene_1    Gene_2    Gene_3                                        
Patient_1    220.43    12,959    12,311
Patient_2    270.27    12,870    13,234
             miRNA_1   miRNA_2    miRNA_3                                        
Patient_1    220.43    12,959     12,311
Patient_2    270.27    12,870     13,234
  1. 我必须绘制所有基因与所有 miRNA 的相关性(使用 Pearson、Kendall 或 Spearman 相关性,没关系),建立以下结构作为最终结果:
Gene     miRNA      Correlation  P-value        Adjusted P-value
Gen_1    miRNA_1    0,959        0.00311        0.00014
Gen_1    miRNA_2    -0,039       0.00311        0.00014
Gen_1    miRNA_3    -0,344       0.00311        0.00014
Gen_2    miRNA_1    0,1333       0.00311        0.00014
Gen_2    miRNA_2    0,877        0.00311        0.00014
...

问题

Cross Join 的结果(all against all)可能会产生一个包含数十亿行的 DataFrame。为了给出所需空间的维度,撇开基因和 miRNA 的列并考虑 3 亿行的小结果将需要 300000000 *(浮动 pt 中的 16 位相关性 + 64 位 p 值 + 64调整后的 p 值位)= 5 GB 约。

为了优化内存使用,我分批进行计算,问题在于调整后的 p 值,因为我使用Benjamini & Hochberg (1995)的方法和 R的函数p.adjust(使用 Python 包装器)这需要完整的 p 值数组,这使我内存不足。

有没有办法从另一个库或另一个类似的统计方法计算批量调整的 p 值?

我已经尝试过FastLSU技术来过滤掉一些不重要的 p 值,但据我所知,当我为每一行获得调整后的 p 值时,我需要知道所有的总 p 值。如果我可以为每一行获得调整后的 p 值,我的问题将得到解决,因为我可以将批次的结果下载到磁盘并告别并发症。

如果有人能对这个主题有所了解,我将不胜感激

1个回答

你能进一步解释一下你是如何批量计算的吗?整个 p 值数组本身不应大到足以导致内存问题。因此,您的主要问题似乎是您试图将交叉连接的 DF 保存在内存中并进行所需的计算。因此,这些是我的想法:

  • 如果您可以访问具有更多内存的集群,您可能可以按照当前的方式解决此问题。
  • 还有另一种解决方法,它将使用更少的内存并且可以在本地工作,但使用嵌套循环需要很长时间(见下文)。您还可以在中间写入结果,而不是在每个循环结束时进行联合。之后,您可以从内存中取出初始 DFS,然后加载所有中间结果并创建最终 df。
  • 您可以使用集群中先前要点中的方法,这会更好一些。
  • 如果您可以使用集群并将其并行化,那就更好了。这个问题非常适合 Spark。
  • 如果您无权访问集群,您仍然可以在自己的计算机上将其并行化,这可能对速度有所帮助。同样,我认为如果您使用 Spark 并在您的计算机上将其并行化,它会更快一些。

在这里,我将解释第一个项目符号,我认为它至少可以让您在没有内存问题的情况下获得最终数据帧:我会首先尝试将这个问题变成数据帧列的嵌套循环,您可以在其中找到 pval每个基因 --> 所有 miRNA,然后在计算 q 值并使用截止值后对其进行子集化。然后,您只会将满足您的 q 值阈值的对存储在内存中。我不建议尝试使用所有这些数据创建一个连接的 DF,因为这会占用太多内存。我为下面的循环编写了伪代码。我觉得这会帮助你耗尽内存,但它仍然会很慢。如果您的内存仍然不足,您是否有可用的集群?此外,将其并行化会更好。你可以用 python 编写它,但你有 Spark 吗?如果您将继续使用“大数据”,我会尝试访问您所在机构的集群或使用 AWS 或其他方式付费。

我将用基因称你的 DF:geneDF 和你的用 microRNA mirnaDF 的 DF。请记住,这是 python 伪代码,非常混乱。如果您认为它对您有用,我可以清理它。我更-所以只是写它以使我所写的内容更清晰。

top_adjusted_pairs = pd.DataFrame(columns=['gene', 'miRNA', 'qval'])
for i in range(len(geneDF)):
    # initialize array for the distances between all microRNAs with just gene X
    miRNA_geneX_pvals = []*len(microRNAsDF)
    geneCol = geneDF[i]
    for j in range(len(mirnaDF)):
         mirnaCol = mirnaDF[j]
         # compute distances and write pvalue into array
         pval = dist(geneCol, mirnaCol).pval
         miRNA_geneX_pvals[j] = [miRNA.name, gene.name, pval]
    # now that you have the array of distances between gene X and all miRNAs you can use multiple hypothesis correction. 
    qvals = adjust(miRNA_geneX_pvals['pval'])
    # pick q-val cut off
    top_mirna_geneX = miRNA_geneX_pvals[qvals<0.1]

top_adjusted_pairs.union(top_mirna_geneX)
         
        
```