Python 如何使用成对比较矩阵来找到最佳的n个候选项进行分析?

Python 如何使用成对比较矩阵来找到最佳的n个候选项进行分析?,python,r,linear-algebra,bioinformatics,Python,R,Linear Algebra,Bioinformatics,我有一组DNA序列(字符串),我以成对的方式相互比较。每次比较都提供了序列之间的确切相似度(相同的核苷酸数量),并用于填充较低的对角矩阵。现在,我想在这个矩阵中找到8个序列的子集(所有可能的8个序列组),它们之间的相似性最小(这些8个序列组中的成对相似性应该尽可能低),但我不知道如何继续 任何使用R(首选)或Python的帮助都将不胜感激 下面是我的矩阵示例: 这里的主要思想是找到n个序列(例如,2个序列)的子集,它们之间的相似性最小。 我的原始矩阵是61X61 seq1 seq2 se

我有一组DNA序列(字符串),我以成对的方式相互比较。每次比较都提供了序列之间的确切相似度(相同的核苷酸数量),并用于填充较低的对角矩阵。现在,我想在这个矩阵中找到8个序列的子集(所有可能的8个序列组),它们之间的相似性最小(这些8个序列组中的成对相似性应该尽可能低),但我不知道如何继续

任何使用R(首选)或Python的帮助都将不胜感激

下面是我的矩阵示例: 这里的主要思想是找到n个序列(例如,2个序列)的子集,它们之间的相似性最小。 我的原始矩阵是61X61

    seq1 seq2 seq3 seq4
seq1 NA  NA   NA   NA
seq2 1   NA   NA   NA
seq3 2    5   NA   NA
seq4 3    2   6    NA

在本例中,相似性最小的n=2的子集为(seq1,seq2),相似性为1。n=3的子集将是(seq1,seq2,seq4),因为在这种情况下,它们的成对相似性之和是最低的(seq1,seq2=1,seq1,seq4=3,seq2,seq4=2;sum=6)。(我一直使用成对交互的最小和作为目标,但如果无法达到,我会很高兴建立一个截止点,例如:子集中的成对交互不应大于20)。

我不确定我是否完全理解任务,我可能过于简单化,但这里有一个尝试

# some test data
seqs <- matrix(nrow = 10, ncol=10)
x <- length(seqs[lower.tri(seqs)])
seqs[lower.tri(seqs)] <- sample.int(n = 5, size = x, replace = TRUE)
nms <- paste("seq", 1:10, sep="")
rownames(seqs) <- colnames(seqs) <- nms

# all combinations of 4 sequences
all_4 <- combn(x = nms, 4, simplify = FALSE)
names(all_4) <- paste("mat", 1:length(all_4), sep="_")

# a function to subset the matrix to a smaller one
submat <- function(mat, cols) {
  mat[cols, cols]
}

mats_4 <- lapply(all_4, function(x) submat(seqs, x))
# similarity per smaller matrix 
mats_4_dist <- sapply(mats_4, sum, na.rm=TRUE)
# index of those matrices with similarity < 20
mats_4_lt20_ind <- mats_4_dist < 20
# extract those matrices
mats_4_lt20 <- mats_4[mats_4_lt20_ind]

# alternatively, find the matrices with the minimal sum
mats_4_min <- mats_4[which.min(mats_4_dist)]

我不确定我是否完全理解这个任务,我可能过于简单化了,但这里有一个尝试

# some test data
seqs <- matrix(nrow = 10, ncol=10)
x <- length(seqs[lower.tri(seqs)])
seqs[lower.tri(seqs)] <- sample.int(n = 5, size = x, replace = TRUE)
nms <- paste("seq", 1:10, sep="")
rownames(seqs) <- colnames(seqs) <- nms

# all combinations of 4 sequences
all_4 <- combn(x = nms, 4, simplify = FALSE)
names(all_4) <- paste("mat", 1:length(all_4), sep="_")

# a function to subset the matrix to a smaller one
submat <- function(mat, cols) {
  mat[cols, cols]
}

mats_4 <- lapply(all_4, function(x) submat(seqs, x))
# similarity per smaller matrix 
mats_4_dist <- sapply(mats_4, sum, na.rm=TRUE)
# index of those matrices with similarity < 20
mats_4_lt20_ind <- mats_4_dist < 20
# extract those matrices
mats_4_lt20 <- mats_4[mats_4_lt20_ind]

# alternatively, find the matrices with the minimal sum
mats_4_min <- mats_4[which.min(mats_4_dist)]

下面是一个python实现。请注意,61 choose 8大约是30亿,所以检查每一个可能的组合,就像我在这里所做的,需要一段时间

来自itertools导入组合的

#数据帧存储为df
#假设列和索引具有相同的名称
_列的子集_=组合(df.columns,8)
最低=无
子集=无
对于_列的子集_中的s:
arr=df.loc[s,s].fillna(0).值
如果最低值为无:
最低=总金额()
子集=s
其他:
如果arr.sum()小于最低值:
子集=列表
最低=总金额()
打印(子集,最低)

这里是一个python实现。请注意,61 choose 8大约是30亿,所以检查每一个可能的组合,就像我在这里所做的,需要一段时间

来自itertools导入组合的

#数据帧存储为df
#假设列和索引具有相同的名称
_列的子集_=组合(df.columns,8)
最低=无
子集=无
对于_列的子集_中的s:
arr=df.loc[s,s].fillna(0).值
如果最低值为无:
最低=总金额()
子集=s
其他:
如果arr.sum()小于最低值:
子集=列表
最低=总金额()
打印(子集,最低)

您能否澄清所需的任务?例如,“8个序列的子集”是什么?我认为您正在寻找8个序列的集合(从您拥有的61个序列中)。选择8个序列的理想标准是什么?你只需要两两比较吗?8个序列共享或不共享相似性意味着什么?谢谢。8个序列的子集应该是来自61个数据集的8个序列的任意一组,当相互比较(通过成对比较)时,它们的相似性很低(这组中的每一对比较都应该是@FredBoehm。我也试图澄清我在正文中的问题。我希望这会有所帮助。你能澄清所需的任务吗?例如,“8序列的子集”是什么?我想你正在寻找8个序列的集合(从你拥有的61个序列中)。选择8个序列的理想标准是什么?您只需要成对比较吗?8个序列共享或不共享相似性意味着什么?谢谢。8个序列的子集应该是61个数据集中相互比较(通过成对比较)的8个序列的任意组将共享低相似性(该组中的每个成对比较应为@FredBoehm)。我还试图澄清我在正文中的问题。我希望这会有所帮助。非常感谢!我使用了“最小和”方法,效果很好(我不得不将组合数减少到最多6个)。关于相似性小于20的矩阵,我正在寻找每个成对比较小于20的子集(不是全部的和),但我认为代码可以很容易地进行修改。非常感谢!我使用了“最小和”方法,并且效果很好(我必须将组合数减少到最多6个).关于相似性小于20的矩阵,我在寻找每个成对比较小于20的子集(不是全部总和),但我认为代码可以很容易地进行调整。