Python信號處理:自相關函數(對標MATLAB中的autocorr)

摘要:Python中,更確切地說是numpy、scipy、statsmodels這些庫中都有計算相關的方法。但numpy和scipy中的correlate方法的定義和MATLAB中的不同,導致計算結果不太一樣。看上去MATLAB和statsmodels裏都是用的標準的統計中的定義——皮爾森相關係數,而numpy和scipy中使用的是非正式的信號處理中的定義,需要均值爲0,且計算結果需要歸一化,纔會得到差不多的答案。

系列目錄

  1. Python信號處理:快速傅里葉變換(FFT),短時傅里葉變換(STFT),窗函數,以及濾波
  2. Python信號處理:自相關函數(對標MATLAB中的autocorr)
  3. Python信號處理:波束形成及目標方位估計,CBF、MVDR
  4. Python信號處理:cvxpy工具包求解稀疏約束優化問題

目錄

  1. 用於對比的三個函數及結論
  2. 非零均值序列的自相關函數
  3. 零均值序列的自相關函數
  4. 消除時滯的影響

1. 用於對比的三個函數及結論

  • numpy.correlate()
  • statsmodels.tsa.api.stattools.acf()
  • MATLAB中的autocorr()

結論:

  1. autocorr(series, 'NumLags', N-1)statsmodels.tsa.api.stattools.acf(series, nlags=N-1)是相同的。[不考慮其他的參數]。
  2. 輸入序列爲0均值時,使用numpy.correlate(series, series, mode='full'),並對計算結果取後一半,得到的結果和前面兩個方法基本相同。
  3. 輸入序列不是0均值時,用numpy.correlate可能是不對的,因爲信號處理下的非正式定義需要零均值條件,算出來的結果也很奇怪。

2. 非零均值序列的自相關函數

選擇輸入序列爲y=[2, 3, 9, 6, 9],N爲5,分別使用上述三種方法得到自相關函數,得到的結果如下:
1.

acf = smt.stattools.acf(y, nlags=N-1)

array([ 1. , 0.06915888, -0.05794393, -0.2271028 , -0.28411215])

acf = np.correlate(y, y, mode='full')
acf = acf[N-1:]
acf = acf / acf[0]

array([1. , 0.66824645, 0.55450237, 0.18483412, 0.08530806])

acf = autocorr(y,'NumLags', N-1);

acf = 1.0000, 0.0692, -0.0579, -0.2271, -0.2841

可以看出,smt.stattools.acf(y, nlags=N-1)autocorr(y,'NumLags', N-1)的結果是一樣的,但np.correlate(y, y, mode='full')的結果差距較大,且所有的相關係數都是正的。

3. 零均值序列的自相關函數

仍使用輸入序列y=[2, 3, 9, 6, 9],N爲5,但對其進行0均值化處理,得到的結果如下:

  1. 和上一節的1.是一樣的
y = y - y.mean()
acf = smt.stattools.acf(y, nlags=N-1)

array([ 1. , 0.06915888, -0.05794393, -0.2271028 , -0.28411215])

  1. 和上一節的2.不同,但變得和1.、3.相同
y = y - y.mean()
acf = np.correlate(y, y, mode='full')
acf = acf[N-1:]
acf = acf / acf[0]

array([ 1. , 0.06915888, -0.05794393, -0.2271028 , -0.28411215])

  1. 和之前的3.是一樣的
y = y - mean(y);
acf = autocorr(y,'NumLags', N-1);

acf = 1.0000, 0.0692, -0.0579, -0.2271, -0.2841

可以看出,對於零均值化的序列,三種方法的結果都是一樣的。

4. 消除時滯的影響

當序列很長時,如下圖,三種方法計算的自相關函數都會隨着時間慢慢減小。在smt.stattools.acf中可以通過unbiased參數進行修正。對於np.correlate,可以用序列長度進行歸一化,同樣能起到消除時滯的效果。根據smt.stattools.acf文檔的描述,兩種做法好像是一樣的。當然MATLAB中肯定也是可以這麼操作的。
在這裏插入圖片描述
對無噪聲的sin序列,分別計算自相關函數,看看時滯的影響,以及消除時滯後的效果。

# 左上,np.correlate,未消除時滯
acf1 = np.correlate(x, x, mode='full')
acf1 = acf1[N-1:]
acf1 = acf1 / acf1[0]
ax[0, 0].plot(t, acf1)

# 右上,np.correlate,消除時滯
acf1 = np.correlate(x, x, mode='full')
acf1 = acf1[N-1:]
acf1 = acf1 / np.arange(N, 0, -1)
acf1 = acf1 / acf1[0]
ax[0, 1].plot(t, acf1)

# 左下,smt.stattools.acf,未消除時滯
acf2 = smt.stattools.acf(x, nlags=N-1, unbiased=False)
ax[1, 0].plot(t, acf2)

# 右下,smt.stattools.acf,消除時滯
acf2 = smt.stattools.acf(x, nlags=N-1, unbiased=True)
ax[1, 1].plot(t, acf2)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章