डेटा के लिए एक साइनसोइडल शब्द को फिट करें


26

हालाँकि मैं इस पोस्ट को पढ़ता हूं , फिर भी मुझे नहीं पता कि इसे अपने डेटा पर कैसे लागू किया जाए और मुझे उम्मीद है कि कोई मेरी मदद कर सकता है।

मेरे पास निम्न डेटा है:

y <- c(11.622967, 12.006081, 11.760928, 12.246830, 12.052126, 12.346154, 12.039262, 12.362163, 12.009269, 11.260743, 10.950483, 10.522091,  9.346292,  7.014578,  6.981853,  7.197708,  7.035624,  6.785289, 7.134426,  8.338514,  8.723832, 10.276473, 10.602792, 11.031908, 11.364901, 11.687638, 11.947783, 12.228909, 11.918379, 12.343574, 12.046851, 12.316508, 12.147746, 12.136446, 11.744371,  8.317413, 8.790837, 10.139807,  7.019035,  7.541484,  7.199672,  9.090377,  7.532161,  8.156842,  9.329572, 9.991522, 10.036448, 10.797905)
t <- 18:65

और अब मैं बस एक साइन लहर फिट करना चाहता हूं

y(टी)=रोंमैंn(ωटी+φ)+सी

चार अज्ञात , , और ।ωφसी

मेरे कोड के बाकी हिस्से निम्नलिखित हैं

res <- nls(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=list(A=1,omega=1,phi=1,C=1))
co <- coef(res)

fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d}

# Plot result
plot(x=t, y=y)
curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue")

लेकिन परिणाम वास्तव में खराब है।

साइन फिट है

मैं किसी भी मदद की बहुत सराहना करूंगा।

चीयर्स।


आप डेटा के लिए एक साइन लहर फिट करने की कोशिश कर रहे हैं या आप साइन और कॉशन घटक के साथ किसी प्रकार के हार्मोनिक मॉडल को फिट करने की कोशिश कर रहे हैं? टीएसए पैकेज में आर में एक हार्मोनिक फ़ंक्शन है जिसे आप जांचना चाहते हैं। अपने मॉडल का उपयोग करके उसे फिट करें और देखें कि आपको किस प्रकार के परिणाम मिलते हैं।
एरिक पीटरसन

5
क्या आपने अलग-अलग शुरुआती मूल्यों की कोशिश की है? आपका नुकसान फ़ंक्शन गैर-उत्तल है, इसलिए विभिन्न शुरुआती मूल्य अलग-अलग समाधानों को जन्म दे सकते हैं।
स्टीफन दांव

1
डेटा के बारे में अधिक बताएं। आमतौर पर एक ज्ञात आवधिकता होती है, इसलिए डेटा से अनुमान लगाने की आवश्यकता नहीं है। क्या यह टाइम सीरीज़ है या कुछ और? यदि आप एक रेखीय मॉडल द्वारा अलग-अलग साइन और कोज़ाइन शब्द फिट कर सकते हैं तो यह बहुत आसान है।
निक कॉक्स

2
एक अज्ञात अवधि होने से आपका मॉडल नॉनलाइनर हो जाता है (ऐसी घटना लिंक की गई पोस्ट पर चयनित उत्तर में बताई गई है)। यह देखते हुए कि, अन्य पैरामीटर सशर्त रूप से रैखिक हैं; कुछ nonlinear LS दिनचर्या के लिए जो जानकारी महत्वपूर्ण है और व्यवहार में सुधार कर सकती है। उस पर अवधि और स्थिति प्राप्त करने के लिए वर्णक्रमीय विधियों का उपयोग करने का एक विकल्प हो सकता है; एक अवधि और अन्य मापदंडों को एक गैर-रैखिक और रैखिक अनुकूलन के माध्यम से क्रमशः पुनरावृत्त फैशन में अद्यतन करना होगा।
Glen_b -Reinstate मोनिका

(मैंने अभी अज्ञात समय के विशेष मामले को बनाने के लिए वहां जो उत्तर दिया है, उसका एक स्पष्ट उदाहरण है कि इसे क्या
अस्पष्ट

जवाबों:


18

यदि आप सिर्फ एक अच्छा का अनुमान चाहते हैं और इसकी मानक त्रुटि की परवाह नहीं करते हैं:ω

ssp <- spectrum(y)  
per <- 1/ssp$freq[ssp$spec==max(ssp$spec)]
reslm <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t))
summary(reslm)

rg <- diff(range(y))
plot(y~t,ylim=c(min(y)-0.1*rg,max(y)+0.1*rg))
lines(fitted(reslm)~t,col=4,lty=2)   # dashed blue line is sin fit

# including 2nd harmonic really improves the fit
reslm2 <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t)+sin(4*pi/per*t)+cos(4*pi/per*t))
summary(reslm2)
lines(fitted(reslm2)~t,col=3)    # solid green line is periodic with second harmonic

साइन प्लॉट

(एक बेहतर फिट अभी भी शायद उस श्रृंखला में आउटलेर के लिए किसी तरह से उनके प्रभाव को कम करेगा।)

---

आप में अनिश्चितता के कुछ विचार चाहते हैं , तो आप प्रोफ़ाइल संभावना (इस्तेमाल कर सकते हैं pdf1 , pdf2 - प्रोफ़ाइल संभावना से लगभग सीआईएस या सत्र हो रही या उसके संस्करण का पता लगाने की मुश्किल नहीं है पर संदर्भ)ω

(वैकल्पिक रूप से, आप इन अनुमानों को nls में फ़ीड कर सकते हैं ... और इसे पहले से ही रूपांतरित कर दें।)


(+1) अच्छा जवाब। मैंने रैखिक मॉडल के साथ फिट होने की कोशिश की lm(y~sin(2*pi*t)+cos(2*pi*t)लेकिन यह काम नहीं किया ( cosशब्द हमेशा 1 था)। जिज्ञासा से बाहर: पहली दो लाइनें क्या करती हैं (मुझे पता है कि spectrumवर्णक्रमीय घनत्व का अनुमान है)?
COOLSerdash

1
@COOLSerdash हाँ, आप की इकाइयां हैं करने के लिए है के लिए अवधि जा रहा है (के रूप में यह जुड़ा हुआ सवाल में था) काम करने के लिए। मुझे वापस जाना चाहिए और अन्य उत्तर में जोर देना चाहिए। (ctd)टी2*pi*t
Glen_b -Reinstate मोनिका

1
@COOLSerdash (ctd) - दूसरी पंक्ति में स्पेक्ट्रम की सबसे बड़ी चोटी से जुड़ी आवृत्ति और अवधि की पहचान करने के लिए अकशेरुकी पाई जाती है। कम से कम इस मामले में (लेकिन मुझे और अधिक व्यापक रूप से संदेह है), इस पर चूक अनिवार्य रूप से उस अवधि की पहचान करती है जो संभावना को अधिकतम रूप से इतनी बारीकी से दर्शाती है कि मैंने उस अवधि के आसपास के क्षेत्र में प्रोफ़ाइल संभावना को अधिकतम करने के लिए मेरे पास मौजूद चरणों को हटा दिया। specTSA में फ़ंक्शन बेहतर हो सकता है (ऐसा लगता है कि अधिक विकल्प हैं, जिनमें से एक कभी-कभी महत्वपूर्ण हो सकता है), लेकिन इस मामले में मुख्य शिखर बिल्कुल उसी स्थान पर था जैसा spectrumकि मैंने परेशान नहीं किया।
Glen_b -Reinstate मोनिका

@Glen_b मेरे उपयोग के मामले के लिए यह विधि अद्भुत काम करती है। मुझे एक कॉस (x) वक्र फिट करने की भी आवश्यकता है, लेकिन यह भी काम नहीं करता है ... मैंने इसे बदल दिया reslmहै reslm <- lm(y ~ cos(2*pi/per*t)+tan(2*pi/per*t))लेकिन यह सही नहीं लगता है। कोई संकेत?
अमित कोहली

आपके पास वहाँ एक तन अवधि क्यों है?
Glen_b -Reinstate मोनिका

15

जैसा कि @Stefan ने सुझाव दिया, विभिन्न शुरुआती मूल्य फिट को नाटकीय रूप से सुधारने के लिए प्रतीत होते हैं। मैंने सुझाव दिया कि ओमेगा के बारे में होना चाहिए , क्योंकि चोटियों को देखकर लगता है कि वे लगभग 20 इकाइयों के अलावा थे।2π/20

जब मैं में है कि डाल nlsकी startसूची, मैं, एक वक्र है कि और अधिक उचित था मिल गया हालांकि यह अभी भी कुछ व्यवस्थित पूर्वाग्रहों है।

इस डेटा सेट के साथ आपका लक्ष्य क्या है, इस पर निर्भर करते हुए, आप आवधिक कर्नेल के साथ अतिरिक्त शब्दों को जोड़कर या गॉसियन प्रक्रिया की तरह एक गैरपारंपरिक दृष्टिकोण का उपयोग करके फिट को बेहतर बनाने का प्रयास कर सकते हैं।

साइन फिट है

स्वचालित रूप से एक प्रारंभिक मूल्य चुनना

यदि आप प्रमुख आवृत्ति को चुनना चाहते हैं, तो आप एक तेज़ फ़ूरियर ट्रांसफॉर्म (FFT) का उपयोग कर सकते हैं। यह मेरी विशेषज्ञता के क्षेत्र से बाहर है, इसलिए मैं अन्य लोगों को विवरणों को भरने दूंगा यदि वे चाहेंगे (विशेषकर चरण 2 और 3 के बारे में), लेकिन Rनीचे दिए गए कोड को काम करना चाहिए।

# Step 1: do the FFT
raw.fft = fft(y)

# Step 2: drop anything past the N/2 - 1th element.
# This has something to do with the Nyquist-shannon limit, I believe
# (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)
truncated.fft = raw.fft[seq(1, length(y)/2 - 1)]

# Step 3: drop the first element. It doesn't contain frequency information.
truncated.fft[1] = 0

# Step 4: the importance of each frequency corresponds to the absolute value of the FFT.
# The 2, pi, and length(y) ensure that omega is on the correct scale relative to t.
# Here, I set omega based on the largest value using which.max().
omega = which.max(abs(truncated.fft)) * 2 * pi / length(y)

आप यह abs(truncated.fft)देखने के लिए भी साजिश कर सकते हैं कि क्या अन्य महत्वपूर्ण आवृत्तियों हैं, लेकिन आपको एक्स-एक्सिस के स्केलिंग के साथ थोड़ा सा फील करना होगा।

इसके अलावा, मेरा मानना ​​है कि @Glen_b सही है कि समस्या एक बार आपको ओमेगा (या शायद आपको फी को भी जानने की जरूरत है? किसी भी स्थिति में, अन्य मापदंडों के लिए शुरुआती मान जानना ओम्गा के लिए उतना महत्वपूर्ण नहीं होना चाहिए, अगर वे सही बॉलपार्क में हों। आप शायद एफएफटी से अन्य मापदंडों के सभ्य अनुमान प्राप्त कर सकते हैं, लेकिन मैं निश्चित नहीं हूं कि यह कैसे काम करेगा।


1
उस संकेत के लिए धन्यवाद। बस थोड़ा स्पष्ट करने के लिए: डेटा एक माइक्रोएरे का एक हिस्सा है जिसमें समय के साथ जीन की आवधिकता को मापा गया था, अर्थात दिखाया गया डेटा एक जीन का अभिव्यक्ति डेटा है। अब समस्या यह है कि मैं इस पद्धति को सभी 40k जीनों के लिए लागू करना चाहता हूं, जिनमें विभिन्न आवधिकताएं और आयाम हैं। इसलिए, यह काफी महत्वपूर्ण है कि एक अच्छा फिट प्रारंभिक स्थितियों से स्वतंत्र पाया जाता है।
पास्कल

1
@ पास्कल ओमेगा के लिए शुरुआती मूल्य को स्वचालित रूप से चुनने के लिए एक सिफारिश के लिए मेरे अपडेट देखें।
डेविड जे। हैरिस

2
ϕa

मुझे आश्चर्य है कि जहां x मान यहां खेलने के लिए आते हैं। निश्चित रूप से यह ओमेगा के लिए एक अंतर बनाता है, क्या दिए गए y मान 1 या 5 x चरणों से अलग होते हैं, है ना?
दस्तक दें

1
प्रोग्रामिंग टिप प्रश्न से संबंधित नहीं है: आर वस्तुओं के नामकरण के दौरान सावधानी foo.bar। यह आर कक्षाओं के लिए तरीकों को निर्दिष्ट करने के तरीके के कारण है ।
फायरबग

10

पहले से ही कहा गया है कि एक विकल्प के रूप में, यह ध्यान देने योग्य हो सकता है कि ARIMA मॉडल के वर्ग से एक एआर (2) मॉडल का उपयोग साइन वेव पैटर्न के साथ पूर्वानुमान उत्पन्न करने के लिए किया जा सकता है।

yटी=सी+φ1yटी-1+φ2yटी-2+टी
सीφ1φ2टी

φ12+4φ2<0।

Panratz (1991) हमें स्टोकेस्टिक चक्रों के बारे में बताता है:

एक स्टोकेस्टिक चक्र पैटर्न को पूर्वानुमान पैटर्न में एक विकृत साइन लहर पैटर्न के बारे में सोचा जा सकता है: यह एक स्टोचस्टिक (संभाव्य) अवधि, आयाम और चरण कोण के साथ एक साइन लहर है।

यह देखने के लिए कि क्या इस तरह के मॉडल auto.arima()को पूर्वानुमानित पैकेज से फ़ंक्शन का उपयोग किया गया है, यह पता लगाने के लिए कि क्या यह एआर (2) मॉडल का सुझाव देगा। यह पता auto.arima()चलता है कि फ़ंक्शन ARMA (2,2) मॉडल का सुझाव देता है; शुद्ध एआर (2) मॉडल नहीं है, लेकिन यह ठीक है। यह ठीक है क्योंकि एक ARMA (2,2) मॉडल में AR (2) घटक होता है, इसलिए एक ही नियम (स्टोचस्टिक चक्र के बारे में) लागू होता है। यही है, हम अभी भी उपरोक्त स्थिति की जांच कर सकते हैं कि साइन लहर पूर्वानुमान का उत्पादन किया जाएगा या नहीं।

परिणाम auto.arima(y)नीचे दिखाए गए हैं।

Series: y 
ARIMA(2,0,2) with non-zero mean 

Coefficients:
         ar1      ar2      ma1     ma2  intercept
      1.7347  -0.8324  -1.2474  0.6918    10.2727
s.e.  0.1078   0.0981   0.1167  0.1911     0.5324

sigma^2 estimated as 0.6756:  log likelihood=-60.14
AIC=132.27   AICc=134.32   BIC=143.5

φ12+4φ2<01.73472+4(-0.8324)<0-0.3202914<0

नीचे दिए गए कथानक मूल श्रृंखला, y, ARMA (2,2) मॉडल के फिट, और 14 आउट-ऑफ-सैंपल पूर्वानुमान दिखाते हैं। जैसा कि देखा जा सकता है, आउट-ऑफ-सैंपल फोरकास्ट साइन-वेव पैटर्न का अनुसरण करता है।

यहाँ छवि विवरण दर्ज करें

दो बातों का ध्यान रखें। 1) यह सिर्फ एक बहुत ही त्वरित विश्लेषण है (एक स्वचालित उपकरण का उपयोग करके) और एक उचित उपचार में बॉक्स-जेनकिंस पद्धति शामिल होगी। 2) ARIMA के पूर्वानुमान अल्पकालिक पूर्वानुमान के हिसाब से अच्छे हैं, इसलिए हो सकता है कि आपको @David J. Harris और @Glen_b द्वारा दिए गए उत्तर में मॉडल से दीर्घकालिक पूर्वानुमान अधिक विश्वसनीय लगें।

अंत में, उम्मीद है कि यह पहले से ही बहुत जानकारीपूर्ण उत्तर के लिए एक अच्छा जोड़ है।

संदर्भ : गतिशील प्रतिगमन मॉडल के साथ पूर्वानुमान: एलन पैंक्रात्ज़, 1991, (जॉन विले एंड संस, न्यूयॉर्क), आईएसबीएन 0-471-61528-5


1

किसी दिए गए डेटा सेट में एक पाप वक्र फिट करने के लिए वर्तमान तरीकों के लिए मापदंडों का पहला अनुमान आवश्यक है, इसके बाद एक अंतःक्रियात्मक प्रक्रिया है। यह एक गैर-रेखीय प्रतिगमन समस्या है। एक अलग विधि में गैर-रेखीय प्रतिगमन को एक सुविधाजनक अभिन्न समीकरण के लिए एक रेखीय प्रतिगमन के लिए धन्यवाद में बदलना शामिल है। फिर, प्रारंभिक अनुमान की कोई आवश्यकता नहीं है और पुनरावृत्ति प्रक्रिया की आवश्यकता नहीं है: फिटिंग सीधे प्राप्त होती है। फ़ंक्शन के मामले में y = a + r * sin (w * x + phi) या y = a + b * sin (w * x) + c * cos (w * x), कागज के पृष्ठ 35-36 देखें स्क्रिप्ड पर प्रकाशित "रेनेसियन साइनसॉइडेल": http://www.scribd.com/JJacquelin/ditions फ़ंक्शन के मामले में y = a + p * x + r * sin (w * x + phi): अध्याय 49-51 के अध्याय "मिश्रित रैखिक और sinusoidal regressions"। अधिक जटिल कार्यों के मामले में, सामान्य प्रक्रिया को "सामान्यीकृत साइनसोइडल प्रतिगमन" पृष्ठ 54-61 के अध्याय में समझाया गया है, इसके बाद एक संख्यात्मक उदाहरण y = r * sin (w * x + phi) + (b / x + c) * ln (x), पेज 62-63


0

यदि आप अपने कोसाइन-लुकिंग डेटा के निम्नतम और उच्चतम बिंदु को जानते हैं, तो आप इस सरल फ़ंक्शन का उपयोग सभी कोसाइन गुणांक की गणना करने के लिए कर सकते हैं:

getMyCosine <- function(lowest_point=c(pi,-1), highest_point=c(0,1)){
  cosine <- list(
    T = pi / abs(highest_point[1] - lowest_point[1]),
    b = - highest_point[1],
    k = (highest_point[2] + lowest_point[2]) / 2,
    A = (highest_point[2] - lowest_point[2]) / 2
  )
  return(cosine)
}

नीचे इसका उपयोग पूरे दिन और सबसे कम घंटे के तापमान और तापमान मानों को दर्ज करके, एक कोसाइन फ़ंक्शन के साथ दिन भर में तापमान की भिन्नता को अनुकरण करने के लिए किया जाता है:

c <- getMyCosine(c(4,10),c(17,25)) 
# lowest temprature at 4:00 (10 degrees), highest at 17:00 (25 degrees)

x = seq(0,23,by=1);  y = c$A*cos(c$T*(x +c$b))+c$k ; 
library(ggplot2);   qplot(x,y,geom="step")

उत्पादन नीचे है: कोसाइन की गणना सबसे कम और उच्चतम बिंदुओं से की जाती है


3
यह दृष्टिकोण शुद्ध साइनसोइडल व्यवहार से किसी भी यादृच्छिक-दिखने वाले प्रस्थान के लिए विशेष रूप से संवेदनशील प्रतीत होगा, जो प्रश्न में सचित्र की तरह लगभग किसी भी डेटासेट के लिए अनुपयुक्त होगा। वैचारिक रूप से, इसका उपयोग इस धागे में सुझाए गए कुछ अन्य पुनरावृत्तियों के लिए शुरुआती मूल्य प्रदान करने के लिए किया जा सकता है।
whuber

सहमत हूँ, यह सबसे सरल है, कुछ मान्यताओं के तहत सरल सन्निकटन के लिए अच्छा होगा
IVIM

0

एक अन्य विकल्प सामान्य समारोह उपयोग कर रहा है optim या NLS। मैंने कोशिश की है कि दोनों में से कोई भी पूरी तरह से मजबूत न हो

निम्नलिखित कार्य y में डेटा लेता है और मापदंडों की गणना करता है।

calc.period <- function(y,t)
{     
   fs <- 1/(t[2]-t[1])
   ssp <- spectrum(y,plot=FALSE )  
   fN <- ssp$freq[which.max(ssp$spec)]
   per <- 1/(fN*fs)
   return(per)
 }

fit.sine<- function(y, t)
{ 
  data <- data.frame(x = as.vector(t), y=as.vector(y))
  min.RSS <- function (data, par){
    with(data, sum((par[1]*sin(2*pi*par[2]*x + par[3])+par[4]-y )^2))
  }  
  amp = sd(data$y)*2.**0.5
  offset = mean(data$y)
  fest <- 1/calc.period(y,t)
  guess = c( amp, fest,  0,   offset)
  #res <- optim(par=guess, fn = min.RSS, data=data ) 
  r<-nls(y~offset+A*sin(2*pi*f*t+phi), 
     start=list(A=amp, f=fest, phi=0, offset=offset))
  res <- list(par=as.vector(r$m$getPars()))
  return(res)
}

 genSine <- function(t, params)
     return( params[1]*sin(2*pi*params[2]*t+ params[3])+params[4])

उपयोग निम्नलिखित है:

t <- seq(0, 10, by = 0.01)
A <- 2 
f <- 1.5
phase <- 0.2432
offset <- -2

y <- A*sin(2*pi*f*t +phase)+offset + rnorm(length(t), mean=0, sd=0.2)

reslm1 <- fit.sine(y = y, t= t)

निम्न कोड डेटा की तुलना करता है

ysin <- genSine(as.vector(t), params=reslm1$par)
ysin.cor <- genSine(as.vector(t), params=c(A, f, phase, offset))

plot(t, y)
lines(t, ysin, col=2)
lines(t, ysin.cor, col=3)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.