Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用numpy计算两两互信息的最佳方法_Python_Performance_Numpy_Scipy_Information Theory - Fatal编程技术网

Python 用numpy计算两两互信息的最佳方法

Python 用numpy计算两两互信息的最佳方法,python,performance,numpy,scipy,information-theory,Python,Performance,Numpy,Scipy,Information Theory,对于m x n矩阵,计算所有列对(n x n)的互信息的最佳(最快)方法是什么 我的意思是: I(X,Y)=H(X)+H(Y)-H(X,Y) 其中H(X)指X的香农熵 目前我正在使用np.histogram2d和np.histogram来计算关节(X,Y)和个体(X或Y)计数。对于给定的矩阵a(例如250000 X 1000个浮点矩阵),我正在为循环执行嵌套 n = A.shape[1] for ix = arange(n) for jx = arange(i

对于m x n矩阵,计算所有列对(n x n)的互信息的最佳(最快)方法是什么

我的意思是:

I(X,Y)=H(X)+H(Y)-H(X,Y)

其中H(X)指X的香农熵

目前我正在使用
np.histogram2d
np.histogram
来计算关节(X,Y)和个体(X或Y)计数。对于给定的矩阵
a
(例如250000 X 1000个浮点矩阵),我正在为
循环执行嵌套

    n = A.shape[1]
    for ix = arange(n)  
        for jx = arange(ix+1,n):
           matMI[ix,jx]= calc_MI(A[:,ix],A[:,jx])
肯定有更好/更快的方法来做到这一点

顺便说一句,我还寻找了数组上的列映射函数(列操作或行操作),但还没有找到一个好的通用答案

以下是我的完整实施,遵循中的约定:

尽管我的工作版本使用嵌套的
for
循环以合理的速度运行,但我想知道是否有更理想的方法将
calc\u MI
应用于
a
的所有列(以计算它们的成对互信息)

我还想知道:

  • 是否有有效的方法将函数映射到
    np.array
    的列(或行)(可能类似于
    np.vectorize
    ,它看起来更像一个装饰器)

  • 是否有其他针对该特定计算的最佳实现(互信息)


  • 我不能建议对n*(n-1)/2上的外环进行更快的计算 向量,但可以简化
    计算MI(x,y,bin)
    的实现 如果可以使用scipy版本0.13或

    在scipy 0.13中,向 此参数控制函数计算的统计信息。如果 使用对数似然比 他回来了。这也通常被称为G或G2统计。除了 2*n的系数(其中n是偶然事件中的样本总数 表),这是相互信息。因此您可以实现
    calc\u MI
    作为:

    这与您的实现之间的唯一区别是 实现使用自然对数而不是以2为底的对数 (因此它用“nats”而不是“bits”来表示信息)。如果 您确实更喜欢位,只需将
    mi
    除以log(2)

    如果您有(或可以安装)
    sklearn
    (即scikit-learn),您可以使用 ,并将
    calc_MI
    实现为:

    from sklearn.metrics import mutual_info_score
    
    def calc_MI(x, y, bins):
        c_xy = np.histogram2d(x, y, bins)[0]
        mi = mutual_info_score(None, None, contingency=c_xy)
        return mi
    

    您能否将示例代码扩展为包含
    calc\u MI
    A
    的示例输入?这样我们就可以复制、粘贴和运行。将极大地帮助任何试图回答您的问题的人。请阅读此内容并更新您的示例代码,以包括
    calc_MI
    A
    的示例输入。我之前的评论是无意中输入的,而我本想回应此建议。感谢指向sscce.org的指针。对于您当前的方法,这是一个准确的自包含示例吗。如果矩阵的大小为
    (n,m)
    ,则没有简单的方法可以仅对所需的
    n*(n-1)/2
    唯一值进行向量化计算,尽管在完全笛卡尔积中对
    n*n
    值进行向量化计算通常更快,即使是重复的。问题在于,它需要一次创建所有中间计算对象。使用上述方法,您必须找到一种创建4D
    历史图的方法。。。我看不出你庞大的数据集能解决这个问题。我会研究Cython或C扩展…很好的代码!垃圾箱数量的合理默认值是多少?@felbo这是个好问题,不是一个容易回答的问题。你可能会得到一些想法,如果你问它在这个方法不工作,如果一些计数等于零。你为什么建议这种方法超过密度估计?此外,我对你的答案投了赞成票,因为它确实提供了一种有效的方法来计算某些情况下的MI。“你为什么建议这种方法超过密度估计?”我没有。我只建议了问题中给出的代码的两种替代实现。建议的两种方法因连续性校正而不同。更改为
    chi2\u意外事件(correction=False)
    将删除此不一致性。
    from scipy.stats import chi2_contingency
    
    def calc_MI(x, y, bins):
        c_xy = np.histogram2d(x, y, bins)[0]
        g, p, dof, expected = chi2_contingency(c_xy, lambda_="log-likelihood")
        mi = 0.5 * g / c_xy.sum()
        return mi
    
    from sklearn.metrics import mutual_info_score
    
    def calc_MI(x, y, bins):
        c_xy = np.histogram2d(x, y, bins)[0]
        mi = mutual_info_score(None, None, contingency=c_xy)
        return mi