快速方式降低python中自相关函数的噪声?

时间:2017-12-05 20:10:40

标签: python numpy scipy correlation

我可以使用numpy的内置功能来计算自相关: <Grid RowSpacing="3" ColumnSpacing="3">

然而,由此产生的相关性自然是嘈杂的。我可以对数据进行分区,并计算每个结果窗口的相关性,然后将它们全部平均以计算更清晰的自相关,类似于numpy.correlate(x,x,mode='same')。在signal.welchnumpy中是否有一个方便的功能可以做到这一点,如果我自己计算分区并循环遍历数据,可能比我得到的更快?

更新

这是由@kazemakase回答的动机。我试图用一些用于生成下图的代码来表明我的意思。

可以看出@kazemakase是正确的,因为AC功能自然地平均了噪音。然而,AC的平均值具有更快的优势!如果通过FFT使用循环卷积计算相关性,scipy似乎可以缩放为np.correlate而不是O(n^2)

enter image description here

O(nlogn)

1 个答案:

答案 0 :(得分:2)

TL-DR:要降低自相关函数中的噪声,请增加信号的长度 x

对光谱估计中的数据进行分区和平均是一个有趣的想法。我希望它能起作用......

自相关定义为

enter image description here

我们说我们将数据分成两个窗口。他们的自相关变得

enter image description here

enter image description here

请注意它们在属性限制方面的区别。基本上,我们将自相关的总和分为两部分。当我们将它们重新组合在一起时,我们又恢复了原来的自相关性!所以我们没有获得任何收益。

结论是,在numpy / scipy中没有实现这样的东西,因为没有必要这样做。

说明:

  1. 我希望很容易看到这扩展到任意数量的分区。

  2. 为了保持简单,我将标准化排除在外。如果您将 Rxx 除以 n ,将部分 Rxx 除以 n / 2 ,则会得到Rxx / n == (Rxx1 * 2/n + Rxx2 * 2/n) / 2。即归一化部分自相关的平均值等于完全归一化的自相关。

  3. 为了让它更简单我假设信号 x 可以被索引超出0和 n -1的限制。实际上,如果信号存储在阵列中,这通常是不可能的。在这种情况下,完全和部分化自相关之间存在一个小差异,随着滞后 l 而增加。不幸的是,这只是精度的损失而且不会降低噪音。

  4.   

    代码异端!我不相信你的邪恶数学!

    当然,我们可以尝试一下,

    import matplotlib.pyplot as plt
    import numpy as np
    
    n = 2**16
    n_segments = 8
    
    x = np.random.randn(n)  # data
    
    rx = np.correlate(x, x, mode='same') / n  # ACF
    l1 = np.arange(-n//2, n//2)  # Lags
    
    segments = x.reshape(n_segments, -1)
    m = segments.shape[1]
    
    rs = []
    for y in segments:
        ry = np.correlate(y, y, mode='same') / m  # partial ACF
        rs.append(ry)
    
    l2 = np.arange(-m//2, m//2)  # lags of partial ACFs
    
    plt.plot(l1, rx, label='full ACF')
    plt.plot(l2, np.mean(rs, axis=0), label='partial ACF')
    plt.xlim(-m, m)
    plt.legend()
    plt.show()
    

    enter image description here

    虽然我们使用8段来平均ACF,但噪音水平在视觉上保持不变。

      

    好的,这就是为什么它不起作用但解决方案是什么?

    以下是好消息:自相关已经是一种降噪技术!嗯,至少在某种程度上:ACF的应用是找到被噪声隐藏的周期性信号。

    由于噪音(理想情况下)具有零均值,因此其影响会减少我们总结的元素。换句话说,您可以使用更长的信号来降低自相关中的噪声。 (我想这对于每种类型的噪声可能都不是这样,但应该适用于通常的高斯白噪声及其亲属。)

    随着更多数据样本,噪音越来越低:

    import matplotlib.pyplot as plt
    import numpy as np
    
    for n in [2**6, 2**8, 2**12]:
        x = np.random.randn(n)
    
        rx = np.correlate(x, x, mode='same') / n  # ACF
        l1 = np.arange(-n//2, n//2)  # Lags
    
        plt.plot(l1, rx, label='n={}'.format(n))
    
    plt.legend()    
    plt.xlim(-20, 20)
    plt.show()
    

    enter image description here