gpt4 book ai didi

performance - 高效的列相关系数计算

转载 作者:行者123 更新时间:2023-12-04 20:09:57 25 4
gpt4 key购买 nike

原问题

我将大小为 n 的行 P 与大小为 n×m 的矩阵 O 的每一列相关联。我编写了以下代码:

import numpy as np

def ColumnWiseCorrcoef(O, P):
n = P.size
DO = O - (np.sum(O, 0) / np.double(n))
DP = P - (np.sum(P) / np.double(n))
return np.dot(DP, DO) / np.sqrt(np.sum(DO ** 2, 0) * np.sum(DP ** 2))

它比幼稚的方法更有效:

def ColumnWiseCorrcoefNaive(O, P):
return np.corrcoef(P,O.T)[0,1:O[0].size+1]

以下是我在英特尔内核上使用 numpy-1.7.1-MKL 获得的时序:

O = np.reshape(np.random.rand(100000), (1000,100))
P = np.random.rand(1000)

%timeit -n 1000 A = ColumnWiseCorrcoef(O, P)
1000 loops, best of 3: 787 us per loop
%timeit -n 1000 B = ColumnWiseCorrcoefNaive(O, P)
1000 loops, best of 3: 2.96 ms per loop

现在的问题是:您能否为这个问题建议一个更快的代码版本?挤出额外的 20% 会很棒。

2017 年 5 月更新

很长一段时间后,我又回到了这个问题,重新运行并扩展了任务和测试。
  • 使用 einsum,我将代码扩展到 P 不是行而是矩阵的情况。因此,任务是将 O 的所有列与 P 的所有列相关联。
  • 我很好奇如何用科学计算常用的不同语言解决相同的问题,我在 MATLAB、Julia 和 R 中实现了它(在其他人的帮助下)。 MATLAB 和 Julia 是最快的,并且它们有专门的例程计算列相关。 R 也有一个专门的例程,但它是最慢的。
  • 在当前版本的 numpy(来自 Anaconda 的 1.12.1)中,einsum 仍然胜过我使用的专用函数。

  • 所有脚本和时间都可以在 https://github.com/ikizhvatov/efficient-columnwise-correlation 获得.

    最佳答案

    我们可以介绍np.einsum对此;但是,您的里程可能会vary取决于您的编译以及它是否使用 SSE2。额外的 einsum替换求和操作的调用可能看起来无关紧要,但 numpy ufunc 直到 numpy 1.8 才使用 SSE2,而 einsum确实如此,我们可以避免一些 if声明。

    在带有 intel mkl blas 的 opteron 内核上运行它,我得到了一个奇怪的结果,正如我所期望的 dot打电话占用大部分时间。

    def newColumnWiseCorrcoef(O, P):
    n = P.size
    DO = O - (np.einsum('ij->j',O) / np.double(n))
    P -= (np.einsum('i->',P) / np.double(n))
    tmp = np.einsum('ij,ij->j',DO,DO)
    tmp *= np.einsum('i,i->',P,P) #Dot or vdot doesnt really change much.
    return np.dot(P, DO) / np.sqrt(tmp)

    O = np.reshape(np.random.rand(100000), (1000,100))
    P = np.random.rand(1000)

    old = ColumnWiseCorrcoef(O,P)
    new = newColumnWiseCorrcoef(O,P)

    np.allclose(old,new)
    True

    %timeit ColumnWiseCorrcoef(O,P)
    100 loops, best of 3: 1.52ms per loop

    %timeit newColumnWiseCorrcoef(O,P)
    1000 loops, best of 3: 518us per loop

    再次使用带有 intel mkl 的 intel 系统运行它,我得到了更合理/预期的结果:

    %timeit ColumnWiseCorrcoef(O,P)
    1000 loops, best of 3: 524 µs per loop

    %timeit newColumnWiseCorrcoef(O,P)
    1000 loops, best of 3: 354 µs per loop

    再次在英特尔机器上使用更大的东西:

    O = np.random.rand(1E5,1E3)
    P = np.random.rand(1E5)

    %timeit ColumnWiseCorrcoef(O,P)
    1 loops, best of 3: 1.33 s per loop

    %timeit newColumnWiseCorrcoef(O,P)
    1 loops, best of 3: 791 ms per loop

    关于performance - 高效的列相关系数计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19401078/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com