2x2矩阵中元素的所有组合,行和列和等于指定值

2024-05-23 14:48:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写Fisher的精确测试代码(参见:wiki),特别是针对2x2列联表(矩阵)。但是我在一个特定的步骤上被卡住了:在观察到的非负整数矩阵的情况下生成替代矩阵,其中替代矩阵的行和和和必须等于原始矩阵。This page (Wolphram)有所有步骤的描述,但下面我将详细说明我所坚持的部分。在


问题

为了实现2x2列联表的Fisher精确检验,我们给出了一个2x2矩阵,其元素是表示观察值的非负整数,即观察到的矩阵。在

其中一个步骤要求我生成2 x 2矩阵的所有组合,备选矩阵,其非负整数元素受以下条件限制:

  • 所有备选矩阵的维数为2×2,即等于观测矩阵。在
  • 备选矩阵的每一行的和必须等于观测矩阵x m的每一行的相应和,即观察矩阵中第2行的和==每个备选矩阵中第2行的和。在
  • 备选矩阵每列之和必须等于观测矩阵每列的相应和。在

对我来说,生成替代矩阵最明显的方法是在一个2x2矩阵中强制所有可能的数字组合,其值小于或等于所观察矩阵的行/列之和。然后迭代这些组合,过滤掉不满足上述条件的组合。在

编辑:在2x2矩阵(备选矩阵)中生成所有元素组合的最快算法是什么?行和列和等于观察到的矩阵的行和和和?

< S>原件:我们如何用以下语言实现这一点:R、Python、C/C++、Matlab?


示例

以2×2检验的一个应用为例,设X为期刊,如《数学杂志》或《科学》,Y为某一期刊某一期中出现的有关数学和生物学主题的文章数。如果《数学》杂志有五篇关于数学的文章和一篇关于生物学的文章,而《科学》没有关于数学的文章和四篇关于生物的文章,那么相关的矩阵将是:

enter image description here

所有可能的替代矩阵将是:

enter image description herew


相关帖子


Tags: and元素文章步骤矩阵数学整数科学
2条回答

这其实很简单。您只需从所有可能的组合中选择符合条件的组合。在

下面是python中的一个解决方案:

# [[i, j]
#  [k, l]]

def findAlternativeMatrices(c):
    # arg c = cont. matrix
    # this only works for integers
    alt = []
    # no single value inside an alternative matrix
    # can be bigger than the largest row/column-sum 
    N = max([c[0][0]+c[1][0],c[0][1]+c[1][1],c[0][0]+c[0][1], c[1][0]+c[1][1]])
    # loop over all matrix entries
    for i in range(N):
        for j in range(N):
            for k in range(N):
                for l in range(N):
                    #check if the respective sums equal
                    if(     (i+k == (c[0][0]+c[1][0]) )
                        and (j+l == (c[0][1]+c[1][1]) )
                        and (i+j == (c[0][0]+c[0][1]) )
                        and (k+l == (c[1][0]+c[1][1]) ) ):

                        if [[i,j],[k,l]] != c:
                            # append the matrix 
                            # if it isn't the given cont. matrix
                            alt.append([[i,j],[k,l]])

    return alt


c = [[5,0],[1,4]]
alt = findAlternativeMatrices(c)

for a in alt:
    print a

我有一个答案用sympy。想法是一样的:求解线性方程组,从矩阵元素的和中得到行数和列数。这是硬编码的,基本上就是你的矩阵。linsolve给你无穷多的解,其余的则把它们限制为正整数。在

from sympy import *
from sympy.solvers.solveset import linsolve
from sympy.sets.fancysets import Naturals0
from sympy.solvers.inequalities import reduce_inequalities

M = Matrix([[1,1,0,0],[0,0,1,1],[1,0,1,0],[0,1,0,1]])
s = Matrix([5,5,6,4])

a,b,c,d = symbols('a, b, c, d')
solution = linsolve((M,s), [a,b,c,d])

solution_eq = [x >= 0 for x in list(list(solution)[0])]
possible_values = reduce_inequalities(solution_eq, x.free_symbols)

for d_fixed in Intersection(possible_values.as_set(), Naturals0()):
    print solution.subs({d : d_fixed})

相关问题 更多 >