背景
我正在尝试编码Fisher的精确测试(参见:wiki),特别是2 x 2列联表(矩阵)。但是我坚持在一个特定的步骤: 在给定观察到的非负整数矩阵的情况下生成替代矩阵,其中替代矩阵的行和列总和必须等于原始矩阵。 / em> This page (Wolphram)描述了所有步骤,但下面我会详细说明我坚持使用的位。
问题
为了对2 x 2列联表实施Fisher精确检验,给出了一个2 x 2矩阵,其元素是表示观测值的非负整数,观察到的矩阵。
其中一个步骤要求我生成2 x 2矩阵的所有组合,替代矩阵,其非负整数元素受以下条件限制:
对我而言,生成替代矩阵的最明显方法是在2 x 2矩阵中强制所有可能的数字组合,其值小于或等于观察到的矩阵的行/列的总和。然后迭代这些组合,过滤掉不符合上述条件的组合。
编辑:在2x2矩阵(替代矩阵)中生成所有元素组合的最快算法是什么,行和列总和等于观察到的 / em>矩阵?
原文:我们如何用以下任何一种语言实现它:R,Python,C / C ++,Matlab?
示例
对于2×2测试的示例应用,让X成为期刊,比如数学杂志或科学,并且让Y成为关于数学和生物学主题的文章的数量出现在其中一个这些期刊。如果“数学杂志”有五篇关于数学的文章和一篇关于生物学的文章,而“科学”没有关于数学和关于生物学的四篇文章,那么相关的矩阵将是:
然后所有可能的替代矩阵将是:
相关帖子
答案 0 :(得分:1)
我有一个使用sympy的答案。这个想法是一样的:解决从矩阵元素之和得到的线性方程组,即行数和列数。这是硬编码的M. s基本上是你的矩阵。 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})
答案 1 :(得分:0)
这实际上非常简单。您只需要选择符合条件的所有可能组合。
这是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