[python] दो समय श्रृंखला के बीच छोटे समय का बदलाव का अनुमान लगा रहा है


Answers

आपके द्वारा प्रदान किए गए लिंक में से एक सही विचार है (वास्तव में मैं यहां बहुत कुछ कर रहा हूं)

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import correlate

a,b, N = 0, 10, 1000        #Boundaries, datapoints
shift = -3                  #Shift, note 3/10 of L = b-a

x = np.linspace(a,b,N)
x1 = 1*x + shift
time = np.arange(1-N,N)     #Theoritical definition, time is centered at 0

y1 = sum([np.sin(2*np.pi*i*x/b) for i in range(1,5)])
y2 = sum([np.sin(2*np.pi*i*x1/b) for i in range(1,5)])

#Really only helps with large irregular data, try it
# y1 -= y1.mean()
# y2 -= y2.mean()
# y1 /= y1.std()
# y2 /= y2.std()

cross_correlation = correlate(y1,y2)
shift_calculated = time[cross_correlation.argmax()] *1.0* b/N
y3 = sum([np.sin(2*np.pi*i*(x1-shift_calculated)/b) for i in range(1,5)])
print "Preset shift: ", shift, "\nCalculated shift: ", shift_calculated



plt.plot(x,y1)
plt.plot(x,y2)
plt.plot(x,y3)
plt.legend(("Regular", "Shifted", "Recovered"))
plt.savefig("SO_timeshift.png")
plt.show()

इसमें निम्नलिखित आउटपुट हैं:

Preset shift:  -3
Calculated shift:  -2.99

यह जांचना आवश्यक हो सकता है

  1. सिस्पी सहसंबद्ध
  2. समय देरी गुदा

ध्यान दें कि संबंध का argmax () संरेखण की स्थिति को दर्शाता है, इसे वास्तविक मान प्राप्त करने के लिए ba = 10-0 = 10 और N की लंबाई से छोटा होना चाहिए।

सहसंबद्ध स्रोत के स्रोत की जांच करना यह पूरी तरह से स्पष्ट नहीं है कि सिगटोसल्स के आयातित फ़ंक्शन, बर्ताव करता है। बड़े डेटासेट के लिए परिपत्र सहसंबंध (फास्ट फूरियर ट्रांसफ़ॉर्म्स के माध्यम से) सीधे-आगे की विधि से बहुत तेज है। मुझे संदेह है कि यह सिग्टो में लागू किया गया है, लेकिन मैं निश्चित रूप से यह नहीं बता सकता। मेरे python2.7 फ़ोल्डर में फ़ाइल की खोज के लिए केवल संकलित सी पीड फाइल लौटाई गई।

Question

मेरे पास दो बार श्रृंखला है, और मुझे संदेह है कि उनके बीच एक समय का बदलाव है, और मैं इस समय शिफ्ट का अनुमान करना चाहता हूं।

इस प्रश्न से पहले पूछा गया है: दो (अमानक) तरंगों के बीच चरण अंतर ढूँढें और दो समान तरंगों के बीच समय में बदलाव ढूंढें , लेकिन मेरे मामले में, डेटा के रिजोल्यूशन से समय की कमी छोटा है। उदाहरण के लिए, डेटा प्रति घंटा संकल्प पर उपलब्ध होता है, और समय की पाली केवल कुछ ही मिनटों (छवि देखें) है।

इसका कारण यह है कि एक श्रृंखला को मापने के लिए इस्तेमाल किए जाने वाले डेटाबेस के समय में कुछ मिनटों की पारी होती है।

वहां कोई एल्गोरिदम जो अधिछाया का उपयोग किए बिना, इस बदलाव का अनुमान लगा सकता है?




वास्तव में, दिलचस्प समस्या है, लेकिन अभी तक कोई संतोषजनक उत्तर नहीं है इसे बदलने की कोशिश करते हैं ...

आप कहते हैं कि आप प्रक्षेप का उपयोग नहीं करना चाहते हैं, लेकिन, जैसा कि मैं आपकी टिप्पणी से समझता हूं, वास्तव में आप क्या मतलब यह है कि आप उच्च संकल्प से अपसंपलिंग से बचना चाहते हैं। एक बुनियादी समाधान कम से कम वर्गों का उपयोग रैखिक प्रक्षेप समारोह के साथ फिट होता है, लेकिन उच्च संकल्प के बिना अपवाद के बिना:

import numpy as np
from scipy.interpolate import interp1d
from scipy.optimize import leastsq

def yvals(x):
    return np.sin(x)+np.sin(2*x)+np.sin(3*x)

dx = .1
X = np.arange(0,2*np.pi,dx)
Y = yvals(X)

unknown_shift = np.random.random() * dx
Y_shifted = yvals(X + unknown_shift)

def err_func(p):
    return interp1d(X,Y)(X[1:-1]+p[0]) - Y_shifted[1:-1]

p0 = [0,] # Inital guess of no shift
found_shift = leastsq(err_func,p0)[0][0]

print "Unknown shift: ", unknown_shift
print "Found   shift: ", found_shift

एक नमूना रन काफी सटीक समाधान देता है:

Unknown shift:  0.0695701123582
Found   shift:  0.0696105501967

यदि स्थानांतरित वाई में शोर शामिल है:

Y_shifted += .1*np.random.normal(size=X.shape)

एक कुछ हद तक कम सटीक परिणाम प्राप्त करता है:

Unknown shift:  0.0695701123582
Found   shift:  0.0746643381744

अधिक डेटा उपलब्ध होने पर शोर की उपस्थिति के तहत सटीकता में सुधार होता है, उदाहरण के लिए:

X = np.arange(0,200*np.pi,dx)

एक सामान्य परिणाम यह है:

Unknown shift:  0.0695701123582
Found   shift:  0.0698527939193



सर्वश्रेष्ठ समाधान के लिए ऑप्टिमाइज़ करें

दी गई बाधाओं के लिए, अर्थात् कि समाधान नमूना पद्धति से कम छोटी राशि से चरण-स्थानांतरित होता है, एक सरल डाउनहिल सिम्प्लेक्स एल्गोरिथ्म अच्छी तरह से काम करता है। मैंने यह कैसे दिखाने के लिए @ mgilson की नमूना समस्या को संशोधित किया है I ध्यान दें कि यह समाधान मजबूत है, इसमें शोर को नियंत्रित किया जा सकता है

त्रुटि फ़ंक्शन : ऑप्टिमाइज़ करने के लिए अधिक इष्टतम चीजें हो सकती हैं, लेकिन यह आश्चर्य की बात अच्छी तरह से काम करता है:

np.sqrt((X1-X2+delta_x)**2+(Y1-Y2)**2).sum()

अर्थात्, एक्स-अक्ष (चरण) का समायोजन करके दो घटता के बीच के यूक्लिडियन दूरी को कम करना

import numpy as np

def yvals(x):
    return np.sin(x)+np.sin(2*x)+np.sin(3*x)

dx = .1
unknown_shift = .03 * np.random.random() * dx

X1  = np.arange(0,2*np.pi,dx)  #some X values
X2  = X1 + unknown_shift

Y1 = yvals(X1)
Y2 = yvals(X2) # shifted Y
Y2 += .1*np.random.normal(size=X1.shape)  # now with noise

def err_func(p):
    return np.sqrt((X1-X2+p[0])**2+(Y1-Y2)**2).sum()

from scipy.optimize import fmin

p0 = [0,] # Inital guess of no shift
found_shift = fmin(err_func, p0)[0]

print "Unknown shift: ", unknown_shift
print "Found   shift: ", found_shift
print "Percent error: ", abs((unknown_shift-found_shift)/unknown_shift)

एक नमूना रन देता है:

Optimization terminated successfully.
         Current function value: 4.804268
         Iterations: 6
         Function evaluations: 12
Unknown shift:  0.00134765446268
Found   shift:  0.001375
Percent error:  -0.0202912082305



Links