4. Vjez be - Analiza vremenskog niza

Save this PDF as:
 WORD  PNG  TXT  JPG

Μέγεθος: px
Εμφάνιση ξεκινά από τη σελίδα:

Download "4. Vjez be - Analiza vremenskog niza"

Transcript

1 4. Vjez be - Analiza vremenskog niza Prvo treba pronaći podatke za analizu. Neke od stranica na kojima se mogu naći podaci za vremenske nizove: Preporučljivo je da niz ima barem 100 podataka. Podatke je najlakše urediti u Excelu. Ne idu svi podaci u model, pa jedan dio, na kojem će se promatrati uspješnost predikcije, treba odvojiti. U R ćemo učitavati sve podatke, a onda u R-u odvojiti onaj dio na kojem se izgrađuje model. Ukoliko su podaci po datumima, onda i njih učitavamo. Primjerice, nasdaq podaci su po datumima, ali ne postoje za svaki dan (burza ne radi svaki dan). Prije učitavanja datuma u R, treba promijeniti formatiranje datuma u Excelu i staviti da bude formatiran kao General, a ne kao Date. Tada će datumi biti zapravo cijeli brojevi. Taj cijeli broj predstavlja redni broj dana od koji se uzima kao prvi dan. No, postoji mala komplikacija jer Excel misli da je godina prijestupna. Općenito, pri modeliranju podatke ćemo indeksirati s rednim brojem (1,2, ), ali korisno je imati datume na raspolaganju radi tumačenja kretanja podataka. Primjerice, korisno je znati da je burzovni indeks doživio veliki pad u listopadu Podaci se iz Excela eksportiraju u txt(tab delimited) file iz kojeg se onda učitavaju u R. #UČITAVANJE PODATAKA #Postaviti working directory zatim nasdaqsvipodaci <- read.table("podaci nasdaq.txt", header=true, dec=",") #Ako su podaci iz Excela, vjerojatno koristi decimalni zarez pa to treba naglasiti pri učitavanjau s dec="," str(nasdaqsvipodaci) #provjerimo je li sve učitano kako treba nasdaqsvipodaci$no <- NULL #ovaj stupac nam ne treba, pa ga brišemo tako da mu dodijelimo NULL vrijednost str(nasdaqsvipodaci) #iduća naredba pretvara učitane datume u format Date. Origin kaže odakle brojanje dana počinje. nasdaqsvipodaci$datum <- as.date(nasdaqsvipodaci$datum, origin=" ") str(nasdaqsvipodaci) nasdaqsvipodaci$datum #oblik "yyyy-mm-dd" je standardni način zapisa datuma. #ODVAJANJE PODATAKA ZA MODEL nasdaqmpodaci <- nasdaqsvipodaci[1:335,] nasdaqmpodaci #Može i ovako, ako ne znamo redni broj podatka nasdaqmpodaci <- nasdaqsvipodaci[nasdaqsvipodaci$datum<=" ",] nasdaqmpodaci 1

2 #napravimo ts objekt nasdaqm <- ts(nasdaqmpodaci$nasdaq) nasdaqm Crtanje podataka #CRTANJE PODATAKA #Najjednostavnije u ovisnostu o rednom broju. Različite slike: plot(nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",type = "l", col ="blue") plot(nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks", type="o",col ="blue") plot(nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",col ="blue") points(nasdaqm,col="red",pch=16,cex=0.8) Različiti simboli za crtanje točaka (points) opcija pch #Podatke možemo nacrtati i u ovisnosti o datumu, zato smo i učitavali datum nazivi <- format(nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], format="%m-%y") plot(nasdaqmpodaci$datum, nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",type="l",col ="blue",xaxt="n") points(nasdaqmpodaci$datum, nasdaqm, col="red", pch=16, cex=0.8) axis(1, at=nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], labels=nazivi, las=2) #las parametar: nazivi paralelni(=0) ili okomiti(=2) na os #Možemo staviti i ime mjeseca nazivi <- format(nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], format="%b-%y") 2

3 plot(nasdaqmpodaci$datum, nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",type="l",col ="blue",xaxt="n") points(nasdaqmpodaci$datum, nasdaqm, col="red", pch=16, cex=0.8) axis(1, at=nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], labels=nazivi, las=2) #Možemo staviti i neke od datuma s imenom dana nazivi <- format(nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], format="%a-%b-%y") plot(nasdaqmpodaci$datum, nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",type="l",col ="blue",xaxt="n") points(nasdaqmpodaci$datum, nasdaqm, col="red", pch=16, cex=0.8) axis(1, at=nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], labels=nazivi, las=2) #A možemo staviti i neke od datuma s danom kao brojem nazivi <- format(nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], format="%d-%b-%y") plot(nasdaqmpodaci$datum, nasdaqm, xlab="vrijeme", ylab="nasdaq burzovni indeks",type="l",col ="blue",xaxt="n") points(nasdaqmpodaci$datum, nasdaqm, col="red", pch=16, cex=0.8) axis(1, at=nasdaqmpodaci$datum[seq(1, length(nasdaqmpodaci$datum), length=10)], labels=nazivi, las=2) Formatiranje datuma: Format Značenje %a skraćeno ime dana %A puno ime dana %d dan kao broj %b skraćeno ime mjeseca %B puno ime mjeseca %m mjesec kao broj %y godina bez stoljeća %Y godina (puni broj) Za ostale formate pogledati:?format.posixct Napomena: Slike se jednostavno kopiraju u Word dokument Copy as bitmap/ Paste. 3

4 Početna analiza #POČETNA ANALIZA PODATAKA #osnovne statistike summary(nasdaqm, digits=6) length(nasdaqm) hist(nasdaqm) qqnorm(nasdaqm) Analiza stacionarnosti Već iz samog izgleda grafa vremenskog niza može se naslutiti odgovor na pitanje o stacionarnosti podataka. Općenito, moglo bi se reći da nizovi koji izgledaju kao da imaju trend, nisu stacionarni. No to ne mora biti tako, jer jaka korelacija može uzrokovati prividno postojanje trenda. Dobar uvid u 4

5 stacionarnost može se dobiti izračunavanjem uzoračke autokorelacijske funkcije. Ako autokorelacijska funkcija sporo pada u 0, može se naslutiti nestacionarnost. Ako je blizu 0 već nakon nekoliko koraka, to ukazuje na mogućnost da su podaci stacionarni. Stacionarnost se može analizirati statističkim testovima, a najčešće se koristi Augmented Dickey- Fuller Unit Root test koji testira hipoteze H0: postoji jedinični korijen H1: ne postoji jedinični korijen Postojanje jediničnog korijena povlači da je niz nestacionaran. Međutim, nepostojanje jediničnog korijena ne znači nužno da je niz stacionaran. U tom slučaju možemo samo reći da eventualna nestacionarnost ne proizlazi iz jediničnog korijena karakterističnog polinoma već ima neki drugi uzrok, primjerice nekakav trend. Npr. AR(1) proces s koeficijentom manjim od 1 po apsolutnoj vrijednosti uz dodani linearni trend nema jedinični korijen, ali nije stacionaran. Dakle, ADF test samo odgovara na pitanje ima li smisla dalje diferencirati s ciljem postizanja stacionarnosti. acf(nasdaqm) #acf ukazuje na nestacionarnost #Za provođenje ADF(Augmented Dickey Fuller Unit Root) testa treba instalirati paket funitroots #Nakon što je paket instaliran treba ga loadati na Load package ili s: library(funitroots) adftest(nasdaqm) #Visoka p-vrijednost ukazuje na to da nema dovoljno razloga za odbacivanje H0, pa smatramo da niz nije stacionaran. Diferenciranje: #ELIMINIRANJE NESTACIONARNOSTI DnasdaqM <- diff(nasdaqm) DnasdaqM #opet ts objekt, ali kreće od 2 summary(dnasdaqm) plot(dnasdaqm, xlab="vrijeme", ylab="diferencije NASDAQ burzovnog indeksa",col ="blue") points(dnasdaqm,col="red",pch=16,cex=0.8) acf(dnasdaqm) #ukazuje na stacionarnost #ADF test pokazuje da ne treba dalje diferencirati adftest(dnasdaqm) #Dakle, model koji dalje izgrađujemo bit će (p,1,q) i promatramo diferencirani niz Identifikacija modela Odabrani model je (p,1,q). Kako odrediti p i q? Prvo, promatranjem autokorelacijske funkcije i pokušati uvidjeti sličnost s izgledom teorijskih autokorelacijskih funkcija nekih ARMA modela. 5

6 Autokorelacijska funkcija MA(q) procesa ima karakteristiku da je nakon q koraka jednaka nuli. No, za AR procese to ne vrijedi, nego ACR funkcija opada prema nuli. Iz tog razloga definira se i promatra parcijalna autokorelacijska funkcija (PACF) koja ima svojstvo da je za AR(p) proces nakon p koraka jednaka nuli. Za MA proces PACF opada u 0. Može se reći da se PACF MA procesa ponaša slično kao ACF za AR proces. Opće ponašanje moglo bi se opisati sljedećom tablicom: AR(p) MA(q) ARMA(p,q) ACF opada jednaka 0 nakon q koraka opada PACF jednaka 0 nakon p koraka opada opada #IDENTIFIKACIJA MODELA - određivanje p i q #Analiza ACF funkcije acf(dnasdaqm, main="autokorelacijska funkcija diferenciranog niza NASDAQ") #Primjetno je da već nakon 1 koraka ACF pada u 0. Nakon 3 koraka taj pad je izraženiji. #To dovodi do zaključka da red AR ili MA dijela nije veći od 3. Moguće je i da je red MA dijela q=0, #i da se radi o AR(1) ili AR(2) procesu. pacf(dnasdaqm,ylim=c(-1,1), main="parcijalna autokorelacijska funkcija diferenciranog niza NASDAQ") #Pada u 0 već nakon jednog koraka. Ipak najbliže je 0 nakon 3 koraka, što bi moglo ukazivati da # je red AR dijela jednak 3. ACF i PACF ne daju jasan odgovor, pogotovo kad se radi o ARMA modelu. Tada vrijednosti nikada ne padaju potpuno u 0, pa se ne može odrediti red. Osim toga, radi se o procjenama za ACF i PACF. Stoga se koriste i druge metode. Proširena autokorelacijska funkcija Metoda proširene autokorelacijske funkcije (Extended autocorrelation function EACF) temelji se na činjenici da ako je poznat stupanj AR dijela nekog ARMA procesa, onda uklanjanjem AR dijela dobivamo neki MA(q) proces koji ima dobro svojstvo da ACF nakon q koraka pada u 0. Koeficijenti AR dijela procjenjuju se regresijski. Ilustracija: ARMA(1,1) proces Y t = φy t 1 + Z t + θz t 1 Prvo se napravi jednostavna linearna regresija Y t u ovisnosti o Y t 1 u smislu metode najmanjih kvadrata i dobije se nekonzistentan procjenitelj od φ. Zatim se napravi višestruka regresija Y t u ovisnosti o Y t 1 i o rezidualima prve procjene s korakom 1 unazad. Dobiveni koeficijent φ koji stoji uz Y t 1 konzistentan procjenitelj za φ i proces Y t φ Y t 1 je približno MA(1) proces i to se može identificirati izgledom ACF funkcije. Općenito, za ARMA(p,q) proces procjena koeficijenata se može dobiti uzastopnim regresijama. Naravno, p i q nisu poznati kad se radi o podacima. Neka je W t (k,j) = Yt φ 1 Y t 1 φ k Y t k dobiven nakon iterativne procjene AR koeficijenata uz pretpostavku da je stupanj AR odnosno MA dijela, k odnosno j. Uzoračke autokorelacije procesa W t (k,j) se nazivaju proširene autokorelacijske 6

7 (k,j) funkcije. Ako je k = p i j q, W t je približno MA(q) proces, pa autokorelacije nakon q koraka trebaju biti 0. Ako je k > p dolazi do overfittinga što povećava stupanj MA dijela. EACF metoda za rezultat daje tablicu. Element u k-tom retku i j-tom stupcu ima oznaku X ako je (k,j) autokorelacijska funkcija od W t na koraku j+1 značajno različita od 0. Inače, u tablici stoji vrijednost 0. U takvoj tablici ARMA(p,q) model teoretski bi trebao postojati trokut sastavljen od 0 čiji gornji lijevi vrh odgovara stupnju ARMA procesa. Sljedećom tablicom prikazan je teoretski izgled za ARMA(1,1) model. Gornji lijevi vrh je u (1,1) što ukazuje na to da se radi o ARMA(1,1) modelu. AR/MA x x x x x x x x x x x x x x 1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x Jasno je da na stvarnim podacima tablica neće imati tako pravilan izgled. Primjerice, pogledajmo kako izgleda tablica simuliranog ARMA(1,1) modela s φ = 0.6, θ = 0.3. AR/MA x x o o o o o o o o o o o o 1 x o o o o o o o o o o o o o 2 x x o o o o o o o o o o o o 3 x x o o o o o o o o o o o o 4 o x o o o o o o o o o o o o 5 o x o o o o o o o o o o o o 6 x o o o o o o o o o o o o o 7 x o x o o o o o o o o o o o Gornja tablica sugerira da bi bilo dobro uzeti q=1 i p=1. #EACF #Za EACF metodu potrebno je učitati paket TSA. library(tsa) #Primjer za simulirani ARMA(1,1) model set.seed(99999) eacf(arima.sim(model=list(ar=c(0.6), ma=c(-0.3)),n=100)) #Gornji lijevi kut sugerira red modela #EACF za Nasdaq eacf(dnasdaqm) #Izgled tablice sugerira da bi mogli uzeti modele: ARMA(0,1), ARMA(1,1) #Možemo uzeti u obzir i ARMA(2,2) AR/MA x o o o o o o o o o o o o o 1 x o o o o o o o o o o o o o 2 x x o o o o o o o o o o o o 7

8 3 x x x o o o o o o o o o o o 4 x x x o o o o o o o o o o o 5 x x o x o o o o o o o o o o 6 x x o x x x o o o o o o o o 7 x x x x x x x o o o o o o o EACF predlaže modele: (0,1,1), (1,1,1), (2,1,2) BAYESOV INFORMACIJSKI KRITERIJ - BIC Još jedna važna metoda određivanja reda modela je Bayesov informacijski kriterij ili Schwarz Bayesov informacijski kriterij (BIC, SBIC, SIC nešto drukčije se definiraju). BIC daje numeričku vrijednost na osnovu koje se mogu uspoređivati različiti modeli i pri tome je bolja manja vrijednost. #BIC #Analiza BIC-a pomoću vlastite funkcije najboljibic <- function(armax, d, mamax, podaci) { redar <- c() redd <- c() redma <- c() BICvrijednost <- c() for (i in 0:armax) { for (j in 0:mamax) { fitbic <- trycatch(aic(arima(podaci, order=c(i, d, j)), k=log(length(podaci))), error = function(e) NaN) redar <- append(redar,i) redd <- append(redd, d) redma <- append(redma, j) BICvrijednost <- append(bicvrijednost, fitbic) } } rez <- data.frame(p=redar,d=redd,q=redma,bicvrijednosti=bicvrijednost) rez <- rez[order(rez$bicvrijednosti),] return(rez[1:min(10,length(redar)),]) } najboljibic(5,1,5,nasdaqm) #Ovo gore je isto kao i: najboljibic(5,0,5,dnasdaqm) #Ne treba pretjerivat s redom AR i MA dijela budući metoda procjene ponekad ne konvergira za velike vrijednosti #Izvršavanje može potrajati... > najboljibic(5,1,5,nasdaqm) p d q BICvrijednosti BIC predlaže modele: (0,1,0), (0,1,1), (1,1,0), (2,1,0), (2,1,2) 8

9 Akaike informacijski kriterij - AIC Izračunava se slično kao i BIC te obično ukazuje na isti model kao najbolji. Manja AIC vrijednost je bolja. #AIC najboljiaic <- function(armax, d, mamax, podaci) { redar <- c() redd <- c() redma <- c() AICvrijednost <- c() for (i in 0:armax) { for (j in 0:mamax) { fitaic <- trycatch(aic(arima(podaci, order=c(i, d, j))), error = function(e) NaN) redar <- append(redar,i) redd <- append(redd, d) redma <- append(redma, j) AICvrijednost <- append(aicvrijednost, fitaic) } } rez <- data.frame(p=redar,d=redd,q=redma,aicvrijednosti=aicvrijednost) rez <- rez[order(rez$aicvrijednosti),] return(rez[1:min(10,length(redar)),]) } najboljiaic(5,1,5,nasdaqm) > najboljiaic(5,1,5,nasdaqm) p d q AICvrijednosti AIC predlaže modele: (2,1,2), (2,1,3), (3,1,2), (2,1,4), (3,1,3) Ostali kriteriji Možemo odabrati model koji želimo. Koji god smatramo da bi mogao dobro pristajati podacima, uključimo ga u dodatnu analizu. 9

10 Takvo što će biti korisno pogotovo nakon idućeg koraka dijagnostike. Osnovni princip je overfitting podataka. Primjerice, ako se u nekom slučaju pokaže AR(2) model kao dobar, isprobamo sljedeći bliski, ali općenitiji model AR(3). Polazni AR(2) model će se potvrditi kao bolji ako: Dodani parametar nije značajno različit od 0 (t-test) Parametri iz početnog modela nisu značajno drukčiji u novom Pri tome treba paziti da se model logično proširuje i da se ne proširuje istovremeno i AR i MA dio. Za kraj sumirajmo sve modele koji ulaze u dodatnu analizu. p d q EACF, BIC EACF EACF, BIC,AIC BIC BIC BIC AIC AIC AIC AIC intuicija

11 DIJAGNOSTIKA MODELA U ovom koraku treba kritički analizirati model. Temelji se na analizi reziduala modela. Nakon što se procjene parametri modela promatraju se reziduali dobivene procjene. Po pretpostavkama modela, reziduali bi trebali biti bijeli šum, tj. nekorelirani i jednako distribuirani s očekivanjem 0 i nekom konstantnom varijancom. Osim toga, poželjno je i da su reziduali normalno distribuirani, što je ponekad teško postići. Većina analize, testova i procjene se temelji na pretpostavci da su reziduali normalno distribuirani. Ipak, ako i nisu normalno distribuirani, neki od tih procjenitelja se dobro asimptotski ponašaju, pa ih se može koristiti. Nekoreliranost reziduala može se uočiti promatranjem autokorelacijske funkcije reziduala. Pri crtanju autokorelacijske funkcije, pokazuje se 95%-tni pouzdani interval procjene za velike korake u slučaju bijelog šuma (±1.96/ n). Ako je većina korelacija unutar tog intervala, može se naslutiti da su podaci nekorelirani. Formalniji pristup provjeri nekoreliranosti reziduala je Ljung-Box test. Ljung-Box test testira hipoteze: H0: podaci su nekorelirani H1: podaci nisu nekorelirani Test statistika se definira kao Q = n(n + 2) ρ 1 2 n 1 + ρ 2 2 n ρ 2 K n K Za koju se može pokazati da u uvjetima H0 asimptotski ima χ 2 distribuciju. Nekoreliranost reziduala je nužan uvjet prihvaćanja modela! Ako reziduali nisu nekorelirani za neki model, onda taj model nije valjan i treba tražiti drugi. Stoga, prvo treba redom testirati sve modele i vidjeti koji od njih zadovoljavaju nužan uvjet nekoreliranosti reziduala. Rezultati testa mogu se dobiti R funkcijom tsdiag(). S obzirom da s ovom funkcijom nemamo kontrolu nad brojem stupnjeva slobode test statistike, definiramo vlastitu funkciju LjungBoxPlot koja daje graf p-vrijednosti. Na kolikom koraku gledati koreliranost? Preporuka je do koraka 20. #DIJAGNOSTIKA MODELA ##Idemo redom testirati jesu li reziduali bijeli šum za sve modele koji su uključeni u daljnju analizu. #To činimo funkcijom LjungBoxPlot() koja je dolje definirana. Graf predstavlja p-vrijednosti Ljung Box testa #za sve korake do 20-og. Ako su sve iznad 0.05, prihvaćamo nultu hipotezu da su reziduali nekorelirani. # LjungBoxPlot <- function(redmodela) { pvrij <- c(rep(na,20)) rez <- arima(nasdaqm, order=redmodela)$residuals for (i in (redmodela[1]+redmodela[3]+1):20) { pvrij[i] <- Box.test(rez, lag=i, type = c("ljung-box"), fitdf=redmodela[1]+redmodela[3])$p.value } plot(pvrij,ylim=c(0,1),xlim=c(0,20), main="ljung-box test plot", xlab="lag", ylab="p-vrijednosti testa") abline(h=0.05, col="blue", lty=2) } #Testiranje modela #(0,1,1) LjungBoxPlot(c(0,1,1)) #Prolazi! 11

12 #(1,1,1) LjungBoxPlot(c(1,1,1)) #Prolazi! #(2,1,2) LjungBoxPlot(c(2,1,2)) #Prolazi! #(0,1,0) LjungBoxPlot(c(0,1,0)) ##### NE prolazi! #(1,1,0) LjungBoxPlot(c(1,1,0)) #Prolazi! #(2,1,0) LjungBoxPlot(c(2,1,0)) #Prolazi! #(2,1,3) LjungBoxPlot(c(2,1,3)) #Prolazi! #(3,1,2) LjungBoxPlot(c(3,1,2)) #Prolazi! #(2,1,4) LjungBoxPlot(c(2,1,4)) #Prolazi! #(3,1,3) LjungBoxPlot(c(3,1,3)) #Prolazi! #(4,1,3) LjungBoxPlot(c(4,1,3)) #Prolazi! Odabir najboljeg modela Treba odabrati najbolji model. To možemo učiniti sljedećom funkcijom. #Usporedba modela# #Ovim korakom idemo usporediti sve modele koji zadovoljavaju nužan uvjet nekoreliranosti. #Usporedba ide kroz 5 kriterija: AIC, BIC, Varijanca, broj parametara i normalna distribucija reziduala. #Funkcija analizamodela testira sve moguće modele koji joj se predaju kroz parametar modeli. #Normalna distribucija reziduala je najjači kriterij, a u output tablici se prikazuje kao p-vrijednost # Shapiro-Wilk testa koji testira hipoteze # H0: podaci su normalno distribuirani # H1: podaci nisu normalno distribuirani 12

13 redovimodela <- list(c(0,1,1),c(1,1,1),c(2,1,2),c(1,1,0),c(2,1,0),c(2,1,3),c(3,1,2),c(2,1,4 ),c(3,1,3),c(4,1,3)) analizamodela <- function(podaci, modeli) { AICvrijednosti <- c() BICvrijednosti <- c() varijance <- c() brojparametara <- c() pvrij <- c() rez <- matrix(data=rep(0,5*length(modeli)), nrow=5, ncol=length(modeli)) rownames(rez) <- c("aic","bic","varijanca","broj parametara","p-vrijednost SWtesta") colnames(rez) <- paste("", as.character(modeli)) for (i in 1:length(modeli)) { model <- arima(podaci, order=modeli[[i]]) rez[1,i] <- model$aic rez[2,i] <- AIC(model, k=log(length(podaci))) rez[3,i] <- model$sigma2 rez[4,i] <- length(model$coef) rez[5,i] <- shapiro.test(model$residuals)$p.value } return(rez) } analizamodela(nasdaqm,redovimodela) Ova funkcija daje sljedeći rezultat: c(0, 1, 1) c(1, 1, 1) c(2, 1, 2) c(1, 1, 0) c(2, 1, 0) c(2, 1, 3) c(3, 1, 2) c(2, 1, 4) AIC BIC Varijanca Broj parametara p-vrijednost SWtesta c(3, 1, 3) c(4, 1, 3) AIC BIC Varijanca Broj parametara p-vrijednost SWtesta NAPOMENA: p-vrijednosti SW testa prikazane u gornjem outputu i sljedećim tablicama su zaokružene vrijednosti. Svakako, stvarna vrijednost je mala (<10^(-6)), koja je zbog zaokruživanja nekorektno prikazana kao 0. Svjesni pogreške u prikazu, iz praktičnih razloga nećemo inzistirati na preciznosti. Preporuka kako odabrati najbolji model: Gornje podatke kopirati u Excel i napraviti klasično Data -> Text to columns. Pri tome paziti da se decimalna točka učita kao zarez u Excel. Na taj način se dobije tablica: c(0, 1, 1) c(1, 1, 1) c(2, 1, 2) c(1, 1, 0) c(2, 1, 0) c(2, 1, 3) c(3, 1, 2) c(2, 1, 4) c(3, 1, 3) c(4, 1, 3) AIC 3454, , , , , , , , , ,714 BIC 3462, , , , , , , , , ,227 Varijanca 1795, , , , , , , , , ,969 Broj parametara p-v rijednost SWtesta

14 Sad u toj tablici treba naći najmanje vrijednosti za svaki od kriterija i označiti p-vrijednosti veće od 0.05 koje onda znače da se reziduali za taj model normalno distribuirani. Upute kako to brzo napraviti u Excelu: Koristiti Format -> Conditional formatting i tamo odabrati da se minimalne vrijednosti formatiraju drukčije od ostatka podataka, npr. da pozadina ćelije bude zelena. c(0, 1, 1) c(1, 1, 1) c(2, 1, 2) c(1, 1, 0) c(2, 1, 0) c(2, 1, 3) c(3, 1, 2) c(2, 1, 4) c(3, 1, 3) c(4, 1, 3) AIC 3454, , , , , , , , , ,714 BIC 3462, , , , , , , , , ,227 Varijanca 1795, , , , , , , , , ,969 Broj parametara p-v rijednost SWtesta Tako dobijemo lijep pregled. Sad na osnovu gornje tablice treba odabrati dobar model. Nijedan od modela nema normalno distribuirane reziduale što je loša karakteristika. Ističu se tri kandidata (0,1,1), (2,1,2) i (4,1,3). (0,1,1) je jednostavan i ima dobar BIC ali dosta veliku varijancu u usporedbi s ostalima. (4,1,3) ima malu varijancu, ali uistinu puno parametara. Stoga ćemo odabrati (2,1,2) model koji ima najmanji AIC, mali BIC i malu varijancu. Broj parametara je prihvatljiv. ODABRANI MODEL: (2,1,2) PROCJENA PARAMETARA Procjena se obično vrši funkcijom arima. Pri tome treba biti svjestan nekih ograničenja vezanih uz tu funkciju. Problem 1. Treba razlikovati očekivanje (mean) i slobodni član (intercept). Standardno, ARMA procesi definiraju se kao procesi s očekivanjem 0, stoga u njihovoj općoj formi ne postoji konstantni član. To znači da prije svakog modeliranja nizu treba oduzeti očekivanje. Funkcija arima će to i napraviti ako je include.mean=true (default). Kod modela s autoregresivnim dijelom treba pripaziti jer je parametar u rezultatu nespretno nazvan interceptom. Primjerice pretpostavimo da je x(t) = α + φ*x(t-1) + w(t) stacionaran. Tada je očekivanje, μ, μ = α + φ*μ odnosno μ = α *(1-φ) Dakle, intercept α, nije isto kao mean, μ, osim ako je φ=0. Primjer: #generiramo AR(1) proces i dodamo 50 set.seed(66) x = arima.sim(list(order=c(1,0,0), ar=.9), n=100) + 50 mean(x) arima(x, order = c(1, 0, 0)) 14

15 > mean(x) [1] Coefficients: ar1 intercept s.e Rezultat nije model x(t) = *x(t-1) + w(t) već x(t) =.8971*[x(t-1) ] + w(t) odnosno x(t) = *x(t-1) + w(t). jer je 5.21 = *( ). Općenito pravi intercept se dobije tako da se član koji se dobije u outputu R-a kao intercept pomnoži s AR polinomom od 1: α = μ*(1-φ 1 - φ φ p ) Ako se odabere model za koji je d=0, paziti na to kod zapisivanja modela u obliku formule. Problem 2. Ukoliko se radi o nizu podataka koji se diferencira (d>0) tada funkcija arima ignorira argument include.mean. To je i logično jer diferencirani niz ima očekivanje 0 pa se stoga može direktno modelirati ARMA modelom. Sljedeće naredbe mogu dati različite rezultate arima(x, order = c(1, 1, 0)) #(1) arima(diff(x), order = c(1, 0, 0)) #(2) jer je u (2) po defaultu uključeno oduzimanje aritmetičke sredine od polaznog niza. Ukoliko želimo u model s diferenciranjem uključiti konstantni član, tada se zapravo radit o determinističkom trendu originalnog niza. Primjerice, proces x(t) = α + φ* x(t-1) + w(t). u originalu (prije diferenciranja) je zapravo x(t)= α*t + φ*x(t-1) + w(t) Kad se diferencira onda ostane α jer imamo α*t- α*(t-1). Takav niz zapravo nije stacionaran jer nema konstantno očekivanje. α*t se naziva drift. Ako postoji drift onda diferencirani proces ima intercept (α). Drift je deterministički trend i mora se procjenjivati regresijski. Funkcijom arima to se može napraviti tako da dodamo argument xreg u funkciji arima. xreg zadajemo tako da je xreg=t, odnosno jednak je vremenskom trenutku. Time se regresijski procjenjuje drift. arima(x, order = c(1, 1, 0), xreg=1:length(x)) #(3) Tako napisana funkcija umjesto x(t) modelira x(t)-β*t, odnosno model [x(t) - β*t] = φ* [x(t-1) - β*(t-1)] + w(t) Što kad se pojednostavni daje x(t) = α + φ* x(t-1) + w(t) gdje je α = β*(1-φ) Najjednostavniji način kako dodati drift u model je korištenjem funkcije Arima koja se nalazi u paketu forecast. Arima(x, order=c(1,1,0), include.drift=true) #(4) Dakle, za procjenu parametara koristiti funkciju Arima. 15

16 Zaključak: koristiti proceduru Arima. Ako se niz ne diferencira (d=0) onda će se automatski uključiti intercept. Treba provjeriti je li on značajan, a ako nije izbaciti ga iz modela. Ako se niz diferencira (d=1) onda probati uključiti drift. Ako je značajan, onda ga ostaviti, ako ne onda ga isključiti. Treba li model imati intercept? Samo ako se pokaže značajan! Prvo procijenimo parametre i onda gledamo značajnost pojedinih parametara. S funkcijom confint dobijemo pouzdani interval. Ako pouzdani interval sadrži 0, onda parametar nije značajno različit od nule. #PROCJENA PARAMETARA ## Učitati paket forecast i koristiti Arima library(forecast) #idemo prvu ključiti intercept model <- Arima(nasdaqM, order=c(2,1,2), include.drift=true) model confint(model) #pokazuje se da je intercept nepotreban, budući pouzdani interval sadrži 0, stoga ga izbacujemo #Osim toga pokazuje se da pouzdani interval ma1 koeficijenta sadrži 0. #Uvijek je dobro isprobati više različitih metoda procjene parametara. #U r-u postoje 3: CSS-ML(default), CSS, ML model <- Arima(nasdaqM, order=c(2,1,2)) model model <- Arima(nasdaqM, order=c(2,1,2),method="ml") model model <- Arima(nasdaqM, order=c(2,1,2),method="css") model #Sve tri metode daju približno iste vrijednosti parametara ali CSS daje najmanje standardne devijacije procjene #Stoga ćemo koristiti procjenu dobivenu CSS metodom #To ne mora uvijek biti tako, pa je dobro isprobati više metoda model <- Arima(nasdaqM, order=c(2,1,2),method="css") model confint(model) # Sad u ovom modelu pokazuje se da pouzdani interval ma1 koeficijenta ne sadrži 0. #Svi parametri su značajno različiti od 0 i njihovo uključivanje u model ima smisla. ##########Dakle, konačni model: model <- Arima(nasdaqM, order=c(2,1,2),method="css") model Coefficients: ar1 ar2 ma1 ma s.e Idemo zapisat formulu modela. Općenito, formula je dana s φ(b)(1 B) d Y t = μ + θ(b)z t gdje je φ(z) = 1 φ 1 z φ 2 z 2 φ p z p, 16

17 θ(z) = 1 + θ 1 z + θ 2 z θ q z q. a μ je intercept ako je d=0 odnosno drift ako je d>0 i kao takvi se prikažu u outputu ako su uključeni u model. Za dobivene parametre slijedi da je φ(z) = z z 2, θ(z) = z z 2. Sređivanjem dolazi se do konačnog oblika ( B B 2 )(Y t Y t 1 ) = ( B B 2 )Z t Y t Y t Y t 2 Y t Y t Y t 3 = Z t Z t Z t 2 Y t = Y t Y t Y t 3 + Z t Z t Z t 2 Dodatna analiza reziduala Kad je model odabran mogu se malo detaljnije analizirati reziduali. #ANALIZA REZIDUALA ODABRANOG MODELA str(model) model$residuals tsdiag(model) #prva slika pokazuje kako izgledaju standardizirani reziduali, druga kako izgleda #ACF reziduala, a treća su p-vrijednosti Ljung-Box testa (ovaj prikaz ne uzima korektan red Chi^2 distribucije) #Opet testirati jesu li normalno distribuirani i prikazati ih qqplotom i histogramom #To nije nužan uvjet prihvaćanja modela, ali je jako važan i odlično je ako vrijedi hist(model$residuals,breaks=20) qqnorm(model$residuals) #test normalnosti (Shapiro-Wilk test) #hipoteze testa # H0: podaci su normalno distribuirani # H1: podaci nisu normalno distribuirani shapiro.test(model$residuals) #odbacujemo nultu hipotezi i ovi reziduali nisu normalno distribuirani 17

18 PREDIKCIJA #PREDIKCIJA #Dobiva se naredbom forecast iz paketa forecast forecast(model,h=34) #h određuje koliko koraka unaprijed da predviđa forecast(model,h=34,level=95) #ako stavimo level=95 dobijemo samo 95% interval predikcije #Crtanje predviđanja #najjednostavnije je odmah nacrtati objekt koji vrati funkcija forecast plot(forecast(model,h=34)) #bojom su označeni intervali pouzdanosti #ako želimo vidjeti samo krajnji dio plot(forecast(model,h=34),xlim=c(310,370)) #Predikciju možemo usporediti sa stvarnim budućim vrijednostima koje nismo uključili u model nasdaqsvi <- ts(nasdaqsvipodaci$nasdaq) #sadrži sve vrijednosti nasdaq i pretvorimo je u ts objekt plot(forecast(model,h=34)) points(nasdaqsvi, col="red", pch=16, cex=0.6) #samo krajnji dio plot(forecast(model,h=34),xlim=c(310,370)) points(nasdaqsvi, col="red", pch=16, cex=0.6) #vidimo da je predikcija zapravo dosta loša #Ljepše slike možemo dobiti ako ne koristimo ugrađenu funkciju fitted.arima(model) #daje predviđene vrijednosti za podatke koji su uključeni u model pred <- forecast(model,h=34,level=95) #daje predviđene vrijednosti i interval 95% str(pred) #da vidimo što se nalazi u objektu forecast pred$mean #ovako dobijemo vektor predviđenih vrijednosti pred$lower #gornje i donje granice pred$upper izmodela <- c(fitted.arima(model), pred$mean) modela(predviđene za sve podatke) izmodela #Sve vrijednosti iz #sad idemo crtat plot(nasdaqsvi, type="n", xlab="vrijeme", ylab="nasdaq", main="predikcija NASDAQ-a") #nacrtaj sve podatke(stvarne) ali se ništa ne crta zbog type="n" lines((length(nasdaqm)+1):length(nasdaqsvi),pred$upper, type="l", col="blue", lty=2) #lty je linetype - vrsta linije a može biti 0=blank, 1=solid (default), 2=dashed, 3=dotted, 4=dotdash, 5=longdash, 6=twodash lines((length(nasdaqm)+1):length(nasdaqsvi),pred$lower, type="l", col="blue",lty=2) points(nasdaqsvi, type="p", col="black", pch=16, cex=0.6) points(izmodela, type="p", col="red", pch=16, cex=0.6) legend("top", c("stvarni NASDAQ", "predviđeni NASDAQ", "granice pouzdanog intervala"), cex=0.8, col=c("black","red","blue"), pch=c(16,16,-1), lty=c(0,0,2)) 18

19 #Objašnjenje za legend: #prvi parametar je položaj legende: može biti - "bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right", "center" #drugi parametar su nazivi na legendi vektor naziva #cex je veličina legende #col je vektor boja u legendi #pch je vektor koje znakove nacrtati (-1 ne crta nikakav znak) #lty je vektor koje tipove linija nacrtati u legendi (0 je ništa) #ako želimo samo krajnji dio, prekopiramo sve i stavimo xlim, ali dodat ćemo i veći ylim plot(nasdaqsvi, type="n", xlab="vrijeme", ylab="nasdaq", main="predikcija NASDAQ-a", xlim=c(310,370),ylim=c(1600,2700)) #nacrtaj sve podatke(stvarne) ali se ništa ne crta zbog type="n" lines((length(nasdaqm)+1):length(nasdaqsvi),pred$upper, type="l", col="blue", lty=2) lines((length(nasdaqm)+1):length(nasdaqsvi),pred$lower, type="l", col="blue",lty=2) points(nasdaqsvi, type="p", col="black", pch=16, cex=0.6) points(izmodela, type="p", col="red", pch=16, cex=0.6) legend("top", c("stvarni NASDAQ", "predviđeni NASDAQ", "granice pouzdanog intervala"), cex=0.8, col=c("black","red","blue"), pch=c(16,16,-1), lty=c(0,0,2)) #idemo probat još kompliciraniji graf s datumima nazivi <- format(nasdaqsvipodaci$datum[seq(1, length(nasdaqsvipodaci$datum), length=12)], format="%b-%y") plot(nasdaqsvipodaci$datum, nasdaqsvi, xlab="vrijeme", ylab="nasdaq", main="predikcija NASDAQ-a", xaxt="n", type="n") lines(nasdaqsvipodaci$datum[(length(nasdaqm)+1):length(nasdaqsvi)],pred$upp er, type="l", col="blue", lty=2) lines(nasdaqsvipodaci$datum[(length(nasdaqm)+1):length(nasdaqsvi)],pred$low er, type="l", col="blue",lty=2) points(nasdaqsvipodaci$datum, nasdaqsvi, type="p", col="black", pch=16, cex=0.6) points(nasdaqsvipodaci$datum, izmodela, type="p", col="red", pch=16, cex=0.6) legend("top", c("stvarni NASDAQ", "predviđeni NASDAQ", "granice pouzdanog intervala"), cex=0.8, col=c("black","red","blue"), pch=c(16,16,-1), lty=c(0,0,2)) axis(1, at=nasdaqsvipodaci$datum[seq(1, length(nasdaqsvipodaci$datum), length=12)], labels=nazivi, las=2) #ako želimo prikazati samo kraj, onda možemo stavljati i datume nazivi <- format(nasdaqsvipodaci$datum[seq(1, length(nasdaqsvipodaci$datum), length=50)], format="%d. %b-%y") plot(nasdaqsvipodaci$datum, nasdaqsvi, xlab="vrijeme", ylab="nasdaq", main="predikcija NASDAQ-a", xaxt="n", type="n", xlim=c(nasdaqsvipodaci$datum[310],nasdaqsvipodaci$datum[369]),ylim=c(1600,2 700)) lines(nasdaqsvipodaci$datum[(length(nasdaqm)+1):length(nasdaqsvi)],pred$upp er, type="l", col="blue", lty=2) lines(nasdaqsvipodaci$datum[(length(nasdaqm)+1):length(nasdaqsvi)],pred$low er, type="l", col="blue",lty=2) points(nasdaqsvipodaci$datum, nasdaqsvi, type="p", col="black", pch=16, cex=0.6) points(nasdaqsvipodaci$datum, izmodela, type="p", col="red", pch=16, cex=0.6) 19

20 legend("top", c("stvarni NASDAQ", "predviđeni NASDAQ", "granice pouzdanog intervala"), cex=0.8, col=c("black","red","blue"), pch=c(16,16,-1), lty=c(0,0,2)) axis(1, at=nasdaqsvipodaci$datum[seq(1, length(nasdaqsvipodaci$datum), length=50)], labels=nazivi, las=2) AUTO #AUTO #U paketu forecast postoji funkcija koja cijelo modeliranje napravi sama. #Jednostavno predamo podatke i dobijemo model. No, takvo modeliranje može dovesti do loših modela. #Pogledajmo koja je preporuka za nasdaq podatke auto.arima(nasdaqm) #Predlaže se (1,2,2) model, iako smo ADF testom utvrdili da nema potrebe dvaput diferencirati. #Ova funkcija koristi neki drugi test jediničnog korijena, a ako naglasimo da želimo ADF test onda dobivamo: auto.arima(nasdaqm,test="adf") #koji smo već analizirali i zaključili da je (2,1,2) model bolji. KOINTEGRACIJA Kointegracija je svojstvo koje mogu posjedovati vremenski nizovi. Ako su dva vremenska niza nestacionarna, ali njihova linearna kombinacija je stacionarna, tada kažemo da su dva vremenska niza kointegrirana. Često se označava da niz (Y t ) je I(d), d = 0,1, ako diferenciranjem tog niza d puta dobijemo stacionaran niz. Za dva niza (Y t ) i (Z t ) koja su I(1) kažemo da su kointegrirana (reda 1) ako postoje konstante μ, α 1 0, α 2 0 takve da je proces X t = μ + α 1 Y t + α 2 Z t stacionaran, odnosno I(0). Primjer: neka je X t = X t 1 + W t slučajna šetnja i neka je Y t = X t + W y,t Z t = X t + W z,t gdje su W y,t i W z,t dva nezavisna bijela šuma. Oba niza su nestacionarna, a diferenciranjem postaju stacionarni. Razlika Y t Z t je stacionaran proces. Dakle, linearna kombinacija od Y t i Z t je stacionarna pa su ova dva niza kointegrirana. Kointegracija dva niza može se utvrditi regresijskim procedurama ili različitim testovima primjerice The Engle-Granger two step metoda, Johanssenova procedura, Phillips-Ouliaris kointegracijski test. U ovom slučaju koristit ćemo Phillips-Ouliaris kointegracijski test koji ima hipoteze 20

21 H 0 : nema kointegracije između dva niza H 1 : dva niza su kointegrirana Za testiranje kointegracije treba imati dva niza. Za drugi niz podataka ne treba praviti sve korake analize kao što smo dosad napravili za Nasdaq. Dovoljno je znati samo znati d, tj. nakon koliko diferenciranja je niz stacionaran. Red d za taj niz mora biti jednak kao kod Nasdaq-a, tj. 1. Drugi niz je burzovni indeks NIKKEI. Pokaže se da oba niza postižu stacionarnost jednim diferenciranjem pa možemo pristupiti testiranju kointegriranosti nizova. #KOINTEGRACIJA nikkeisvipodaci <- read.table("podaci nikkei.txt", header=true, dec=",") str(nikkeisvipodaci) nikkeisvipodaci$rdbr <- NULL str(nikkeisvipodaci) nikkeisvipodaci$datum <- as.date(nikkeisvipodaci$datum, origin=" ") str(nikkeisvipodaci) nikkeimpodaci <- nikkeisvipodaci[1:335,] nikkeimpodaci nikkeim <- ts(nikkeimpodaci$nikkei) nikkeim #bitno je da se postiže stacionarnost nakon jednog diferenciranja: library(funitroots) adftest(nikkeim) adftest(diff(nikkeim)) #za kointegracijski Phillips-Ouliaris test potreban je paket tseries library(tseries) po.test(cbind(nasdaqm,nikkeim), demean=false) #Stavljamo demeaned=false ako želimo #testirati kointegraciju uz intercept(u vezu između dva niza je uključen i intercept) #Napravimo linearni model koji opisuje vezu između dva burzovna indeksa veza <- lm(c(nikkeim) ~ c(nasdaqm)) veza veza$residuals adftest(veza$residuals) #Pogledajmo kako izgleda procjena NIKKEI-a na osnovu poznatog NASDAQ-a plot(predict(veza,newdata=data.frame(nasdaqm=c(nasdaqsvi))), type="l", xlab="vrijeme", ylab="nikkei", main="nikkei na osnovu NASDAQA",ylim=c(6000,14000)) points(predict(veza,newdata=data.frame(nasdaqm=c(nasdaqsvi))), col="green", pch=16, cex=0.6) lines(nikkeisvipodaci$nikkei, col="blue") points(nikkeisvipodaci$nikkei, col="red", pch=16, cex=0.6) legend("top", c("stvarni NIKKEI", "NIKKEI na osnovu NASDAQ-a"), cex=0.8, col=c("green","red"), pch=c(16,16), lty=c(0,0)) #samo krajnje vrijednosti 21

22 plot(predict(veza,newdata=data.frame(nasdaqm=c(nasdaqsvi))), type="l", xlab="vrijeme", ylab="nikkei", main="nikkei na osnovu NASDAQA",xlim=c(310,370),ylim=c(8000,13000)) points(predict(veza,newdata=data.frame(nasdaqm=c(nasdaqsvi))), col="green", pch=16, cex=0.6) lines(nikkeisvipodaci$nikkei, col="blue") points(nikkeisvipodaci$nikkei, col="red", pch=16, cex=0.6) legend("top", c("stvarni NIKKEI", "NIKKEI na osnovu NASDAQ-a"), cex=0.8, col=c("green","red"), pch=c(16,16), lty=c(0,0)) 22