ฉันคิดว่ามี 2 สิ่งที่ทำให้หัวข้อนี้สับสน:
- นิยามเชิงสถิติเทียบกับการประมวลผลสัญญาณ: ตามที่คนอื่น ๆ ชี้ให้เห็นในสถิติเราปรับความสัมพันธ์อัตโนมัติให้เป็น [-1,1]
- ค่าเฉลี่ย / ความแปรปรวนบางส่วนและไม่เป็นบางส่วน: เมื่ออนุกรมเวลาเลื่อนที่ความล่าช้า> 0 ขนาดที่ทับซ้อนกันจะ <ความยาวเดิมเสมอ เราใช้ค่าเฉลี่ยและมาตรฐานของค่าเฉลี่ยดั้งเดิม (ไม่ใช่บางส่วน) หรือคำนวณค่าเฉลี่ยและมาตรฐานใหม่เสมอโดยใช้การทับซ้อนที่เปลี่ยนแปลงตลอดเวลา (บางส่วน) ทำให้เกิดความแตกต่าง (อาจมีคำที่เป็นทางการสำหรับคำนี้ แต่ตอนนี้ฉันจะใช้ "บางส่วน")
ฉันได้สร้างฟังก์ชัน 5 ฟังก์ชันที่คำนวณความสัมพันธ์อัตโนมัติของอาร์เรย์ 1d โดยมีความแตกต่างบางส่วนและไม่ใช่บางส่วน บางคนใช้สูตรจากสถิติบางอย่างใช้ความสัมพันธ์ในแง่การประมวลผลสัญญาณซึ่งสามารถทำได้ผ่าน FFT แต่ผลลัพธ์ทั้งหมดเป็นความสัมพันธ์โดยอัตโนมัติในคำจำกัดความของสถิติดังนั้นจึงแสดงให้เห็นว่ามีการเชื่อมโยงถึงกันอย่างไร รหัสด้านล่าง:
import numpy
import matplotlib.pyplot as plt
def autocorr1(x,lags):
'''numpy.corrcoef, partial'''
corr=[1. if l==0 else numpy.corrcoef(x[l:],x[:-l])[0][1] for l in lags]
return numpy.array(corr)
def autocorr2(x,lags):
'''manualy compute, non partial'''
mean=numpy.mean(x)
var=numpy.var(x)
xp=x-mean
corr=[1. if l==0 else numpy.sum(xp[l:]*xp[:-l])/len(x)/var for l in lags]
return numpy.array(corr)
def autocorr3(x,lags):
'''fft, pad 0s, non partial'''
n=len(x)
# pad 0s to 2n-1
ext_size=2*n-1
# nearest power of 2
fsize=2**numpy.ceil(numpy.log2(ext_size)).astype('int')
xp=x-numpy.mean(x)
var=numpy.var(x)
# do fft and ifft
cf=numpy.fft.fft(xp,fsize)
sf=cf.conjugate()*cf
corr=numpy.fft.ifft(sf).real
corr=corr/var/n
return corr[:len(lags)]
def autocorr4(x,lags):
'''fft, don't pad 0s, non partial'''
mean=x.mean()
var=numpy.var(x)
xp=x-mean
cf=numpy.fft.fft(xp)
sf=cf.conjugate()*cf
corr=numpy.fft.ifft(sf).real/var/len(x)
return corr[:len(lags)]
def autocorr5(x,lags):
'''numpy.correlate, non partial'''
mean=x.mean()
var=numpy.var(x)
xp=x-mean
corr=numpy.correlate(xp,xp,'full')[len(x)-1:]/var/len(x)
return corr[:len(lags)]
if __name__=='__main__':
y=[28,28,26,19,16,24,26,24,24,29,29,27,31,26,38,23,13,14,28,19,19,\
17,22,2,4,5,7,8,14,14,23]
y=numpy.array(y).astype('float')
lags=range(15)
fig,ax=plt.subplots()
for funcii, labelii in zip([autocorr1, autocorr2, autocorr3, autocorr4,
autocorr5], ['np.corrcoef, partial', 'manual, non-partial',
'fft, pad 0s, non-partial', 'fft, no padding, non-partial',
'np.correlate, non-partial']):
cii=funcii(y,lags)
print(labelii)
print(cii)
ax.plot(lags,cii,label=labelii)
ax.set_xlabel('lag')
ax.set_ylabel('correlation coefficient')
ax.legend()
plt.show()
นี่คือรูปผลลัพธ์:
เราไม่เห็นทั้ง 5 เส้นเพราะ 3 เส้นซ้อนกัน (ที่สีม่วง) การทับซ้อนเป็นความสัมพันธ์อัตโนมัติที่ไม่ใช่บางส่วน เนื่องจากการคำนวณจากวิธีการประมวลผลสัญญาณ ( np.correlate
, FFT) ไม่คำนวณค่าเฉลี่ย / มาตรฐานที่แตกต่างกันสำหรับการทับซ้อนกัน
โปรดทราบว่าไฟล์ fft, no padding, non-partial
ผลลัพธ์ (เส้นสีแดง) แตกต่างกันเนื่องจากไม่ได้เติมไทม์ซีรีย์ด้วย 0 ก่อนทำ FFT ดังนั้นจึงเป็น FFT แบบวงกลม ฉันไม่สามารถอธิบายรายละเอียดได้ว่าทำไมนั่นคือสิ่งที่ฉันเรียนรู้จากที่อื่น