POST IN VIA DI COSTRUZIONE: LA VIA SI FA NELL’ANDARE! e, con Foerster e, per certi versi, Bruner, la cultura non si comunica ma si costruisce insieme.
Per questo lavoro si ringrazia il dott. David Bettini per aver fornito nel 1996, circa venti anni fa, i dati mensili di piogge e temperature del Volterrano per trenta anni a partire dal 1956
Da aggiungere l’analisi direttamente con Excel per piogge 1956-1961
RIFLESSIONI E CONTI SU PIOGGE E TEMPERATURE MENSILI DAL 1956 AL 1986, CALCOLO E VARIAZIONE DEGLI INDICI CLIMATICI DI BAGNOULS E GAUSSEN COL TEMPO, ATTRAVERSO MEDIE MOBILI, FATTORI STAGIONALI ED ALTRO SULLE SERIE STORICHE a cura del dott. Piero Pistoia
Ecco i ‘conti’ con Excel che sviluppai appunto una ventina d’anni fa:
Sulle cartelle di lavoro di Excel appaiono 7 grafici (N°: 1-2; 3; 4; 7; 8; 9; 11) e 7 fogli di lavoro (N°: 18; 1; 2; 3; 5; 6; 7), alla rinfusa a zibaldone, su cui discuteremo nel seguito.
I seguenti intervalli sono pagine bianche: 10-15; 24-25; 31-32; 38-39; 50-52; 70-75
Intanto il lettore potrà trovare una guida alla ‘lettura’ dei precedenti processi (individuando le formule utilizzate) su altri esempi di statistica, anche con l’uso di Excel, dello stesso autore, per es. nel post “UN PARZIALE PERCORSO DI BASE SULL’ANALISI DI UNA SERIE STORICA REALE…”, uno zibaldone di statistica e linguaggi informatici (la statistica ‘raccontata’ con Excel, con il Basic, il Mathematica di Wolfram e l’R), ecc..
DA CORREGGERE IN DIVENIRE, PERCHE’ L’ARTICOLO SCIENTIFICO ‘RIPULITO’ E’ STATO CONSIDERATO SPESSO DA RICERCATORI AFFIDABILI UNA FRODE!
Intanto cerchiamo di ricavare dal link i dati di pioggia e temperatura in Excel, per memorizzarle in un file .csv, leggibile da R. Iniziamo con i dati di pioggia. Si clicca sul link: PIOGGE_VOLTERRA_1956_1986, riportato sopra.
Appare una console di Excel con riportate varie colonne, nominate sopra; si va al Foglio 1 (7 colonne e un grafico degli Effetti Stagionali) e si isola intanto la seconda colonna che contiene 360 dati mensili della pioggia da 1956 al 1986, eliminando le altre, memorizzandola poi col suffisso .CSV, nel file VOLTERRA_PIOGGE_1956_1986_A (ricordarsi in quale Memoria di Massa), con le seguenti opzioni: Si mantenga il formato corrente – Tipo di carattere occidentale – Separatore di campo la “virgola”.
Si entra nella console di R e si guarda se il processo funziona.
setwd(“X:/”)
in X va la lettera della memoria di massa; nel nostro caso setwd(“I:/”) o ultimamente G-
Si fanno tentativi per far leggere da R i dati con suffisso .xls
Altri scritti e argomentazioni seguiranno successivamente
ECCO UN PRIMO ‘ASSAGGIO’ ORGANIZZATO DEL RACCONTARE L’ARTICOLARSI DEL CONTENUTO DEL LINK IN XLS CON IL LINGUAGGIO DI R, INIZIANDO IN PARTICOLARE DALLA COLONNA DUE CHE CONTIENE I DATI .
In definitiva tenterò di raccontare una storia statistico-informatica usando un linguaggio informatico alternativo; i diversi trucchi informatici con i loro risvolti logico-razionali necessari aumenteranno la possibilità di tentare veloci prove diversificate, attivando una maggiore concentrazione sui concetti statistici, visti da punti di vista diversi, insieme alla loro memorizzazione e alla loro assimilazione, oltre ad un intenso ammaestramento informatico.
Come in un gioco di puzzle a più vie, si attivano costruzioni con i ‘mattoni’ statistici a più possibilità e si costruiscono gli stessi concetti statistici con ‘mattoni’ informatici diversi logicamente, individuando percorsi diversi e il percorso spesso diventa una facility per l’apprendimento.
SCRIPTS IN R E COMMENTI
setwd(“I:/”) dataset=read.csv(“PIOGVOLTR0.CSV”, header=T, dec=”.”, sep=”;”). La lettera ‘0’ è uno zero!
#Da tener d’occhio l’attributo dec=”.” dell’argomento !?
#COME SI COSTRUISCE IL FILE PIOGVOLTR0.CSV a partire da foglio 1 di Excel:
# 1 – Dal post “CONTROLLA IL CONTO…” si carica, cliccando sul link #”PIOGGE_VOLTERRA 1956_1986″, l’analisi in .xls su questi dati di cui parla il post # e questo al fine di costruire dal foglio 1 un data frame leggibile da R.
# 2 – E’ un foglio di Excel, ma siamo in Open Office; mi pongo sul foglio 1 # (siglato anche col nome del link)
# 3 . Cambio le intestazioni originali e le sostituisco col nome di variabili neutre #X.1 X.2 …X.7 per le sette colonne del foglio; ne chiariremo nel proseguio #il contenuto.
# 4 – Salvo questo foglio in xls con l’opzione di Open Office “Testo CSV(.csv)” # nel file, in questo caso, PIOGVOLTR0 che ricaricheremo con R; ognuno #può chiamarlo col nome che vuole e memorizzarlo sul disco che vuole, basta #ricordasi il nome; noi abbiamo chiamato il file come detto e lo memoriziamo in # un disco rimovibile indicato con I o G. Durante la memorizzazione rispondiamo #alle domande, separatore di campo “;” , separatore di testo Apice ‘ ecc.
# 5 – Si copi il presente testo sulla console di R e controlla che giri; il nostro gira! Per un po’!! Vedere nel proseguo dell’argomentazione.
Oppure, per preparare i racconti successivi, si memorizzano tutte le sette colonne (cioè l’intera pagina di excel), ponendo al posto delle intestazioni che figuravano nella pagina, le seguenti sette una per colonna: X.1,X.2….X.7, alla testa di esse.
PREMESSA E DESCRIZIONE DEL PROCESSO
ECCO IL NOSTRO PROGETTO IPOTETICO CON OUTPUTS
attach(dataset) X.1
Dovrebbe apparire la prima colonna
Dovrebbero apparire i 6 valori iniziali del dataset
head(dataset)
X.2[1:6]
In effetti appaiono tre NA iniziali prima dei valori del 1956; per il resto Ok; con
X.2[4:375], si pensa di correggere; appaiono i 372 valori effettivi delle piogge misurate! La corroborazione dell’ipotesi sembrava abbastanza scontata. Il dataframe col processo descritto portava, nominando la seconda variabile di colonna, ai dati da analizzare! Il processo aveva funzionato.
Invece da qui la sorpresa non prevista. Se cerco di memorizzare X.2[4-375] in una variabile (es.,dataset2 ), cioè
dataset2=X.2[4:375] e guardo i dati in essa (battendo dataset2 sulla console di R) i contenuti sono stranamente completamente cambiati! ts.plot(dataset2) dà un grafico che sembra non riguardare più la nostra prova, comunque continuiamo la loro analisi per cercare anche di capire. Il processo comunque è un modello abbastanza trasferibile ad altri insieme di dati! Poi con calma cercheremo di entrare in possesso di questi dati reali in qualche modo, al limite copiandoli direttamente in un vettore di R. Insomma nel trasferimento del contenuto conosciuto di una variabile ad un’altra….entriamo in una zona caotica imprevista, almeno per ora. VEDREMO poi!
Da una revisione sui processi nella sintassi del richiamo del file in .CSV, fra gli altri attributi, c’era dec (separatore dei decimali) =; qui fra virgolette avevo inserito il punto. Dovevamo dire che invece c’era la virgola: dec=”,”. Ora il programma gira. Col punto il programma pensava che le scritte dei numeri decimali fossero testo, attivando le funzioni factor e level.
ECCO IL RIQUADRO DELLA CAUSA
I am sorry. Troppe direttrici culturali, aperte e diverse fra loro, da ordinare, creano una situazione entropica densa e dispersiva che, coniugata al tempo che ora scorre rapido ed ai problemi sempre più numerosi in quest’ultimo scorcio della vita, aumentano una richiesta di concentrazione poco spiegabile per un lavoro semplicemente hobbistico, in totale assenza di contributi, che vengono invece elargiti, per la cultura, da organi sociali; per passare il tempo insomma! Vedrò.
Comunque , ‘si parva licet componere magnis’ (Virgilio ‘Georgiche, IV), ritengo che un apporto culturale che non si esaurisca in ‘racconti e descrizioni’, ma proceda con punti interrogativi, caso proprio di questo blog, non sia inferiore a quello dei molti centri attivi benificiati da contributi, ed anche mi sembra che le stesse ‘lectiones magistrales’ dei gruppi di eccellenza, che si susseguono nei palchi, spesso, nel migliore dei casi, si ‘spengano’ in se stesse, comunicando poco, e, negli altri casi si riducano ad escamotages pubblicitari per ottenere finanziamenti.
In attesa …per i lettori curiosi, se ci sono, ho intanto ricopiato direttamente in un vettore di R i 372 dati delle piogge mensili, su cui sarà possibile accedere, nell’immediato, alla loro analisi, ‘divertendosi’ nel controllare conti e processi, cioè nel fare cultura.
Comunque lo sviluppo a partire da questo vettore verrà inserito in links successivi. Al termine aggiungeremo anche l’outputs senza errori come garanzia del lavoro
Seguono i 5 grafici del link precedente a quello sopra, costruiti nell’ OUTPUT relativo. Dovremo aggiungere anche altri tre grafici relativi all’output del nuovo ultimo links.
Nella serie dataset ipotizziamo che sia assente un trend, come suggerito dal GRAF.1
I links successivi riguarderanno la Stagionalità, Fattori stagionali, Effetti stagionali.
_______________________________________________
Prove statistiche e tentativi su ipotesi al fine di costruire un modello trasferibile.
#Ipotizzo che con una media mobile a tre termini pesata, #possa eliminare in buona parte i randoms da questa strana #serie dataset2 (già senza il trend come dal grafico).
yt2=dataset2; n2=length(yt2); mbt2=c() for(t in 2: n2-1){mbt2[t]=(yt2[t-1]+2*yt2[t]+yt2[t+1])/4} ts.plot(mbt2)
#Ho smussato dall’originale (dataset2 )i randoms per cui avrei ottenuto #una serie senza i randoms (con plausibili stagionalità+ciclo; assente il trend #iniziale come si vedeva ad occhio dal grafico di dataset2. #Così se applico una media mobile di ordine dodici a mbt2 (primo caso), mi aspetto di trovare una serie con solo il ciclo. #Potevo applicare la media mobile 12 direttamente su dataset2, smussandola #di stagionalità e forse anche di randoms, e poi, togliendo #la stagionalità+ randoms (questa nuova serie) da dataset2 avrei ottenuto solo # il ciclo, perché all’inizio non possedeva trend . #Protocollo sperimentale per il modello: da confrontare questi due processi che dovrebbero condurre ambedue al ciclo.
#Questa serie con solo il ciclo la chiamo mbt2_12.
#PROVIAMO IL CASO 1: yt=mbt2; n1=length(mbt2)-2; mbt2_12=c() for(t in 7: n1-6){mbt2_12[t]=(yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+ yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+yt[t+6]/2)/12}
#CICLO; è la serie mbt2 smussata della stagionalità #se tolgo stagionalità + ciclo – ciclo, mbt2-mbt2_12, ottengo la stagionalità.
#Stiamo pensando anche di scrivere direttamente i 372 valori
#della di X.2[4:375], nella variabile dataset2 con
#dataset2=c(………)
LA VERSIONE CORRETTA + I RELATIVI CINQUE GRAFICsetwd(“F:/”)
dataset=read.csv("PIOGVOLTR0.CSV", header=T, dec=",", sep=";")
#Da osservare l'attributo dec=","! nell'argomento della funzione "read.csv".
#COME SI COSTRUISCE IL FILE PIOGVONTR.CSV a partire da foglio 1 di Excel.
par(ask=T)
attach(dataset)
X.1
#Stampa i 372 dati della 1a colonna delle 7 colonne del DATA.FRAME
#contenuto nel file PIOGVOLTR0.CSV (indicazione degli anni a partire dal 1956
#intervallati da NA head(dataset) # X.1 X.2 X.3 X.4 X.5 X.6 X.7
#1 1956 89,2 -3,3 70,62580645 #2 NA 32 2,0 73,94193548 #3 NA 68 10,2 83,02258065
#4 NA 106 -2,0 72,30322581 #5 NA 39,8 -9,6 62,67741935 #6 NA 69,4 -21,0 52,52903226
#Stampa i valori delle prime sei righe del data.frame, costituito da
#sette colonne.
X.2[4:375]
#Stampa i 372 dati della 2a colonna in mm di pioggia mensili
#partendo dall'anno 1956 con gennaio
X.2[1:6]
#Stampa i primi sei valori della seconda colonna
#[1] 89,2 32 68 106 39,8 69,4
dataset=ts(dataset)
#considera il data.frame dataset come una serie storica dataset2=X.2[1:372]
#prende 1 valori da 1 a 372 del vettore X.2 e li mette
#nella variabile dataset2
dataset2=ts(dataset2)
#dataset2 è una serie storica ts.plot(dataset2)
#GRAF.1 #Stampa la serie storica dataset2; sembra assente il trend. yt2=dataset2; n2=length(yt2); mbt2=c()
for(t in 2: n2-1){mbt2[t]=(yt2[t-1]+2*yt2[t]+yt2[t+1])/4}
ts.plot(mbt2)
# GRAF.2
#disegno il grafico di mbt2, GRAF.2, cioè i dati originali (senza trend)
#privati anche dei random s.l.
GRAF.2
#Penso di smussare cioè dataset2 dai randoms s.l.; nel vettore mbt2 è plausibile
#siano contenuti dati relativi a stagionalità e ciclo.
#Ho smussato dall'originale (dataset2 )i randoms s.l. per cui avrei ottenuto
#una serie senza i randoms (con plausibili stagionalità+ciclo); assente il trend
#iniziale come si vedeva ad occhio dal grafico di dataset2.
#Così se applico una media mobile di ordine dodici a mbt2 mi aspetto di trovare
#una serie con solo il ciclo (PRIMO CASO).
#Potevo applicare la media mobile 12 direttamente su dataset2 (SECONDO CASO),
#smussandola dalla stagionalità e forse anche dai randoms (?), e poi, togliendo
#la stagionalità + randoms (questa nuova serie) da dataset2 avrei ottenuto solo
# il ciclo.
#Da confrontare questi due processi che dovrebbero condurre ambedue al ciclo.
#Questa seconda serie con solo il ciclo la chiamo mbt2_12.
#PROVIAMO IL PRIMO CASO (applico una media modile 12 su mbt2:
yt=mbt2; n1=length(mbt2)-2; mbt2_12=c()
for(t in 7: n1-6){mbt2_12[t]=(yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+ yt[t-1]+
yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+yt[t+6]/2)/12}
ts.plot(mbt2_12)
#GRAF.3 Disegno il grafico del ciclo
#GRAF.3
ts.plot(mbt2) # + CICLO1 sovrapposto.
#Disegno il grafico di mbt2 (stagionalità + ciclo) e sovrappongo mbt2_12 (ciclo):
lines(mbt2_12)
#è la serie mbt2 smussata della stagionalità
#Insieme al grafico mbt2 (stagionalità+ciclo) sovrappongo il ciclo: GRAF.4 #Se tolgo il ciclo da stagionalità + ciclo (mbt2), ottengo mbt2-mbt2_12,
#cioè la stagionalità.
#Sorge il problema che mbt2 e mbt2_12 debbono avere la stessa lunghezza
#per poterli sottrarre
#FACCIO DELLE PROVE PER RENDERE I VETTORI LUNGHI UGUALE
#Controllo mbt2
length(mbt2) # 371 = 12
head(mbt2) # NA 1.00 70.75 177.50 202.75 159.00
mbt2=mbt2[2:(length(mbt2)-1)]
#Controllo mbt2_12
length(mbt2_12) # 363
head(mbt2_12)
# NA NA NA NA NA NA
#Impongo che mbt2 e mbt2_12 abbiano la stessa lunghezza per sottrarli
mbt2_12=mbt2_12[7: (length(mbt2_12)-6)]
length(mbt2_12)
#Proviamo il SECONDO CASO (applico direttamente la Mb12 su dataset2)
#per il calcolo del ciclo
yt=dataset2; n1=length(dataset2); mbt2_12_0=c()
for(t in 7: n1-6){mbt2_12_0[t]=(yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+ yt[t-1]+
yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+yt[t+6]/2)/12}
ts.plot(mbt2_12_0)
#Disegno il grafico del ciclo nel secondo modo: GRAF.5 #Da confrontare i due grafici del ciclo mbt2_12_0 e mbt2_12.
#I due cicli praticamente coincidono. Ma nel secondo sono rimasti
#più errori randoms (?), nel senso che la Mb12 sugli originali
#praticamente elimina da essi solo la stagionalità. Per cui
#nella serie nuova rimarrà ciclo+randoms e se sottraggo
#Ciclo+Randoms dall'originale (dataset2) otterrei
#direttamente la Stagionalità. #Potremmo fare un test statistico per controllo.
#CALCOLO DELLA STAGIONALITA' nel proseguo (SECONDA PARTE)
___________________________________________ OUTPUTS di R
> rm(list=ls(all=TRUE))
> setwd("F:/")
> dataset=read.csv("PIOGVOLTR0.CSV", header=T, dec=",", sep=";")
>#COME SI COSTRUISCE IL FILE PIOGVONTR.CSV a partire da foglio 1 di Excel
> par(ask=T)
> attach(dataset)
>#The following objects are masked from dataset (pos = 3):
>X.1, X.2, X.3, X.4, X.5, X.6, X.7
> X.1
[1] NA NA NA 1956 NA NA NA NA NA NA NA NA NA NA NA
[16] 1957 NA NA NA NA NA NA NA NA NA NA NA 1958 NA NA
[31] NA NA NA NA NA NA NA NA NA 1959 NA NA NA NA NA
[46] NA NA NA NA NA NA 1960 NA NA NA NA NA NA NA NA
[61] NA NA NA 1961 NA NA NA NA NA NA NA NA NA NA NA
[76] 1962 NA NA NA NA NA NA NA NA NA NA NA 1963 NA NA
[91] NA NA NA NA NA NA NA NA NA 1964 NA NA NA NA NA
[106] NA NA NA NA NA NA 1965 NA NA NA NA NA NA NA NA
[121] NA NA NA 1966 NA NA NA NA NA NA NA NA NA NA NA
[136] 1967 NA NA NA NA NA NA NA NA NA NA NA 1968 NA NA
[151] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[166] NA NA NA NA NA NA 1970 NA NA NA NA NA NA NA NA
[181] NA NA NA 1971 NA NA NA NA NA NA NA NA NA NA NA
[196] 1972 NA NA NA NA NA NA NA NA NA NA NA 1973 NA NA
[211] NA NA NA NA NA NA NA NA NA 1974 NA NA NA NA NA
[226] NA NA NA NA NA NA 1975 NA NA NA NA NA NA NA NA
[241] NA NA NA 1976 NA NA NA NA NA NA NA NA NA NA NA
[256] 1977 NA NA NA NA NA NA NA NA NA NA NA 1978 NA NA
[271] NA NA NA NA NA NA NA NA NA 1979 NA NA NA NA NA
[286] NA NA NA NA NA NA 1980 NA NA NA NA NA NA NA NA
[301] NA NA NA 1981 NA NA NA NA NA NA NA NA NA NA NA
[316] 1982 NA NA NA NA NA NA NA NA NA NA NA 1983 NA NA
[331] NA NA NA NA NA NA NA NA NA 1984 NA NA NA NA NA
[346] NA NA NA NA NA NA 1985 NA NA NA NA NA NA NA NA
[361] NA NA NA 1986 NA NA NA NA NA NA NA NA NA NA NA
> #Stampa i 372 dati della 1a colonna delle 7 colonne del DATA.FRAME
> #contenuto nel file PIOGVOLTR0.CSV (indicazione degli anni a partire dal 1956
> #intervallati da NA
> head(dataset) X.1 X.2 X.3 X.4 X.5 X.6 X.7
1 NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA
4 1956 89.2 NA NA NA -3.3 70.62581
5 NA 32.0 NA NA NA 2.0 73.94194
6 NA 68.0 NA NA NA 10.2 83.02258
> # X.1 X.2 X.3 X.4 X.5 X.6 X.7
> #1 1956 89,2 -3,3 70,62580645
> #2 NA 32 2,0 73,94193548 >
>#3 NA 68 10,2 83,02258065
> #4 NA 106 -2,0 72,30322581
> #5 NA 39,8 -9,6 62,67741935
> #6 NA 69,4 -21,0 52,52903226
> #Stampa i valori delle prime sei righe del data.frame, costituito da
> #sette colonne.
> X.2[4:375]
[1] 89.2 32.0 68.0 106.0 39.8 69.4 33.4 25.2 64.4 41.4 123.8 34.4
[13] 66.8 100.2 17.0 109.8 159.8 23.6 27.0 5.6 2.4 74.2 100.8 79.0
[25] 47.4 27.0 133.0 108.8 36.0 30.6 22.0 21.0 12.8 163.8 67.0 134.4
[37] 61.2 35.6 133.2 69.2 120.8 25.4 4.6 46.0 46.2 74.6 73.4 149.2
[49] 57.8 112.8 113.4 62.0 9.6 91.4 64.6 5.2 179.6 214.6 132.2 210.2
[61] 107.8 30.0 0.6 152.8 37.6 73.0 18.4 1.5 87.6 160.4 135.8 86.4
[73] 50.4 46.6 139.6 35.6 35.6 21.6 37.6 50.0 64.8 161.6 196.8 35.4
[85] 147.6 89.4 75.3 74.2 45.8 89.2 28.8 38.8 94.6 95.2 100.4 88.8
[97] 4.6 77.6 157.6 58.8 49.6 32.2 84.0 69.5 34.0 193.0 78.0 118.4
[109] 127.8 16.8 91.0 107.4 50.4 36.0 80.0 24.8 119.8 2.6 240.2 104.8
[121] 97.8 88.4 28.4 28.4 36.2 28.6 67.2 52.2 122.8 173.4 259.0 59.6
[133] 49.2 42.2 56.4 11.4 84.2 83.6 19.4 75.8 99.2 42.8 99.8 62.6
[145] 57.0 149.8 29.8 49.0 156.0 91.4 28.0 65.8 35.6 75.0 148.2 68.0
[157] 89.0 156.2 85.8 40.0 56.6 43.4 38.4 83.8 128.6 26.4 157.2 106.4
[169] 104.8 98.2 140.6 79.6 66.6 63.8 18.6 22.4 75.0 28.2 106.4 95.0
[181] 81.0 51.4 55.0 53.0 122.4 67.2 15.8 2.2 54.8 17.4 149.0 8.6
[193] 85.4 91.8 43.0 106.8 51.4 26.0 71.0 49.0 136.6 76.0 46.8 67.2
[205] 70.8 33.0 13.0 48.2 17.2 56.2 38.8 22.6 171.0 80.0 73.2 30.6
[217] 35.4 105.2 66.0 80.6 52.8 27.2 12.6 61.4 88.8 87.6 64.2 16.6
[229] 16.2 39.6 101.6 92.2 47.6 74.4 11.4 92.8 51.2 125.2 103.8 102.2
[241] 12.4 55.0 92.8 75.8 28.6 32.6 86.0 94.4 110.8 154.6 69.4 175.4
[253] 61.2 108.0 54.0 15.0 101.0 12.0 29.4 100.2 33.2 31.4 65.4 60.4
[265] 102.2 96.6 68.0 172.2 66.8 67.0 87.6 23.2 18.6 88.0 38.8 103.0
[277] 127.4 75.8 50.8 84.8 1.4 80.0 9.4 131.4 84.8 110.4 126.6 108.0
[289] 50.2 20.4 125.8 34.0 102.6 66.6 22.8 13.0 1.0 142.4 182.2 79.8
[301] 64.2 25.6 85.2 74.4 31.4 13.4 45.0 15.8 99.8 172.2 1.6 152.2
[313] 33.0 40.8 64.2 23.2 55.6 34.4 3.4 59.4 70.4 142.6 210.4 100.0
[325] 23.0 199.6 128.0 65.6 22.8 34.2 8.0 192.0 12.4 73.2 17.6 37.0
[337] 72.4 65.6 83.8 91.4 161.0 87.2 3.3 131.4 91.0 139.6 142.8 86.0
[349] 93.8 67.6 147.2 9.2 94.4 25.0 15.0 72.2 0.4 58.0 117.8 32.6
[361] 102.4 113.4 125.6 122.0 1.4 121.8 70.0 7.4 26.8 13.0 63.6 53.2
> #Stampa i 372 dati della 2a colonna in mm di pioggia mensili > #partendo dall'anno 1956 con gennaio (i dati del data.frame > #partivano da tre mesi prima (da ottobre 1955) > > X.2[1:6] [1] NA NA NA 89.2 32.0 68.0 > #Stampa i primi sei valori della seconda colonna > #[1] 89,2 32 68 106 39,8 69,4 > X.2=as.number(X.2) Errore: non trovo la funzione "as.number" > > dataset=ts(dataset) > #considera il data.frame dataset come una serie storica > > dataset2=X.2[1:372] > #prende 1 valori da 1 a 372 del vettore X.2 e li mette > #nella variabile dataset2 > > dataset2=ts(dataset2) > #dataset2 è una serie storica > > ts.plot(dataset2) #GRAF.1 Aspetto per confermare cambio pagina... > #Stampa la serie storica dataset2; sembra assente il trend. > yt2=dataset2; n2=length(yt2); mbt2=c()
> for(t in 2: n2-1){mbt2[t]=(yt2[t-1]+2*yt2[t]+yt2[t+1])/4} > > ts.plot(mbt2)# GRAF.2 Aspetto per confermare cambio pagina... > #disegno il grafico di mbt2, cioè i dati originali (senza trend) > #privati anche dei random s.l. > #Penso di smussare cioè dataset2 dai randoms s.l.; nel vettore mbt2 è plausibile > #siano contenuti dati relativi a stagionalità e ciclo. > #Ho smussato dall'originale (dataset2 )i randoms s.l. per cui avrei ottenuto > #una serie senza i randoms (con plausibili stagionalità+ciclo; assente il trend > #iniziale come si vedeva ad occhio dal grafico di dataset2. > #Così se applico una media mobile di ordine dodici a mbt2 mi aspetto di trovare > #una serie con solo il ciclo (PRIMO CASO). > > #Potevo applicare la media mobile 12 direttamente su dataset2 (SECONDO CASO), > #smussandola dalla stagionalità e forse anche dai randoms, e poi, togliendo > #la stagionalità + randoms (questa nuova serie) da dataset2 avrei ottenuto solo > # il ciclo. > #Da confrontare questi due processi che dovrebbero condurre ambedue al ciclo. > > #Questa serie con solo il ciclo la chiamo mbt2_12. > > #PROVIAMO IL PRIMO CASO (applico una media modile 12 su mbt2: > yt=mbt2; n1=length(mbt2)-2; mbt2_12=c() > for(t in 7: n1-6){mbt2_12[t]=(yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+ + yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+yt[t+6]/2)/12} > > ts.plot(mbt2_12)#GRAF.3 Aspetto per confermare cambio pagina... > Disegno il grafico del ciclo Errore: unexpected symbol in "Disegno il" > ts.plot(mbt2) Aspetto per confermare cambio pagina... > #Disegno il grafico di mbt2 (stagionalità + ciclo) e sovrappongo mbt2_12 (ciclo): > lines(mbt2_12) #è la serie mbt2 smussata della stagionalità > #Insieme al grafico mbt2 (stagianalità+ciclo) sovrappongo il ciclo: GRAF.4 > #Se tolgo il ciclo da stagionalità + ciclo (mbt2), ottengo mbt2-mbt2_12, > #cioè la stagionalità. > #Sorge il problema che mbt2 e mbt2_12 debbono avere la stessa lunghezza > #per poterli sottrarre > > #FACCIO DELLE PROVE PER RENDERE I VETTORI LUNGHI UGUALE > > #Controllo mbt2 > length(mbt2) [1] 371 > # 371 = 12 > head(mbt2) [1] NA NA NA NA 55.3 68.5 > # NA 1.00 70.75 177.50 202.75 159.00 > mbt2=mbt2[2:(length(mbt2)-1)] > > #Controllo mbt2_12 > length(mbt2_12) [1] 363 > # 363 > head(mbt2_12) [1] NA NA NA NA NA NA > # NA NA NA NA NA NA > #Impongo che mbt2 e mbt2_12 abbiano la stessa lunghezza per sottrarli > mbt2_12=mbt2_12[7: (length(mbt2_12)-6)] > length(mbt2_12) [1] 351 > > #Proviamo il SECONDO CASO (applico direttamente la Mb12 su dataset2) > #per il calcolo del ciclo > > yt=dataset2; n1=length(dataset2); mbt2_12_0=c() > for(t in 7: n1-6){mbt2_12_0[t]=(yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+ + yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+yt[t+6]/2)/12} > > ts.plot(mbt2_12_0) Aspetto per confermare cambio pagina... > #Disegno il grafico del ciclo nel secondo modo. > #Da confrontare i due grafici del ciclo mbt2_12_0 e mbt2_12.
> #I due cicli praticamentte coincidono. nel secondo sembra siano rimasti più
> #errori randoms. Potremmo fare un test statistico per controllare
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ANALISI CON EXCEL DELLE PIOGGE A VOLTERRA 1956-1961
post terminato molte decine di anni fa dA PIERO PISTOIA
DA CONTINUARE
Questi ‘racconti’ di Statistica applicata di fatto sono modelli che automatizzano percorsi nell’analisi dei dati.
R è un programma potente e gratuito, continuamente aggiornato in tempo reale nelle principali Università del mondo. Sono disponibili centinaia di manuali gratuiti e migliaia di packages per tutte le esigenze.
Per vedere gli outputs anche grafici, le istruzioni (quando pronte girano!) possono essere riportate, con copia incolla, per es, prima sul Blocco Note o direttamente sulla console di R. Nel procedere potremmo anche decidere di alternare le istruzioni ai grafici (vedremo). Nota bene: prima di incollare in R, è necessario ripulire il piano di lavoro di R, premendo dal MENU MODIFICA ‘Pulisci console’ e poi dal MENU VARIE ‘Rimuovi tutti gli oggetti’
Questi primi dati di Larderello sono stati ripresi dalla “COMUNITA’ DI POMARANCE 1-1991” consegnati alla Redazione da Mauro Fanfani, allora Tecnico presso il laboratorio ENEL.
Quelli di Volterra furono forniti dal dott. Juri Bettini.
—————————————-
RIFLESSIONI SU UN ESEMPIO DI ANALISI STATISTICA CON R: MM DI PIOGGIA CADUTI IN OGNI ANNO DAL 1907 AL 1998 NELLA ZONA DI LARDERELLO (POMARANCE, Pisa). POSSIBILITA’ DI TRASFERIRE, CON POCHE MODIFICHE, IL PROCESSO SU ALTRE ANALOGHE SERIE STORICHE (Es., Volterra 1956-1986)
PRECISAZIONI SU REGRESSIONI LINEARI, MEDIE MOBILI, TESTS STATISTICI, INTERVALLI DI CONFIDENZA, FORECASTS ED ALTRO, OLTRE AL MODO PIU’ O MENO ORTODOSSO DI PROCEDERE. dott. Piero Pistoia
Si evidenziano i files richiamati e si copiano sulla console di R: iniziano automaticamente a girare; se incontrano un grafico si fermano in attesa di un tasto premuto o un click del mouse, permettendo di stampare o memorizzare il grafico stesso. Volendo possiamo anche con copia-incolla trasferire pezzi dell’articolo, per es., da un grafico all’altro. Infine è possibile ricopiare le istruzione direttamente sulla console di R.
——————————-
PARTE PRIMA CON INSERIMENTO DI OTTO PAGINE DI GRAFICI (FIG. 1-8) RIPRESI DAGLI OUTPUTS
Si ‘guarda’ dentro i dati ‘provocandoli’ con le istruzioni di R!
#ESEMPIO DI ANALISI STATISTICA CON IL LINGUAGGIO R: MILLIMETRI #DI PIOGGIA CADUTI IN CIASCUN ANNO DAL 1907 Al 1990 #A LARDERELLO E DAL 1956 AL 1986 A VOLTERRA. #PRECISAZIONI SU INTERVALLI DI CONFIDENZA ED ALTRA STATISTICA #dott. Piero Pistoia #IN QUESTO PRIMO INTERVENTO SI PROPONGONO UNA SERIE DI AZIONI #MESSE IN ATTO PER PORRE PUNTI INTERROGATIVI AI DATI #DA ANALIZZARE. NEI GRAFICI SI ‘LEGGONO’ LE RISPOSTE RESE DAI DATI.
#I dati originali erano a scansione mensile, ma noi inizieremo #ad analizzare i dati annuali ottenuti sommando i 12 #valori mensili delle piogge per ogni anno.
#Se volessimo esprime un’ipotesi sulla pioggia caduta nell’anno #in un certo intervallo di anni, quella più immediata #è che la quantità di essa costruisca nel tempo una serie #stazionaria, senza uniformità interne, (assenza di trend, #fluttuazioni di circa uguale ampiezza) perché sosterremmo #che sommare le entità mensili ridurrebbe le oscillazioni #stagionali di tutti i livelli, mentre non è così immediato #pensare a fenomeni atmosferici e/o astronomici che #possano attivare oscillazioni annuali periodi o non periodiche #(come, per es. i cicli undecennali delle macchie solari…)
library(“UsingR”); library(“TTR”);library(“tseries”); library(“graphics”);library(“forecast”) #Le librerie, se non esistono già nella biblioteca attuale della #versione, devono essere prima caricate dal Menù.
par(ask=T) par(mfrow=c(2,2))
#Da prove preliminari si evidenzia che nella serie originale di #Larderello esistono almeno tre autliers: nel 1913 #(636 sostituito da 736.2), nel 1915 (1505.5 sostituito #da 1145) e 1972 (539.2 sostituito da 739.2), pensando ad una #serie più armonica internamente (gli autliers, essendo ‘accideni’ #isolati pesano meno nel forecast).
#Con pochi cambiamenti possiamo analizzare meccanicamente diverse #serie storiche fornendo il vettore dati: #proponiamo la serie di Larderello di 84 dato a partire dal 1907 #e quella di Volterra di 30 dati a partire dal 1956
c(1174,915.7,1204.1,1203.6,891.5,950.6,836.2, 960.6,1145.5, 1142.2,1156.3,876.4,1045.9,968.0,750.8, 878.3, 719.5, 720.7, 1045.7,1198.1,904.2,1142.0,958.0, 914.4,952.1,1141.8,1023.1,966.6,1013.0,823.1,1138.1, 763.1,1102,1083.0,949.3,1054.2,741.2,804.9,814.8,964.6, 1236.2,829.6,1086.2,782.9,1153.8,877.8,780.4,799.4,800.7, 863.8,760.7,821.6,753,1175.6,873,857.4,1192.6,1276.4, 1117.3,1251.2,742.4,1023.8,1107.4,845.6, 769.4,739.2, 782.7,799.2,985.6,1163.4,826.0,880.4,1067.7,923.6,903.6, 856.6,855.6,1010.4,842.1,891.7,1061.8,783,739.3,1009.6) #si chiude o si apre il vettore dati per analizzare un’altra serie
piogann907990=ts(Piogge_annuali_1907_1990) #si chiude per altro #vettore dati dello stesso nome yt0 yt0=piogann907990 #si chiude o si apre t=c(907:990)#si chiude o si apre #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #Di seguito analizziamo la serie di Volterra di trenta dati dal 1956. #Da prove precedenti consideriamo 2 autliers 1960 (1253)e 1984 (1156) #interpolando con 1000 e 950 rispettivamente
#yt0=c(727,766,804,839,1000,892,866,968,957,1002,1042,727,954,1012,869,678,851,655,698,858,988, #671,932,991,841,781,837,813,950,733,821) piogge annuali Volterra 1956-1986 #t=c(956-986) #si apre o si chiude #yt0=ts(yt0) #si apre o si chiude
#Fig. 1 -> quattro grafici sulla stessa pagina: 1)(yt0,Time); 2)acf(yt0); #3)hist(yt0); 4)punti dati e retta di regressione
#3)hist(yt0); 4)punti dati e retta di regressione
ts.plot(yt0)
#Osservando il grafico dei dati ad occhio ci turba notare un certa tendenza #delle piogge a diminuire nel tempo, #falsificando le aspettative se il fenomeno fosse corroborato.
acf(yt0)
hist(yt0)
#Osservando il grafico dei coefficienti di auto-correlazione h, #sembra chiaramente che all’interno della serie #non ci siano legami di causalità avvallando le aspettative.
#Applichiamo comunque un modello di regressione lineare semplice #ai dati per un controllo. # INIZIO DELL’ELABORAZIONE DEI DATI
# Si prova a cercare il package Using-R #library(“UsingR”) #library(“TTR”)
# Fitta i dati delle piogge col tempo in anni e fornisce gli autputs
#FIG. 2 -> #plot (result) fitta 4 grafici per l’analisi dei residui:
#1)Nel primo (Residual,fitted) si osserva la diffusione dei dati intorno #alla linea y=0 e il trend che non è ovvio. 2)Nel secondo (Normal qqplot), #i residui sono gaussiani se questo grafico segue da vicino la linea #tratteggiata.
plot(result) par(mfrow=c(1,1)) #da ora si plotta grafico per grafico. fit=lm(yt0~t) attributes(fit) summary(fit) fit$coefficients fit$resid
#plot(lm(yt0~t)) pre=predict(fit)# valori sulla retta pre # valori predetti
#FIG. 3 -> acf(pre)
acf(pre) # Plotta i dati e la linea di regressione ts.plot(yt0) abline(fit) #Opppure:plot(t,yt0); abline(result) yt1=yt0-pre
#FIG. 4 -> nel piano cartesiano “yt0,time” viene disegnato l’intervallo #di confidenza al 90% per la media. Ci sono due tipi di intervallo, quello di ‘confidenza per la media’ e quello per la ‘predizione individuale’, #naturalmente più grande. Consideriamo questi intervalli al 90%. Nel secondo #vengono riportati ambedue gli intervalli
#FIG. 5 -> punti-dati con i due intervalli, di confidenza e di previsone, al 90%
# Si possono usare comandi di più alto livello del package UsingR di VENABLE fit=simple.lm(t,yt0) summary(fit) simple.lm(t,yt0,show.ci=T,conf.level=0.90,pred=T) #fa un po’ casino!
#FACCIO DELLE PROVE DI ‘SMUSSAMENTO’
#Elimino una parte del contenuto dei files piogann908990 # (yt0) con una media mobile di ordine 5, pesata con 1,2,3,2,1 (Media Mobile 3*3) #con comandi di basso livello e osservo quello che accade #(confrontare con media mobile semplice 5) #—————————
#SMUSSO5 pesato 1,2,3,2,1 (3*3) m5=c() for(i in 2:length(yt0)){ m5[i] =(yt0[i-2] +2* yt0[i-1] + 3*yt0[i] +2* yt0[i+1] + yt0[i+2])/9} #prova a plottare m5 m5=ts(m5) m5 # smusso5 la yt0 3*3; elimino dall’originale ciò che non è random!?
L’idea era solo sperimentare en passant, smussando con m5!
Da notare è che d’improvviso ho trovato cancellati i pesi dell’m5, sbilanciando risultati e grafici!!
#—————————— #Secondo ‘pezzo’ per cambiare vettore dati da sottoporre al prog. #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#Attenzione! devo fare modifiche per scegliere fra i due vettori dati #da analizzare m5=m5[3:82] #per Volterra (31 dati) va da 3 a 29; PER LARDERELLO (84 DATI) #DA 3 A 82 n5=length(m5) yt=yt0[3:82] #in yt ci sono da 3 a 82 dati yt<yt0; per Volterra 3-29 #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
par=(mfrow=c(2,2))
yt nyt=length(yt) nyt par(mfrow=c(2,2))
ts.plot(m5) acf(m5)
yt_m5=yt-m5 #m5 e yt hanno la stessa lunghezza per cui si possono sottrarre yt_m5 #originale meno m5_smussata
ts.plot(yt_m5) lines(m5)
acf(yt-m5) # auto-correlazione di yt-smussamento 3*3
#Analizzo il vettore dati yt-m5 cercando la retta di regressione t1=c(1:length(m5)) fit1=lm(yt_m5~t1) summary(fit1)
La retta di regressione non esiste!
#FACCIO DELLE PROVE DI ‘SMUSSAMENTO’
——————————————————
# FIG. 6 -> 4 grafici sulla stesso piano: 1)graf. m5 (smusso 5 pesato 12321,3*3); # 2)acf(m5); 3)graf. yt1=yt-m5 (yt è yt0 di lunghezza pari a m5 per sottrarre); # 4)acf(yt1).
OSSERVAZIONI FUORI NORMA
Da osservare l’acf della serie yt-m5 : il picco fuori range può essere considerato dovuto a un caso accidentale come 1 su 20? e le oscillazioni smorzate dell’ acf di m5 non suggeriscono niente? Le armoniche di Fourier potrebbero ‘suonare’ qualcosa? Ritengo che non siano fuori luogo (anche se azzardate e deboli, ma cariche di significati scientifici, K. Popper, ipotesi ‘tentative’ o Tentative Theory) su oscillazioni super-annuali (di periodo circa 5, 11..?) relative ad armoniche rilevanti (si controllino anche i grafici di Fig. 7)
_________________________________
#TENTATIVI DI SMUSSAMENTO con SMA per raccogliere informazioni su #eventuali cicli super-annuali spesso periodici da analizzare con Fourier
piog3=SMA(yt0,n=3) #opero un semplice smussamento di ordine 3 piog5=SMA(yt0,n=5) # opero ora un semplice smussamento di ordine 5 piog8=SMA(yt0,n=8) #piog11=SMA(yt0,n=11) piog12=SMA(yt0,n=12) #opero un semplice smussamento di ordine 12 #piog15=SMA(yt0,n=15)
#Osservando le ‘lisciature’ della curva_dati originale, sarebbe
#interessante sottoporre i vettori dati degli #smussamenti alla
#funzione del PERIODOGRAMMA (scritta dal dott. PIERO PISTOIA
#e testata e riportata nei diversi posts relativi ad esempi statistici a
#cura dello stesso scrivente: in particolare vedere “UN PARZIALE
#PERCORSO DI BASE SULL’ANALISI DI UNA SERIE STORICA
#REALE” dove tale funzione in .jpg è trasferibile e funzionante);
# per la ricerca di armoniche rilevanti.
#Non sembra così strano pensare ad influenze, per lo più
#periodiche, del Cosmo esterno sulla nostra atmosfera, con periodi
#maggiori di un anno terrestre. Anche l’Analisi di Fourier scritta
#col Mathematica di Wolfram, in più occasioni utilizzata dallo
#stesso autore, potrebbe essere uno strumento di controllo efficace.
#Si potrebbe anche riportare la Funzione _Periodogramma
#direttamente su questo post, per ogni possibile, anche futuro,
#utilizzo su qualsiasi vettore_dati.
par(mfrow=c(1,1))
#FIG. 8 -> 4 grafici di smussamento sullo stesso piano cartesiano (yt0,Time)
#Confronto 6 curve in un unico grafico (yt0,pre,m5,piog5,piog8,piog12) ts.plot(yt0) lines(pre) lines(m5,col=”orange”,lwd=2) lines(piog5,col=4,lwd=2) lines(piog8,col=”blue”,lwd=2) lines(piog12,col=”red”,lwd=4) #Riflettiamo sullo smussamento interessante 12: sembra che esso tolga cicli super-annuali #da investigarne in qualche modo le armoniche con fourier # LA STATISTICA DI DURBIN WATSON
library(tseries) y=yt0 n=length(y) result=c() result1=c() for(t in 2:n){ result[t]=(y[t]-y[t-1])^2 } result=result[2:n] a=sum(result) for(t in 1:n) result1[t]=y[t] b=sum(y) dw=a/b dw
#Possiamo usare anche funzioni di più alto livello caricando qualche #libreria nuova
#(‘lmtest’; attenzione alla versione di R!)
#PARTE SECONDA E IL PACKAGE ‘forecast’; si aggiungono #6 pagine di grafici ripresi dagli outputs relativi
#Ci permettiamo di prendere un momento di riflessione in questo #scorcio iniziale della PARTE SECONDA del nostro lavoro di #’lettura’ dei dati. La retta di regressione apparsa ad occhio sui dati, #dopo la regressione con i minimi quadrati di fatto ‘spiega’ ben poco #del nostro campione (R-quadro trascurabile), ma se consideriamo #le ‘statistiche campionarie T’ relative ai suoi coefficienti e le #inseriamo sulle ascisse delle rispettive distribuzioni di Student, #conosciute sotto l’ipotesi nulla, ci accorgiamo che probabilmente #quella retta ‘esiste anche nell’Universo di tutti i campioni riferiti #alla nostra ricerca. Così,nonostante questa retta non così ovvia, #riteniamo ipoteticamente che: “se eliminiamo dai dati originali #yt0, i valori della retta (pre), yt1=yt0-pre, già e ‘ricondizioniamo’ #il campione aggiungendo la media dei valori (cioè la media di yt0 #o di pre), otteniamo un valore migliore dell’originale almeno per #l’applicazione del nostro modello di forecast (Simple Exponential #Smoothing), cioè si rispetterebbero meglio i criteri di applicazione #(omogeneità delle fluttuazioni col tempo, assenza di correlazioni #interne…insomma migliore Stazionarietà)”. Tale ipotesi verrebbe #controllata a posteriori con l’analisi dei residui. Basterà attribuire i #valori della variabile ‘campione-condizionato’ alla variabile #originale yt0 e procedere a far girare il programma successivo di #previsione( yt0=campione-condizionato). Tale prova la qualche #lettore, se vorrà.
#yt1 era il vettore dei dati originali (yt0) meno le ordinate della retta #(pre)
Myt0=mean(yt0); Mpre=mean(pre); Myt1=mean(yt1)
Myt0
Mpre
Myt1
#Dal plot di yt1
#Possiamo notare dal plot di yt1 che esiste un livello costante #situato in corrispondenza ad valore di zero per la media; le #fluttuazioni sembrano rimanere grossolanamente costanti nel #tempo. E’ possibile probabilmente considerare la serie stazionaria, #per cui si può tentare di usare un modello addittivo e uno #’Smoothing Esponenziale Semplice’ per il forecast, forse con #maggiore ‘matching’ di prima. Naturalmente bisogna #’ricondizionare’ yt1 (centrata intorno alla media zero) alla serie #originale. Riteniamo di poterlo fare aggiungendo ai valori di yt1, la #media dei valori predetti ovvero dei valori originali; procederemo #poi al solito a controllare questa scelta dal risultato (rilevanza del #forecast)
#Le righe dei commenti associati al programma che segue devono essere #scorciate (con cancelletti all’inizio) se vogliamo far girare il tutto dalla console di R! #come accade nella prima parte di questo post; in caso contrario vanno riscritte le linee di programma #in successione sulla console di R
#Il metodo del Semplice ‘Lisciare’ Esponenziale è raccomandato quando 1) i dati non #presentano un trend ‘esplicito’ e, 2) non è coglibile una stagionalità.
#Da precisare che non si ha ‘trend esplicito’ anche quando si ha, sì, un cambiamento di livello #o media nel corso del tempo fuori del random, ma tale evento si presenta poco regolare e #intuibile, scarsamente razionalizzabile in un trend ‘esplicito’
#Sono almeno tre i possibili interventi nei processi di forecast del metodo SES , due #praticamente immediati, il metodo ‘ingenuo’ , o ‘naive methods’, ‘average methods’ #(per prevedere è importante solo l’ultima osservazione che rimane costante nel tempo #di previsione), l’altra, il metodo della ‘Media’ (i valori predetti sono tutti uguali alla media #dei valori che servono per prevedere) e il terzo, più mediato, usa medie pesate, che tengono conto #dei valori pesandoli in maniera diversa; quelli più lontani sempre meno di quelli più vicini #secondo una curva esponenziale.
#Fra i modelli del terzo tipo utilizzeremo due modelli di HoltWinters con le funzioni di R HoltWinters() #e forecast.HoltWinters(); per es., per Larderello: valori annuali 1907-1990; per Volterra valori #annuali 1956-1986.
#RIASSUMIAMO IL PROCESSO
#Poiché riteniamo di avere una serie storica a cui si può applicare un modello addittivo con fluttuzioni #pressochè costanti pressochè costanti e che possiede un livello che si mantiene, pensiamo, uguale #nel tempo (valore medio) e nessuna stagionalità, possiamo usare uno dei tanti modelli SES (Simple #Exponential Smoothing), per brevi previsioni future, cioè un mezzo per stimare i livelli previsti nei #punti correnti col tempo.
#Se usiamo però un SES predittivo che utilizza la funzione HoltWinters() di R, sono necessari, #per questo modello due parametri da immettere nell’argomento, beta e gamma che nella fattispecie #dobbiamo uguagliare a FALSE (si cambia il loro valore, per es., per casi con trend e/o stagionalità), #mentre calcola da sé il terzo parametro alfa, che controlla lo smoothing (alfa vicino a zero significa #che diamo più peso ai dati recenti). Come outputs abbiamo il valore di alfa e tutti i valori previsti #corrispondenti ai dati delle misurazioni originali (nella fattispecie 84) con cui è possibile costruire #la curva di previsione all’interno dei dati.
#La funzione di HoltWinters() memorizza gli outputs in una lista di ‘oggetti’ da richiamare contenuta #nella variabile ‘yt0previsti’ da noi scelta. Così la funzione HW() scrive i valori previsti (ed altro) in #uno dela lista degli ‘oggetti’ (fitted, SSE…) contenuti nella variabile yt0previsti calcolata, per cui #essi si troveranno nella variabile yt0previsti$fitted. Gli ‘errori della previsione’ si calcolano #sottraendo dai valori predetti quelli osservati e l’oggetto SSE (Sum of Squared Errors), #rappresenta una misura dell’accuratezza del forecast, fornito sempre dalla HW( ), che # invece verrà richiamato da yt0previsti$SSE.
#E’ interessante notare che è necessario scegliere un valore iniziale di partenza per il calcolo #dei livelli previsti; se questo valore non viene esplicitato il programma sceglie il primo valore #dei dati.
#Ci sono anche dei processi per aiutarci a scegliere questo valore.
#Possiamo immettere però anche questo primo valore scelto da noi, aggiungendo il #parametro ‘1.start’ nell’argomento della funzione HoltWinters(),
#HoltWinters exponential smoothing without trend and without seasonal #component.
yt0previsti$fitted
plot(yt0previsti)
FIG: 10
#La funzione HoltWinters() calcola i forecasts solo per i dati originali (nella #fattispecie quelli da 1907 a 1990). Se vogliamo prevedere alcuni dati futuri #(es., 8) è necessario scaricare il package di R ‘forecast’ , tramite library(‘forecast’), #il quale contiene la funzione nuova ‘forecast.HoltWinters()’, che memorizzerà l’output #nella variabile da noi scelta yt0previsti2 e aggiungeremo nel suo argomento #’yt0previsti, h=8′ yt0previsti2 = forecast.HoltWinters(yt0previsti, h = 8)
#Con la funzione plot.forecast messa disposizione dalla libreria scaricata possiamo stampare #le predizioni ottenute con la funzione forecast.HoltWinters():
plot.forecast (yt0previsti2)
#La funzione forecast.HoltWinters() dà la previsione per ogni anno con un intervallo di #predizione all’80% (fascia arancionee) e al 95% (fascia gialla).
library(“forecast”)
FIG. 11
#La funzione HoltWinters() calcola i forecasts solo per i dati originali (nella #fattispecie quelli da 1907 a 1990). Se vogliamo prevedere alcuni dati futuri #(es., 8) è necessario scaricare il package di R ‘forecast’ , tramite library(‘forecast’), #il quale contiene la funzione nuova ‘forecast.HoltWinters()’, che memorizzerà l’output #nella variabile da noi scelta yt0previsti2 e aggiungeremo nel suo argomento #’yt0previsti, h=8′ yt0previsti2 = forecast.HoltWinters(yt0previsti, h = 8)
#Con la funzione plot.forecast messa disposizione dalla libreria scaricata possiamo stampare #le predizioni ottenute con la funzione forecast.HoltWinters():
plot.forecast (yt0previsti2)
#La funzione forecast.HoltWinters() dà la previsione per ogni anno con un intervallo di #predizione all’80% (fascia arancionee) e al 95% (fascia gialla).
acf(yt0previsti2$residuals, lag.max=20)
FIG. 12
#Osservando l’acf dei residui può accadere che qualche ordinata superi la zona permessa #(dove c’è assenza di autocorrelazione). Può essere che uno o due segmenti escano dai #’significance bounds’. restando incerti se, fra 1-20 lags, ci sia qualche correlazione significativa. #Per una conferma attiviamo il test in R di Ljung-Box-test che usa la funzione “ Box-test()”
#della libreria(stats):
#Box-test(yt0previsti2$residuals, lag=20, type=”Ljung-Box”) #IL TEST DI LJUNG-BOX
#Se il p-value supera 0.05 di poco ci sarà una piccola certezza di qualche correlazione interna, #che decideremo se sia dovuta al caso.
#E’ buona idea controllare anche la costanza della varianza e la normalità della distribuzione #dei residui. Per la costanza della varianza facciamo il plot dei residui con il tempo.
plot.ts(yt0previsti2$residuals)
#Appare un grafico che presenta una successive di fluttuazioni col tempo. Può accadere a vista #che in alcune parti del tempo l’ampiezza di esse risulti leggermente divers da quella di altre parti. #Sarà da decidere se riteniamo che sia circa costante sostenendo l’ipotesi della uguaglianza #della varianza col tempo
FIG: 13
#Per controllare infine se gli errori di previsione siano a distribuzione gaussiana con media zero, #faremo in un istogramma (area coperta=1) degli errori con sovrapposta una curva gaussiana #con media zero e deviazione standard pari a quella della distribuzione degli errori di previsione. #Per far questo, di seguito viene riportata la routine di Avril Coghian di cui l’autore si sente debitore #di questo scritto.
#Basta, dalla console di R, richiamare la funzione, scritta ad hoc, plotForecastErrors() con l’argomento #’yt0previsti2$residuals’:
#INIZIO FUNZIONE PERSONALE #plotForecastErrors=function(forecasterrors)
plotForecastErrors=function(forecasterrors) { #faccio un istogramma degli errori di previsioni
#freq=F assicura che l’area sotto l’istogramma è = 1. #genera una gaussian con media zero e standard deviation mysd
myhist = hist(mynorm,plot=FALSE, breaks=mybins)
#plotto una gaussiana blu sopra l’istogramma ddegli errori di previsione:
points(myhist$mids,myhist$density, type=”l”,col=”blue”,lwd=2) } #FINE FUNZIONE plotForecastErrors(yt0previsti2$residuals )
#Possiamo usare questa funzione per costruire un istogramma con gaussiana #degli errori di previsione per qualsiasi predizione delle #piogge! FIG. 14
e cambiando scala verticale:
#Da controllare se la distribuzione degli errori è grossolanamente centrata
#sullo zero, se è più o meno distribuita come una gaussiana, se è ‘skewed’ #da una parte rispetto alla curva normale, ecc.
#Comunque, a mio parere, è da sottolineare che questi nostri racconti di #statistica nel loro articolarsi, non di rado si imbattono in scelte volontarie #ed intuitive su grandezze in gioco e questo suggerisce che non è necessario #poi in generale un atteggiamento troppo intransigente e restrittivo nelle #valutazioni sulla rilevanza delle ipotesi.
Programmi utili in R commentati e controllati. Il Correlogramma , la Statistica di Durbin Watson, il Periodogramma (applicato come esercizio a medie trimestrali). Formule trigonometriche delle armoniche costruite dai dati di sfasamento e ampiezza riportati nei risultati.
PROGRAMMI IN BASIC: calcolo Coefficienti di Autocorrelazione, il Test di Durbin-Watson, il Test della normale di Lin-Mudholkor, analisi spettrale per il Periodogramma. Calcolo dei coefficienti in una regressione multipla (MLR), calcoli con le matrici, metodo di Cholescki. Calcola il radicando dell’errore Standard delle predizioni con la RLM, calcolo matriciale. Tavole per il Test di Normalità di Lin-Mudholkar e per il Test di Durbin-Watson.
ARTICOLO PREMESSA: “Il senso comune, l’insegnamento scientifico ed i saperi preposti alle scelte” di P. Pistoia
ARTICOLO COMMENTO: “Analisi di Fourier con commenti su dati reali e simulati con il Mathematica di Wolfram vers. 4.2.” di P. Pistoia
“PROGRAMMI in Mathematica con esercitazioni” di P. Pistoia
Vari esempi analizzati compreso ‘Oscillazione mensile ozono a Montecerboli (Pomarance, Pi), 2007,2011’
di Piero Pistoia
L’Esempio 5 si riferisce all’analisi della serie storica concentrazione As detrendizzata.
1 – PREMESSA
PREMESSA SULLO STATO DELL’ARTICOLO
Il presente scritto diventa, sempre più articolato ‘nell’andare’, sempre meno lineare, continuando a riempirsi di parentesi, di alternative informatiche, di pause di riflessione, di ritorni e di correzioni (si veda, per es., il caso del periodogramma come function, ormai praticamente risolto, inseribile come modulo all’interno di qualsiasi programma scritto dai lettori) ecc.. Per me è questo il ‘vero’ articolo scientifico col suo ‘travaglio raccontato (trouble)’, denso di stimoli, possibilità nascoste, interferenze casuali… e non lo scritto finale asettico e razionalmente ripulito, che banalizza il percorso. In questa ottica qualcuno ha detto che l’articolo scientifico è un inganno (Antiseri). Possiamo forse affermare che seguire il ‘processo’ è come un auto-porsi domande-risposte, attraverso una successione di ipotesi-falsificazioni, una sorta di MAIEUTICA SOCRATICA che favorirebbe la costruzione del concetto? Il filosofo non insegna nulla ai discepoli, ma piuttosto a scoprire la ‘verità’, che potenzialmente hanno già dentro di loro (per processo co-evolutivo con la Natura), attraverso una successione di argomentazioni su punti interrogativi. Allora, dal punto di vista educativo-didattico è più importante il percorso o la meta, la storia o l’evento? (meditate, gente, meditate!). Secondo me si apprende molto più e meglio se spingiamo a riflettere sugli errori rilevati, sulle ipotesi a cammino chiuso, sulle falsificazioni insomma, anche in termini di memoria, che seguire acriticamente un racconto lineare, ‘ripianato’, anche se intrinsecamente coerente. In questa disquisizione aperta si inserisce bene anche l’altro aspetto di un Socrate-docente che, perchè ‘ignorante’, costruisce insieme al discepolo, senza conoscenze preacquisite (risuonano qui le posizioni di Foerster e Bruner, da richiamare in questo blog).
Per sovrapporre però una ‘lettura’ su video meno discontinua e difficile, che serva come back-ground, una guida all’apprendimento più lineare, più conforme, meno a ‘frullato di pezzi di concetti’ e quindi forse più facile e più gradevole, trasferiamo, col titolo ‘IL PROLOGO’, la prima parte dell’articolo originale dello stesso autore (senza l’uso di R, ma di scripts in Qbasic ed Excel), di cui lo scritto in questione voleva essere una ‘lettura rivisitata’ mediata dal linguaggio R e dal Mathematica di Wolfram. Prima delle appendici trasferiamo anche la seconda parte col titolo ‘L’EPILOGO’. L’intenzione è introdurre all’inizio anche un INDICE a link per migliorare l’accesso alle diverse ‘zone mosaico’ dell’articolo. Mi scuso per ‘questo andare’ poco controllato! Se mi rimanesse più energia mentale e ‘tempo di vita’ forse potrei anche rivisitarlo.
Comunque, un buon apprendistato sarebbe quello di leggere, prima di questo intervento, il primo post dal titolo “Un percorso verso il periodogramma” curato dallo stesso autore. Grazie.
2 – IN ANTEPRIMA
IN ANTEPRIMA
ECCO LA FUNCTION PRDGRAM DEL PERIODOGRAMMA IN R scritto dal dott. Piero Pistoia
Segue una proposta di esercitazione da attivare sulla consolle di R: 1) si incolla la f. PRDGRAM in R e in successione 2) si trasferiscono gli ESERCIZI dell’esercitazione, per es., uno alla volta. Si hanno i dati e grafici in uscita per ogni ESERCIZIO. Ricordarsi, una volta sulla consolle, per prima cosa, sempre azzerare i dati, che R ha già in memoria, tramite il menù ‘VARIE’ (Rimuovi tutti gli oggetti) e poi introdurre in R, prima di incollare la PRDGRAM, le ‘library’ necessarie (tseries e graphics).
PROPOSTA DI ESERCITAZIONE ANCHE PER FAVORIRE L'ACQUISIZIONE
INTUITIVA DELLA 'LETTURA' DI UN PERIODOGRAMMA (contenuta nel
precedente link) di Piero Pistoia
Inizialmente vogliamo simulare ad hoc una serie storica
'tabellando' n=21 dati da tre funzioni del seno con costante
additiva 100,con ampiezze rispettivamente 4,3,6 e 'frequenze'
nell'ordine 2/21, 4/21,5/21 e infine fasi -pi/2, 0, -1.745,
con il comando iniziale di di R: t=c(1:n), usando come base
per i nostri esempi proprio questa espressione:
yt=100+4*sin(2*pi*2*t/n-pi/2)+3*sin(2*pi*4*t/n+0)+
6*sin(2*pi*5*t/n-1.745) #0.
Calcolati i 21 dati yt, attribuendo a t valori da 1 a 21
nell'espressione precedente, tali dati rappresentano
proprio lanostra serie storica da sottoporre al
Periodogramma, una volta precisati i tre valori
essenziali da passare ad esso (yt,n,m), dove m è il
numero di armoniche da calcolare; m=n/2-1 se n è
pari; m=(n+1)/2 se m è dispari.
Tramite il nostro programma in R calcolammo allora
i valori di ampiezze e fasi per le prime 10 armoniche
riscoprendo nei dati le oscillazioni che c'erano.
Per esercizio continuiamo a simulare serie storiche
modificandol'espressione di base, modificandola anche
aggiungendo, a scelta, un trend lineare (k*t) e/o
valori random onde controllare se il Periodogramma
riesce a"sentire", oltre alle oscillazioni armoniche,
anche il trend e la componente casuale.
Con l'istruzione '#' elimineremo secondo la necessità
le linee di programma non utilizzate per lo scopo
prefissato.
Proviamo, prima, ad applicare il programma su 21 dati
simulati dalle espressioni di una retta inclinata e da
una serie random estratta da una distribuzione gaussiana.
Sceglieremo poi una combinazione di seni interessanti
più adatta a proseguire l'esercitazione.
PERCORSI DA INVESTIGARE
par(mfrow=c(1,1))
#n=21
#n=240
#t=c(1:n)
# yt=0.5*t # 1
#si tratta di un ramo di iperbole(?)discendente
#yt=c();yt[1:t]=0
#yt <- rnorm(t,0,1) # 2
#yt=-4+ 0.5*t + rnorm(t,0,1) # 3
#yt=100+4*sin(2*pi*2*t/256-pi/2)+3*sin(4*t/256*2*pi+0)+
6*sin(5*t/256*2*pi-1.745) # 4
#analisi yt; tenendo come base questa espressione con
armoniche basse, ro è sulla rampa alta #della 'iperbole'
e si obnubila il trend.
#yt=100+4*sin(2*pi*2*t/n-pi/2)+3*sin(2*pi*4*t/n+0)+
6*sin(2*pi*5*t/n-1.745) + 0.1*t # 5 #analisi yt_reg
#yt=100+2*sin(2*pi*2*t/n-pi/2)+sin(2*pi*4*t/n+0)+
3*sin(2*pi*5*t/n-1.745) + rnorm(t,0,1)*2 # 6
#analisi yt_rnorm: diminuiamo le ampiezze e aumentiamo
i random
#yt=100+4*sin(2*pi*2*t/n-pi/2)+3*sin(2*pi*4*t/n+0)+
6*sin(2*pi*5*t/n-1.745) + 0.5*t)+(rnorm(t,0,1)-1/2)) # 7
#analisi yt_reg_rnorm
yt <- 6*sin(2*pi*5*t/n)+2*sin(2*pi*30*t/n)+
3*sin(2*pi*40*t/n)+0.1*t + rnorm(n,0,1)*2 # 8
#questa espressione anche con 'frequenze' alte (30,40) è la
#più indicata a dimostrare che il Periodogramma 'scopre' anche trends
#e randoms oltre alle oscillazioni sinusoidali.
Ora possiamo prevedere che cosa accade se togliamo una
o due di queste tre,basta far girare il programma nei
diversi casi.
In questo contesto nel prosieguo useremo invece, per
esercizi, le tecniche di scomposizione di una serie
storica: proviamo a 'destagionalizzarla' in successione
con due o tre medie mobili opportune (o magari col
comando filter di R) per controllare che cosa rimane
(che cosa accade ai random?). Potevamo anche
'detrendizzarla prima con una regressione lineare,
ovvero eliminare i random con una media mobile 3*3 ecc..
TRACCIA DEI PERCORSI
ESERCIZIO N° 0
n0=256 # può essere cambiato
t=c(1:n0)
yt0=100+4*sin(2*pi*2*t/n0-pi/2)+3*sin(2*pi*4*t/n0+0)+
6*sin(2*pi*5*t/n0-1.745)
yt0 # la serie storica
ts.plot(yt0)
if(n0/2==n0%%2) m0=n0/2-1 else m0=(n0-1)/2
yt0_period=PRDGRAM(yt0,n0,m0)
yt0_period # data in uscita con ampiezza e fase, per il
controllo
yt0_period$ro # vettore delle ampiezze
ts.plot(yt0_period$ro)
Esercizio N° 1
n01=21
t=c(1:n01)
yt1=0.5*t
yt1 # serie storica
ts.plot(yt1)
if(n01/2==n01%%2) m01=n01/2-1 else m01=(n01-1)/2
yt1_period=PRDGRAM(yt1,n01,m01)
yt1_period #data in uscita comprese ampiezze e fasi
yt1_period$ro #vettore delle ampiezze
ts.plot(yt1_period$ro)
Esercizio N° 2
n2=21 # può essere cambiato
t=c(1:n2)
yt2<- rnorm(t,0,1)
plot(yt2)
yt2 # serie storica
if(n2/2==n2%%2) m2=n2/2-1 else m2=(n2-1)/2
yt2_period=PRDGRAM(yt2,n2,m2)
yt2_period # data in uscita
yt2_period$ro # vettore delle ampiezze
plot(yt2_period$ro)
ESERCIZIO N° 4
n4=256 # può essere cambiato
t=c(1:n4)
ts.plot(yt8)
if(n8/2==n8%%2) m8=n8/2-1 else m8=(n8-1)/2
yt8_reg=PRDGRAM(yt8,n8,m8)
yt8_reg # data in uscita
yt8_reg$ro # vettore delle ampiezze
ts.plot(yt8_reg$ro)
GRAFICO YT8 E PERIODOGRAMMA (Yt8_reg$ro) SENZA IL TREND
GRAFICO DI Yt8_reg_rnorm n=240
GRAFICO Yt8 ANCHE CON IL TREND (serie originale)
#RIFLESSIONI
#Se aggiungo il trend 0.1*t a yt8 ottengo il grafico
precedente. Confrontando il grafico che segue#e quello
precedente sarebbe interessante approfondire
intuitivamente perché col trend le ampiezze
#vengono disturbate tanto più quanto più lentamente
scende a zero il ramo di 'iperbole'.Sembra #quasi così,
induttivamente, si possa affermare la regola empirica
(ipotesi) che armoniche con #frequenze più alte vengano
disturbate meno di quelle più basse, che si posizionano
sul ramo a #pendenza più elevata e con i suoi punti
più distanti dall'ascissa. Se sommiamo la distanza della
#base dei picchi dall'asse orizzontale alla cima dei
picchi l'ampiezza tenderebbe al valore della
#formula? Se togliamo anche i random da yt8 i tre picchi
sarebbero poggiati sull'asse orizzontale?#La numerosità
di yt8 influisce o no sulla velocità con cui si muove
verso l'asse x la curva del trend? Cercare di rispondere
osservando i grafici precedenti.
FINE ANTEPRIMA
<A NAME=”punto3″>IL PROLOGO
IL PROLOGO
3 – PROLOGO
COME INTRODUZIONE RIPORTIAMO LA PRIMA PARTE DELLA RICERCA ORIGINALE (SENZA L’USO DI R); LA SECONDA PARTE VIENE RIPORTATA PRIMA DELLE APPENDICI.
SE VUOI APPROFONDIRE LE PROBLEMATICHE RELATIVE A FOURIER VEDI L’APPENDIX5
LA COSTRUZIONE SI FA CON L’ANDARE!
LA FUNCTION DEL PERIODOGRAMMA ora può essere trasferita come modulo in qualsiasi altro programma scritto da chiunque! Abbiamo cercato di correggere tutti gli scripts dove figurava questa funzione all’interno di questo post. Vedere di seguito (area definita “fra parentesi”) il funzionamento di un listato con svariati richiami a questa funzione con proposte di ‘gioco’ con le armoniche su una serie storica reale (serie storica trimestrale) …. Il listato del periodogramma è lungo e articolato. Nell’analisi di una serie di dati storici con piu’ serie derivate capita spesso di far uso di questo listato per guardare all’interno delle serie. E’ pertanto utile riuscire a scrivere una sola volta questo listato per poi richiamarlo quando serve. Da riorganizzare anche testo e paragrafi. Problemi sorgono anche perché R memorizza all’uscita tutti gli oggetti su cui ha lavorato che tacitamente, pur nascosti, sono ancora disponibili. Questi valori possono interagire sui programmi in via di sviluppo, creando situazioni le più disparate. In generale conviene dal menù ‘varie’ eliminare questi valori prima di far girare o costruire programmi! Si cercherà con calma di attivare i controlli anche sugli altri post, dove figura la function PRDGRAM.
ATTENZIONE: I SEGMENTI DELL’ARTICOLO IN GRIGIO CHIARO HANNO UNA BARRA ORIZZONTALE IN FONDO PER MUOVERE LO SCRITTO A DESTRA E SINISTRA, SE LO SCRITTO ESCE DALLO SCHERMO
FINE PROLOGO
UN PARZIALE PERCORSO DI BASE SULL’ANALISI STATISTICA DI UNA SERIE STORICA REALE POCO INTUITIVA COMMENTATO CON IL LINGUAGGIO R
“Letture” su concetti statistici e su alcuni aspetti della programmazione
Dott. Piero Pistoia
PREMESSA
NB – I GRAFICI OTTENUTI CON IL SUPPORTO DEL PROGRAMMA CORR IN QBASIC (ALLEGATO) E DI EXCEL, SE RIUSCIAMO A RIDISEGNARLI TUTTI, FACENDO GIRARE GLI SCRIPTS DEL LINGUAGGIO R CHE SEGUONO, QUESTO E’ UN EFFICACE CONTROLLO INTERNO ALLO SCRITTO.
Il file.dati che prenderemo come campione da analizzare riguarda le concentrazioni mensili di arsenico (As) misurate in mg/l nelle acque della Carlina (sorgenti Onore), prov. Siena, nell’intervallo di tempo 1989- 1993 (5 anni, 60 mesi con inizio da gennaio). Dopo interpolazione per i dati mancanti, un’analisi preliminare (Modello Additivo secondo il Metodo delle Medie Mobili Centrate) porta ad individuare tre residui standardizzati elevati (> 2 in valore assoluto e quindi considerati outliers da eliminare e sostituire con nuova interpolazione,ottenendo così una serie storica corretta, stocastica e discreta; stocastica, nel senso che il futuro è solo parzialmente determinato dai valori del passato e discreta, nel senso che le misure sono fatte in tempi specifici (ogni mese) a uguali intervalli.
Su questa serie (yt=as1) di 60 dati – inserita nel file che si chiama As-Carlina1.csv – e che comunque verrà esplicitata all’inizio dell’analisi – procediamo “a fare i conti” e a gestirla con R. Questa parte iniziale preliminare verrà trattata successivamente.
Intanto alleghiamo di seguito Il grafico della serie corretta e interpolata (Graf. N.1).
L’analisi di base di una serie storica procede alla ricerca delle uniformità al suo interno, come TREND, vari tipi di stagionalità periodica (giornaliera, settimanale, mensile, trimestrale ecc.) correlata al carattere dei dati che abbiamo (orari, giornalieri, settimanali,ecc.), cicli con eventuale periodo superiore che esce dal range dei dati (in generale periodo e ampiezza variabili), la componente random, che riassume lo ‘white noise’ ed altro (impulsi erratici). Alleghiamo come informazioni preliminari anche il relativo grafico dell’autocorrelogramma e del periodogramma (GRAF. N. 2, a e b). Si rimanda al loro significato e processo alla Appendice 1 di questo articolo e al Post scritto a nome di P.Pistoia ed altri, facilmente accessibile da questo sito, per es., battendo periodogramma nella finestra ‘Cerca’. Anticipiamo che dal correlogramma (GRAF. N.2 a) si osservano una stretta convessità intorno al valore 12-13 che supera la fascia dell’errore, una ondulazione dei picchi (forse una oscillazione), un permanere di picchi nella zona positiva (TREND) ed altro e quindi si evince che i dati della serie al 95% di fiducia, non sono random e dal periodogramma si nota un picco forse rilevante corrispondente al valore 5 (5 oscillazioni nel range dei dati, cioè 5 oscill. in 5 anni, una oscillazione all’anno, quindi periodo=12 mesi). In dati mensili, una oscillazione periodica di periodo 12 è allora un’ipotesi plausibile.
Scegliamo di procedere, come tentativo, per prima cosa ad eliminare dalla serie storica corretta ( yt o as1) l’oscillazione stagionale prevista dai grafici precedenti. Useremo vari metodi per farlo e confronteremo poi i risultati.
4 – Cenni al METODO DELLA MEDIA MOBILE
SINTESI SUL METODO DELLA MEDIA MOBILE
Il metodo della media mobile consiste nel sostituire ai valori osservati, valori artificiali corretti, ottenuti effettuando la media di ciascun valore con quelli contigui (per il calcolo vedere, per es., [3] pag. 997), ottenendo una nuova serie storica.
Se da una serie storica vogliamo eliminare una oscillazione di un dato periodo, bisogna scegliere, per il calcolo della media, una lunghezza del periodo mobile uguale il più possibile alla lunghezza del periodo dell’oscillazione prevista.
E’ da tener presente che sembra che talora tale metodo abbia il difetto di inserire un ciclo fittizio in una serie storica anche casuale. Abbiamo controllato nel caso della serie trimestrale enucleata da quella in studio (vedere dopo).
Useremo la Media Mobile Centrata di ordine 12 (come suggerito dai grafici preliminari) che di norma elimina l’oscillazione di uguale periodo insieme alle componenti casuali dalla serie originale, trasformando la serie mensile originale (yt o as1, che inizia con gennaio, APPENDIX3, TABELLA N.1, col.5 ) in una serie storica di dodici termini più corta (la serie Mbt, APPENDIX3, TABELLA N.1, col.6, che perde i valori dei primi sei mesi e degli ultimi sei, e inizia da luglio). Da porre attenzione che nel processo di scorciamento il primo termine della serie Mbt si riferisce al mese di luglio del primo anno e così via. L’Mbt sottratta da quella originale (as1) ne fornisce una della stessa lunghezza della precedente (48 temini), l’STRD (componente stagionale + random, APPENDIX3, TABELLA N.1, col.7 ), sulla quale operiamo poi per ottenere il Fattore Stagionale costituito da dodici termini, uno per ogni mese (oscillazione in un anno). Per ottenere il Fattore Stagionale corrispondente ad un mese, si considerano tutti i valori della serie STRD (più corta di 12 termini) corrispondenti a quel mese e se ne fa la media. Quando faremo girare il programma scritto con R e vedremo i 48 valori della serie STRD, potremo controllare che, per es., i 4 valori del mese di gennaio (il settimo, il diciannovesimo, il trentunesimo, il quarantaduesimo) sono -0.0030, -0.0046, 0.0033, 0.0126 e facendo la media otterremo il 7° elemento del Fattore Stagionale, 0.0022, cioè il primo elemento di ESAs (APPENDIX3, TABELLA N.2, col.1), EFFETTO STAGIONALE, la cui oscillazione è visibile nel GRAF. N.3 a.
Così per il mese di gennaio si fa la media dei 4 valori di gennaio contenuti nella serie STRD, ottenendo il primo valore dell’Effetto e così via. Con questi processi di media verranno eliminate anche le componenti casuali, se ci sono rimaste, dalla serie STRD che diviene così ST (stagionalità). Ripetendo 5 volte la ST copriamo i 5 anni, ottenendo l’Effetto Stagionale. E’ necessario però prima riorganizzare i 12 termini del Fattore Stagionale, spostando i primi sei termini, alla fine degli ultimi sei in maniera da avere i 12 valori allineati da gennaio a dicembre. Per il controllo di questa oscillazione applichiamoci, per es., il programma CORR scritto in Qbasic dall’autore (nota 2) o in linguaggio R (vedere sotto PARENTESI) e focalizziamo l’attenzione sul periodogramma dell’ultima serie ottenuta per osservare la frequenza di questa oscillazione (GRAF. N.3 a,b dell’Effetto Stagionale, ottenuto invece per mezzo di Excel): chiaramente significativa appare la frequenza 5. Troveremo lo stesso periodogramma anche con R. Con R useremo la funzioneacf (file, main=”Titolo”), per ritrovare i correlogrammi costruiti con CORR ed excel; per il periodogramma si rimanda anche alla relativa routine qui riproposta, rivisitata e funzionante.
————————————————-
5 – INIZIO AREA FRA PARENTESI
5-AREA FRA PARENTESI
APERTA PARENTESI
Alcuni programmi in R utili nello studio delle serie storiche
Da notare (fra parentesi) il programmino riportato qui sotto, scritto in linguaggio R dal sottoscritto, con i suoi risultati, che calcola egregiamente (almeno sembra) i coefficienti di auto-correlazione di una serie storica di prova:
y=c((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)). Comunque, nell’andare, lo vedremo in azione per i tanti confronti e prove! Si aggiungono di seguito anche scripts in R per il calcolo di DW (test di Durbin Watson), metodo più efficace nell’analisi dei correlogrammi, sempre del sottoscritto.
ATTENZIONE! GLI SCRIPTS DEI PERIODOGRAMMI COME SUBROUTINES (functions) SONO IN VIA DI CORREZIONE
RIPORTIAMO SUBITO ANCHE IL PROGRAMMA PIU’ COMPLESSO PER COSTRUIRE IL PERIODOGRAMMA DI UNA SERIE STORICA con i relativi risultati per il controllo . Un controllo quantitativo più puntuale è stato condotto col MATHEMATICA 4.2 di Wolfram nella APPENDIX4 (Piero Pistoia)
Queste routines messe sotto forma di Functions serviranno per costruire correlogrammi, tests di DW e periodogrammi ognivolta che servono.
library(tseries)
# PROGRAMMINO ‘CORRELOGRAMMA’
# Un piccolo strumento per allenare anche l’intuito
#dott. Piero Pistoia
result=c() # result=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
result1=c() # result1=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
#y=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
y=c(1:20)
# Il lettore può a piacere aggiungere altre funzioni (anche numeri casuali), tentare di indovinare # con ipotesi e poi controllare, per acquisire intuizione sul Correlogramma e sui suoi limiti.
#Controllare se le definizioni dei vettori con elementi NA sono necessari! Sembra di no!
#y=c(1,2,3,4,5)
N=length(y)
m=10
yM=mean(y)
for(h in 1:m){
for (t in 1:N-h){
result[t]=(y[t]-yM)*(y[t+h]-yM)
}
result1[h]=sum(result)
} # OK
result1
result2=c()
#result2=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
#for(h in 1:m){
for(t in 1:N){
result2[t]=(y[t]-yM)^2
}
result3=sum(result2)
# Calcolo il coeff. di correl. di lag 1
rh=result1/result3
t=seq(1:10)
Prh=plot(t,rh)
RISULTATI DELLA PROVA (nessun errore rilevato dalla consolle di R nella prima prova!)
‘tseries’ is a package for time series analysis and computational finance.
See ‘library(help=”tseries”)’ for details.
> result=c(); result=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA) > result1=c(); result1=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA) > y=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) > > #y=c(1,2,3,4,5) > N=length(y) > m=10 > yM=mean(y) > > for(h in 1:m){ + for (t in 1:N-h){ + result[t]=(y[t]-yM)*(y[t+h]-yM) + } + result1[h]=sum(result) + } # OK Ci sono 45 avvisi (usare warnings() per leggerli) > result1 [1] 565.25 385.75 233.75 107.25 4.25 -77.25 -139.25 -183.75 -212.75 [10] -228.25 > > result2=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA) > #for(h in 1:m){ > > for(t in 1:N){ + result2[t]=(y[t]-yM)^2 + } > result3=sum(result2) > > # Calcolo il coeff. di correl. di lag 1 > > rh=result1/result3 > > t=seq(1:10) > > Prh=plot(t,rh)
Risultato da confrontare con acf(y)
SE SCRIVIAMO coeffcorr=acf(y), R DARA’ ANCHE IL VETTORE DATI IN coeffcorr
La formula usata è quella senza la moltiplicazione per N/(N-1)
LA STATISTICA DI DURBIN WATSON
library(tseries)
y=c(1,2,3,4,5,6,7,8,9,10)
n=length(y)
#result=c(NA,NA,NA,NA,NA,NA,NA,NA,NA)
result=c()
result1=c()
for(t in 2:n){
result[t]=(y[t]-y[t-1])^2
}
result=result[2:n]
a=sum(result)
for(t in 1:n)
result1[t]=y[t]
b=sum(y)
dw=a/b
dw
#Nella tabella, k'=n° regressori non contando la costante, a=n° osservazioni (y) e dw, sono le tre informazioni per fare il
test con la tabella.
#Per k'=1 e a=20 l'intervallo dl-du=1.201-1.411, per cui 0.2 < dl: presenza di correlazione,
#si respinge l'ipotesi nulla (ipot. nulla = i dati non sono
correlati!), come era intuitivamente già nelle cose.
Da notare che normalmente il test si applica ai residui per
testare la loro indipendenza.
RISULTATI DELLA PROVA (nessun errore sulla consolle di R)
> library(tseries)
> y=c(1,2,3,4,5,6,7,8,9,10)
> n=length(y) >
#result=c(NA,NA,NA,NA,NA,NA,NA,NA,NA)
> result=c() > result1=c()
> for(t in 2:n){ + result[t]=(y[t]-y[t-1])^2 + }
> result=result[2:n]
> a=sum(result)
> > for(t in 1:n)
+ result1[t]=y[t]
> b=sum(y)
> dw=a/b
> dw [1]
0.1636364
>
#TENTIAMO SCRIPTS del PERIODOGRAMMA IN FORMA DI FUNCTION del dott. Piero Pistoia
# PROVE_TEST SUL PERIODOGRAMMA E CONTROLLO COL MATHEMATICA 4.2 # Oscillazioni su medietrim e costruzione delle formule
trigonometriche# Eliminazione delle varie armonichepar(ask=T)par(mfrow=c(1,3))#medietrim sono i 20 valori trimestrali relativi ai 60 dati mensili delle concentrazioni arsenico #della Carlina per 5 anni, in studio.#Vedere il Post a nome di P.Pistoia "Un percorso verso il periodogramma" #in questo blog o rivisitato ed esteso in APPENDIX4.
yt=c(0.04233333,0.06100000,0.04500000,0.0556666,0.05400000,
0.06500000,0.07066667,0.04633333,0.05833333,0.06533333,
0.08516667,0.06866667,0.07650000,0.0761666,0.07300000,
0.06700000,0.07966667,0.07333333,0.07866667,0.06266667)#ALTRA PROVA IN COSTRUZIONE#yt= qui si introduce il vettore detrend_trim, cioè i 20 valori di yt detrendizzato, #su cui faremo agire la function del periodogramma. Vedere
APPENDIX4# detrend_trim=c(-0.0094714286, 0.0077825815, -0.0096300752, #-0.0003760652, -0.0034553885, # 0.0061319549, 0.0103859649, -0.0153600251, -0.0047726817,
0.0008146617, # 0.0192353383, 0.0013226817, 0.0077433584, 0.0059973684,
0.0014180451, #-0.0059946115, 0.0052593985, -0.0024865915, 0.0014340852,
-0.0159785714)n=length(yt)yt=as.vector(yt)nx=nyx=yt medietrim=yt#m =(n-1)/2 # perché n dispari#m =(n/2-1) # perché n pariif (nx/2%%2==2) mx=nx/2-1 else mx=(nx-1)/2 #controllo
automatico di n (pari o dispari?)
#Controllare se ho invertito le due opzioni!
nxmxt=c(1:length(medietrim))PRDGRAM<- function(y1,n1,m1) {# VALORI DEL PARAMETRO aka0=c(); k=0; a0=0;for(t in 1:n1){a0=a0+y1[t]*cos(2*pi*t*k/n1)}a0a0=a0*2/n1;a0=a0/2a0a=c();a[1:m1]=0;for(k in 1:m1) {for(t in 1:n1){a[k]=a[k]+y1[t]*cos(2*pi*t*k/n1)}}a=2*a/n1# vALORI DEL PARAMETRO bkb=c();b[1:m1]=0;b0=0;k=0for(k in 1:m1) {for(t in 1:n1){b[k]=b[k]+y1[t]*sin(2*pi*t*k/n1)}}a <- as.vector(a)for(i in 1:m1){if (abs(a[i]) < 1e-10) a[i]=0 else a[i]=a[i]}afor(i in 1:m1){if (abs(b[i]) < 1e-10) b[i]=0 else b[i]=b[i]}b=2*b/n1b# AMPIEZZE#ro[1:m1]=0ro <- sqrt(a^2 +b^2)for(i in 1:m1){if (abs(ro[i]) < 1e-10) ro[i]=0 else ro[i]=ro[i]}# CALCOLO DELLA FASE DI OGNI ARMONICA# RIPORTANDO IL VALORE AL QUADRANTE GIUSTOf2=c()f2[1:m1]=0for(i in 1:m1){f2[i] <- abs(a[i]/b[i])f2[i] <- atan(f2[i])*180/pi}f2 =as.vector(f2)f2#f2[1:m1]=0 un f2[1:m1] di troppo!phi <- c()for(i in 1:m1){# f2 <- abs(a[i]/b[i]);# f2 <- atan(f2)*180/pi;if(b[i]>0 & a[i]>0) phi[i] = f2[i];if(b[i]<0 & a[i]>0) phi[i] = 180-f2[i];if(b[i]<0 & a[i]<0) phi[i] = 180+f2[i];if(b[i]>0 & a[i]<0) phi[i] = 360-f2[i];if(b[i]==0 & a[i]==0) phi[i] = 0;if((b[i]<0 & b[i]>0) | a[i]==0) phi[i]=0; if(b[i]==0 & a[i]>0) phi[i]=90;if(b[i]==0 & a[i]<0) phi[i]=360-90}# PHI FASE ARMONICHEphi=as.vector(phi)phiparam_a <-aparam_b <-bampiezza <- rofase <- phia;b;ro;phi# Qui, al termine della function si pone il valore di un'unica # variabile che esce o, se escono più variabili, si usa # un data.frame: data=data.frame(x1,x2,...).# Ogni chiamata alla function permette di includere l'unica # variabile o i data nel nome della chiamata:# es. periodxx=nome.function(x1,x2,...)
data <-data.frame(a,b,ro, phi) data# questa matrice esce dalla function e viene 'raccolta' nella variabile periodxx}#FINE SUBROUTINE ANALISI FOURIERperiod=PRDGRAM(medietrim,nx,mx)period plot(period$ro,type="l",main="PERIODG.medietrim",xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")
# 1° grafico in A1# medietrim (vedere ro del period. di medietrim) presenta # le armoniche rilev. n.3 e n.5 (GRAF.A1)# for(i in 1:10000000) i=i#data <-data.frame(param_a,param_b,ampiezza, fase)#data
# Con il numero delle armoniche considerate rilevanti,
le relative ampiezze e fasi possiamo
# costruire le loro espressioni trigonometriche.
w1=c(1:length(medietrim))y_osc=0.0058*sin(2*pi*5*t/20+3.9) # questa oscillazione
dovrebbe avere # un'armonica 5 (GRAF.A3)so=medietrim-y_osc # so nel grafico dell'ampiezza (GRAF.B2). # Questa sottrazione eliminerà l'armonica 5# da ro di medietrim (GRAF.B2)so#PER UN'ALTRA PROVA# Se consideriamo l'altra espressione y_osc1=0.0066*sin(2*pi*3*t/20+2.92), che ha un picco
#all'armonica 3, invece di y_osc, e la sottraiamo da medietrim che ha pure un picco
#all'armonica 3 (GRAF.A1), come diverrà il grafico? (vedere
GRAF.B3)#Se detrendiziamo medietrim (detrend_trim) e applichiamo il
period. #potremo controllare le sue armoniche rilevanti e esprimere in forma analitica #(in formula trigonometrica) la loro rilevanza (y_oscxx).
APPENDIX4 #detrend_trim=c(-0.0094714286, 0.0077825815, -0.0096300752, #-0.0003760652, -0.0034553885, #0.0061319549, 0.0103859649, -0.0153600251, -0.0047726817,
0.0008146617, #0.0192353383, 0.0013226817, 0.0077433584, 0.0059973684
0.0014180451, #-0.0059946115, 0.0052593985, -0.0024865915, 0.0014340852,
-0.0159785714) #ripreso dall'APPENDIX4FINE ALTRA PROVAny=length(y_osc) n=length(so) if (n/2== n%%2) m=n/2-1 else m=(n-1)/2
period1=PRDGRAM(so,n,m) period1 period1$ro #plot(period1$ro,type="l",main="PERIODG.senza osc.5", #xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")
period6=c()period6=PRDGRAM(y_osc1,nz,mz)period6plot(period6$ro,type="l",main="PERIODG.y_osc1",
xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")# 2° grafico in A2
if (ny/2== ny%%2) my=ny/2-1 else my=(ny-1)/2period2=PRDGRAM(y_osc,ny,my) period2 period2$ro plot(period2$ro,type="l",main="PERIODG.y_osc",xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza") # 3° grafico in A3
period3=c()period3=periodplot(period3$ro,type="l",main="PERIOD.medietrim",xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")
# 4° grafico in B1# medietrim (vedere ro del period. di medietrim)
so1=medietrim-y_osc1#period4=c()#period4=period1#plot(period4$ro,type="l",main="PERIODG.senza osc.3",#xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")nz=length(y_osc1)if (nz/2%%2==2) mz=nz/2-1 else mz=(nz-1)/2 #controllo automatico di n (pari o dispari?)period5=c()period5=PRDGRAM(so1,nz,mz)period5plot(period5$ro,type="l",main="PERIODG.senza osc.3", xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza") # 5° grafico in B3#par=(mfrow=c(1,1))#period6=c()period6=PRDGRAM(y_osc1,nz,mz)#period6#plot(period6$ro,type="l",main="PERIODG.y_osc1", #xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")#
plot(period1$ro,type="l",main="PERIODG.senza osc.5", xlab="Armoniche = N° oscillazioni in n dati", ylab="ampiezza")
#6° grafico in B2
#RISULTATI OK
cliccare qui sotto per vedere i risultati degli scripts in pdf che verranno costruiti facendo girare il programma precedente.
period_prove_test (1)
Si aggiungono qui i relativi tre grafici FIG.A, FIG.B, FIG.C costruiti dal programma precedente, e la successiva FIG.D, che illustra, alla rinfusa, l’appunto relativo alla formulazione delle due armoniche costruite su ampiezze e fasi dei risultati.
FIG.D
DA QUI IN POI QUALCOSA ANCORA DA CONTROLLARE
PER VEDERE LA PRIMA VERSIONE DEL PRECEDENTE PROGRAMMA IN PDF
CLICCARE SOTTO:
function_period_ok_3_richiami_result-p_pistoia-1 (1)
LA NUOVA VERSIONE DEL PRECEDENTE PROGRAMMA CON IN USCITA 12
GRAFICI SI TROVA CLICCANDO SU:
function_period_ok_3_richiami_result-p_pistoia (1)Una volta compreso come richiamare e come gestire i risultati
della function del periodogramma,
ora siamo in grado di continuare di volta in volta la
correzione.
#In ogni caso gli scripts dei programmi presentati in R possono essere trasferiti, anche
#un pezzo alla volta, direttamente sulla console di R con Copia-Incolla: il programma inizierà
#nell'immediato a girare costruendo risultati e grafici i cui
significati sono riassunti
#nei remarks.
Ho scritto le precedenti routines che sembrano funzionare, come si vede dai risultati, considerando il periodogramma come una function, una specie di subroutine. Sarò costretto comunque a rimettere in discussione con calma altri programmi in R che contengono questa function tenendo conto dei cambiamenti!
CHI VOLESSE PUO’ VEDERE ANCHE GLI SCRIPTS DELLO STESSO AUTORE RELATIVI AL PERIODOGRAMMA E ALL’ANALISI DI FOURIER IN MATHEMATICA DI WOLFRAM VERS. 4.2, per fare un controllo dei risultati. Sono inseriti nelle appendici.
IL CONTROLLO DEI PROGRAMMI IN R CHE SEGUONO E’ QUASI COMPLETATO
AD MAIORA
CHIUSA PARENTESI
________________________
6_CENNO A COMANDI IN R DI CALCOLO E ORGANIZZAZIONE DEI DATI
Filter, matrix e ts di R. Discussione sui comandi di calcolo ed organizzazione sui dati. Commento sulle prime istruzioni di R (file di dati). Processi per automatizzare i “i conti”.
Si usa la funzione ts di R che riorganizza direttamente la serie originale (yt o as1) in 12 colonne (mesi) e 5 righe (anni) per il calcolo poi con un for delle medie di tutti i Gennaio, di Febbraio…
Discussione su filter
Applico direttamente la funzione Filter di R, sempre sulla serie originale (yt o as1), che, eliminando da essa (cioè da as1) la componente stagionale di ordine 12 + random, cambia contenuto in TREND + Ciclo + random? (divenendo la asf12). Trovo poi la retta di regressione su asf12, i cui valori delle sue ordinate verranno tolti dalla serie originale; faccio il grafico di asf12 + retta di regr . Da controllare meglio. Smussando la yt, la asf12 è senza random? Vedere dopo gli script.
SEGUE IL COMMENTO SULLE LE PRIME ISTRUZIONI DI R PER AUTOMATIZZARE I ‘CONTI’ DEL PROCESSO RIASSUNTO IN PRECEDENZA CHE ESPANDEREMO IN UN SECONDO TEMPO
I PRIMI INTERVENTI IN R
I primi passi nella schermata iniziale di R consistono nel caricare le Librerie suppletive di R necessarie a fornire i comandi, oltre a quelli di base, per gestire ed elaborare i dati sperimentali. Con la funzione getwd() capisco dove ‘guarda’ R (cioè qual è la directory di lavoro) per cercare il file-dati da caricare e la funzione setwd (directory) permette di cambiare tale directory di lavoro. Fatta conoscere ad R la directory di lavoro, gli facciamo leggere il file-dati scelto per l’analisi (con il comando read.csv); nella fattispecie “As-Carlina1.csv”; la funzione file.show(“nome file.csv”) permette di visionare il contenuto del file che in generale è una matrice con righe e colonne è cioè un data.frame a cui si attribuisce un nome (per es., frame) e di cui è possibile conoscere le dimensioni col comando dim() o estrarre elementi. Le righe della matrice sono le osservazioni o casi; le colonne sono i campi o variabili. Con frame$variable si vuol dire di estrarre la variabile chiamata variable dal data.frame chiamato frame; frame[1,] significa prendere la prima riga, mentre frame[,3], prendere la terza colonna e così via. L’espressione summary(frame$variable) trova tutti i valori della variabile variabile contenuti nel data.frame chiamato frame. Così summary(frame[,3]), trova tutti i valori della colonna 3.
library (stats)
library(tseries)
library(lattice)
#library(graphics)
#getwd()
#setwd(“E:/R-2.12.2/bin/i386”)
# Se conosco dove è memorizzato il file con i dati da analizzare e la sua struttura
# utilizzo questi scripts iniziali
#as=read.csv(“As-Carlina.csv”)
#as1=as[,5]
#leggo la quinta colonna del data.frame: As-Carlina.csv dove c’è appunto yt
#as1=ts(as1) # considero as1 una serie storica
#ts.plot(as1) # plotto as1
Introdurremo invece direttamente la Serie yt o as1
7 – ECCO QUELLO CHE FAREMO CON R: ‘LETTURE’ SUI PROCESSI (‘CACCIA AI RESIDUI’ compresa)
ECCO QUELLO CHE FAREMO CON R
RIORGANIZZAZIONE DELLA SERIE STORICA MENSILE LUNGA CINQUE ANNI, As1, IN DODICI COLONNE (mesi) E CINQUE RIGHE (anni) E BREVI LETTURE SUCCESSIVE
Il primo passo è riorganizzare la serie storica mensile della durata di 5 anni (5×12=60 mesi), in 12 colonne (mesi) e 5 righe (anni).
In ogni colonna ci sono 5 valori di ogni mese: nella prima, i 5 valori di gennaio, nella seconda, i 5 di febbraio e così via, Questo insieme costituisce il file as1.ts1. Per costruire as1.ts1 si può con R operare in almeno due modi. Una volta costituita la classificazione as1.ts1, si usa la funzione ts che permette poi tramite la subas, di meccanizzare con un for il calcolo delle dodici medie riferite ad ogni mese per i 5 anni (vedere dopo).
In sintesi con ts, che ha come argomenti: file, start e frequency, raggruppo i dati con i valori di ogni mese nella stessa colonna. Nella tabella appaiono il nome dei mesi su ogni colonna e il nome degli anni ad ogni riga; siamo così in grado di prendere i cinque dati di ogni mese (uno ogni dodici) per farne la media.
as1.ts1=ts(as1,start=1989,frequency=12)
Questa espressione fa anche la media di ogni colonna?
subas=as1.ts1[seq(1, length(as1), by=12)]
subas raccoglie i dati di gennaio per i 5 anni e ne fa la media(0.064); per ulteriori elaborazioni si può automatizzare con for.
Con for ottengo le 12 medie di ogni mese per 5 anni, mettendo un i al posto di 1 nell’argomento.
Guardiamo come.
mediamesi=c()
for(i in 1:12){mediamesi[i]=mean(as1.ts1[seq(i,length(as1),by=12)])}
ts.plot(mediamesi)
Se togliamo dal vettore mediamesi la media di as1, si ottiene una sorta di Effetto Stagionale mensile.
Mediamesi0=c()
Mediamesi0 =(mediamesi – mean(as1)) # da errore!
ts.plot(mediamesi0) # da errore! In effetti (vedere gli scripts al termine), non so perchè, sono necessarie variabili intermedie.
Vedremo dopo altri modi per il calcolo dell’Effetto Stagionale attraverso una Media Mobile e la funzione filter su as1, ambedue di ordine 12, modificando la stessa as1 o yt, in Mbt e asf12 di 12 termini più corte rispettivamente, contenenti ambedue almeno TREND lin.+ Ciclo (il random plausibilmente si cancellerebbe nel processo). La serie originale era pensata costituita da componente stagionale + TREND_ lin. + ciclo + random.
Calcolo la Media Mobile di ordine 12 su yt o as1; trovo la serie Mbt di 12 termini più corta, che è yt smussata della stagionalità, che serve a calcolare l’Effetto Stagionale, passando attraverso la sottrazione yt – Mbt , chiamata STRD (stagionalità più random: Tabella 1, colonna 7, APPENDIX 3).
yt=as.vector(yt): n=length(yt); Mbt=c()
for(t in 7:n){Mbt[t] = (yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+(yt[t+6])/2)/12}
Mbt # di 12 termini più corta: 6 NA all’inizio e 6 NA alla fine, in tutto 48 dati (yt o as1 erano 60)
Mbt=Mbt[7:54]# elimino da Mbt gli NA; se i dati iniziali iniziavano da gennaio, Mbt inizia da un luglio e termina a un giugno
In alternativa applico il filter di ordine 12 su as1 o yt:
asf12=filter(yt, filter=rep(1/13,13)) # 12 o 13?
asf12
asf12=asf12[7:54] # elimino da asf12 gli NA
Le deboli differenze fra Mbt e asf12 è facile siano dovute alla Media Mobile manuale che è centrata.
Scorcio la as1 di 6 valori iniziali e finali per renderla lunga come Mbt e poi vi sottraggo Mbt:
STRD=as1[7:54] – Mbt # il primo valore di STRD corrisponde a luglio del primo anno.
Ciò significa: STRD= (ciclo+TREND+stagionalità+random) – (ciclo+TREND)=stagionalità+random; 60-12=48 termini.
Si calcola ora il Fattore Stagionale mensile (Tabella 1, colonna 8; 12 termini, APPENDIX 3) agendo con la funzione matrix su STRD e successivamente con colMeans: metto STRD (48 termini) sotto forma di matrice con dodici colonne (mesi) e 4 righe (anni)
stag = matrix(STRD, ncol=12, byrow=T)
Su questa matrice col comando colMeans posso trovare le 12 medie dei 4 valori, una per ogni mese, che metto in mediacol:
mediacol = colMeans(stag) # in mediacol rimangono i random?
Ordino le 12 medie ottenute, che iniziano da luglio del primo anno e terminano a giugno dell’anno successivo, da gennaio a dicembre:
mediacol=(mediacol[7:12],mediacol[1:6]) # Controllare se funziona!
mediacol # detto talora Fattore Stagionale
Copro poi i 5 anni ripetendo questi 12 valori:
ESAs = rep(mediacol,5) # Effetto stagionale di yt o as1
ESAs # serie lunga come yt o as1 originale
Dobbiamo ora togliere da yt o as1 l’Effetto Stagionale trovato per ottenere la serie iniziale destagionalizzata (stg, detta anche y1t o dst; Tabella 2, colonna 2) :
stg=c() #forse è meglio chiamala dst o y1t al posto di stg
# Di fatto questa istruzione stranamente dava errore; forse è necessario introdurre variabili intermedie (vedere scripts relativi dopo). Controllare meglio!
# dst <- c(as1–ESAs) # TREND+ciclo_random #ancora da rifletterci!
dst # è la serie originale destagionalizzata (in altre occasioni chiamata y1t). Di questa disegno il correlogramma: i dati sono autocorrelati; la statistica DW , per K= 1, N=60, rischio 0.05, cade a sinistra dell’intervallo dl-1.62 e si intravede la presenza di un TREND positivo (GRAF. N.4 a); dal periodogramma è sparito completamente il picco di frequenza 5 (periodo 60/5) dell’oscillazione stagionale (GRAF. N.4 b), presente invece nel periodogramma della serie originale (GRAF. N.2 b) e nell’ESAs (GRAF. N.3 b).
y1t=dst
6-7 LA ‘CACCIA’ AI RESIDUI
Potremmo tentare di togliere da dst o y1t (TREND+ciclo_random) i random, provando a perequare con una Media Mobile 3*3 (pesata 1,2,3,2,1) per cui l’yt_smussato verrebbe a contenere ciclo+TREND che, tolto da dst o y1t, dovrei ottenere i random, se le ipotesi iniziali fossero giuste (vedere il testo di questi scripts già in Blocco Note con i risultati relativi, nel paragrafo prima delle Appendici (SECONDA PARTE). Alcuni ricercatori infatti propongono medie mobili a tre o 5 termini pesati 12321, per eliminare i random! PROVIAMO invece il tentativo più classico che Segue:detrendizziamo linearmente la dst o y1t, sottoponendola ad una regressione lineare semplice (RLS)…
8 – INIZIO COPIA SCRIPTS DEL PROGRAMMA CENTRALE Vari commenti possibili e riflessioni alternative
INIZIANO GLI SCRIPTS DEL PROGRAMMA RELATIVO A TUTTO IL PROCESSO DESCRITTO E DISCUSSO IN PRECEDENZA
Da copiare sul Blocco Note con copia/incolla e poi sulla consolle di R (o direttamente su R). In generale i programmi scritti in R o si fanno girare scrivendo una istruzione dietro l’altra , oppure, per es., si copiano gli scripts sul Blocco Note od altro semplice programma di scrittura (anche quelli indirizzati ad R), con copia/incolla e poi sulla consolle di R.
Altro problema in R, quando si copiano programmi pronti dal Blocco Note, è quello di gestire la visione dei diversi grafici, man mano che il programma gira. In questo caso è necessario che il programma controlli i grafici nel senso, per es., di far fermare il programma all’apparire del grafico nella finestra grafica, nella attesa della pressione di un tasto. Per questo esiste un semplice comando, da inserire, per es., all’inizio degli scripts, che ha la sintassi: par(ask=T). Si può utilizzare in alternativa o insieme il comando par(mfrow=c(x,y) , che divide l’unica finestra grafica in x*y parti; x=2 e y=3, la finestra rimane divisa in 6 parti e può contenere 6 grafici e così via.
COMMENTO
Il seguente programma è stato utilizzato da prima nell’analisi della serie As originale, nel modo come era nato, cioè iniziando il lavoro con l’applicare la media mobile direttamente sulla serie originale, arrivando però ad una serie residuale che può non rispettare i criteri richiesti (rivedremo i passaggi). Questo primo modo è quello che per ora continua a venire presentato e commentato.
Per osservare il percorso che parte invece, forse più giustamente, dalla serie detrendizzata (il trend in una serie può ‘disturbare’ il computo dell’Effetto Stagionale?), basta sostituire nel vettore as1, invece dei valori originali, i valori della serie detrendizzata, nel nostro caso per es. copiati dai programmi del Mathematica di Wolfram (Appendix 5) o dall’altro post ‘Verso il periodogramma’, sempre dello stesso autore o… si rifaccia il conto. Basta togliere il cancelletto (#) all’as1 che riporta i valori della serie detrendizzata e ‘cancellettando’ invece i valori dell’as1 che riporta quelli della serie originale (e viceversa). I risultati ipoteticamente dovrebbero migliorare. Proviamo.
Col tempo e la pazienza è possibile che riporti, in un link, il programma in pdf che, in as1, ha i suoi valori detrendizzati, con più di una decina di grafici relativi, con risultati e commenti! Vedere sopra la prima versione.
#alfa=-pi/2 -> 270°; alfa=-1.175 rad (cioè -100°) -> 260°
#INIZIO FUNCTION
PRDGRAM<- function(y1,n1,m1) {
# VALORI DEL PARAMETRO ak
a0=c(); k=0; a0=0;
for(t in 1:n1){a0=a0+y1[t]*cos(2*pi*t*k/n1)}
a0
a0=a0*2/n1;a0=a0/2
a0
a=c();a[1:m1]=0;
for(k in 1:m1) {
for(t in 1:n1){
a[k]=a[k]+y1[t]*cos(2*pi*t*k/n1)}}
a=2*a/n1
# vALORI DEL PARAMETRO bk
b=c();b[1:m1]=0;b0=0;k=0
for(k in 1:m1) {
for(t in 1:n1){
b[k]=b[k]+y1[t]*sin(2*pi*t*k/n1)}}
a <- as.vector(a)
for(i in 1:m1){
if (abs(a[i]) < 1e-10) a[i]=0 else a[i]=a[i]}
a
for(i in 1:m1){
if (abs(b[i]) < 1e-10) b[i]=0 else b[i]=b[i]}
b=2*b/n1
b
# AMPIEZZE
#ro[1:m1]=0
ro <- sqrt(a^2 +b^2)
for(i in 1:m1){
if (abs(ro[i]) < 1e-10) ro[i]=0 else ro[i]=ro[i]}
# CALCOLO DELLA FASE DI OGNI ARMONICA
# RIPORTANDO IL VALORE AL QUADRANTE GIUSTO
f2=c()
f2[1:m1]=0
for(i in 1:m1){
f2[i] <- abs(a[i]/b[i])
f2[i] <- atan(f2[i])*180/pi}
f2 =as.vector(f2)
f2
#f2[1:m1]=0 un f2[1:m1] di troppo!
phi <- c()
for(i in 1:m1){
# f2 <- abs(a[i]/b[i]);
# f2 <- atan(f2)*180/pi;
if(b[i]>0 & a[i]>0) phi[i] = f2[i];
if(b[i]<0 & a[i]>0) phi[i] = 180-f2[i];
if(b[i]<0 & a[i]<0) phi[i] = 180+f2[i];
if(b[i]>0 & a[i]<0) phi[i] = 360-f2[i];
if(b[i]==0 & a[i]==0) phi[i] = 0;
if((b[i]<0 & b[i]>0) | a[i]==0) phi[i]=0;
if(b[i]==0 & a[i]>0) phi[i]=90;
if(b[i]==0 & a[i]<0) phi[i]=360-90
}
# PHI FASE ARMONICHE
phi=as.vector(phi)
phi
param_a <-a
param_b <-b
ampiezza <- ro
fase <- phi
# Qui, al termine della function si pone il valore di un’unica
# variabile che esce o, se escono più variabili, si usa
# un data.frame: data=data.frame(x1,x2,…).
# Ogni chiamata alla function permette di includere l’unica
# variabile o i data nel nome della chiamata:
# es. periodxx=nome.function(x1,x2,…)
data <-data.frame(a,b,ro, phi)
data
# questa matrice esce dalla function e viene ‘raccolta’ nella variabile nomexx (es.,periodxx)
}
#FINE FUNCTION
#Per richiamare la function:
#nomexx = PRDGRAM(Nome_var_vettore dati, numerosità del campione, numero di armoniche da cercare)
yt=as1
yx=as1
nx=length(yt)
#periodogramma yt
if (nx/2== nx%%2) mx=nx/2-1 else mx=(nx-1)/2 #da controllare se non sia necessario uno swap!
period_as1= PRDGRAM(yx, nx ,mx)
#par(mfrow=c(1,4))
#plot(a, xlab="Armoniche = N° osc. in n dati")
#plot(b, xlab="Armoniche = N° osc. in n dati")
period_as1 # tabella dei dati in uscita: ak, bk, ampiezze, fasi
# Con questa tabella si costruiscono le formule analitiche delle armoniche
period_as1$ro # vettore delle ampiezze
plot(period_as1$ro,type="l",main="GRAF. N.2; a-period_yt",
xlab="Armoniche = N° oscill. in n dati", ylab="ampiezza")
par(mfrow=c(1,4))
plot(period_as1$a,ylab="Parametro a")
plot(period_as1$b,ylab="Parametro b")
plot(period_as1$ro,type="l",main="PERIODOGRAMMA di as1",
xlab="Armoniche = N° osc. in nx dati", ylab="ampiezza")
plot(period_as1$phi,type="l", ylab="Fase")
#Per vedere i risultati trasferiti dalla consolle di R in pdf
#del precedente frammento di programma cliccare sotto:
As1_corr_R - P. Pistoia
par(mfrow=c(1,1))
as1.ts1=ts(as1,start=1989,frequency=12)
subas=as1.ts1[seq(1,length(as1),by=12)]
#-----------------------------------------------
# Gli scripts che riguardano il calcolo delle variabili vettoriali mediamesi e Mmesio per ora sono esclusi.
#mediamesi=c()
#for(i in 1:12){mediamesi[i]=mean(as1.ts1[seq(i,length(as1),by=12)])}
#ts.plot(mediamesi,main”mediamesi in 5 anni”)
#Mmesi0=c()
#a=mediamesi
#b=mean(as1)
#c=a-b
#Mmesi0=c () 12 valori medi meno la media serie originale; una specie di Effetto Stagionale
#Mmesi0=mediamesi – mean(as1)
#ts.plot(Mmesi0) # da controllare: Effetto Stagionale da confrontare con mediacol
#acf(Mmesi0, main=”CORR_Mmesi0″)
#Mmesi0 # da confrontare con mediacol
#—————————————————————————–
yt=as1
yt=as.vector(yt); n=length(yt); Mbt=c()
for(t in 7:n){Mbt[t] = (yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+
Sembra che in questo processo CLRD (residui) non siano random e siano correlati (da provare altri tests). Proviamo però a fare altre misure di controllo. Se è così percorriamo altre vie già accennate. Possiamo partire col detrendizzare la serie originale as1, rendendola nelle previsioni stazionaria, e procedere con gli stessi scripts già usati.
Se ai dati originali di as1 sostituiamo i dati originali senza però il trend rettilineo (serie originale detrendizzata, nelle previsioni resa stazionaria), possiamo vedere che cosa accade. In effetti sembrerebbe che, se invece partiamo coll’applicare una media mobile di ordine 12 su una serie non stazionaria, si possa arrivare a questo risultato.
Se si parte con una detrendizzazione (serie stazionaria) e poi si applica la media mobile per trovare gli Effetti Stagionali, che togliamo dalla serie originale, e si procede con successiva detrendizzazione su serie_originale- Eff. Stag., si prevede un aumento dell’ R-quadro e forse un risultato più idoneo.
Si fa prima una regressione sulla serie di partenza; attraverso una media mobile si cercano gli Effetti Stagionali che togliamo dalla serie originale (la non stazionarità può disturbare gli effetti stagionali), ottenendo la serie originale destagionalizzata; si fa infine una seconda regressione su questa differenza, cioè sulla serie destagionalizzata, che può contenere appunto TREND + CICLO_RANDOM, ricavando poi il CICLO_RANDOM (da verificare).
Altro percorso: analisi dei dati trimestrali della stessa serie as1.
9 – PRIMA PARTE IN SINTESI
PRIMA PARTE IN SINTESI
LA SERIE PEREQUATA Mbt, L’EFFETTO STAGIONALE ESAs, LA SERIE DESTAGIONALIZZATA y1t (dst), LA y1t SMUSSATA: ciclo+TREND (y1ts),
LA COMPONENTE CASUALE O RESIDUI
IL CORRELOGRAMMA, IL TEST DI DURBIN WATSON e di LINMUDHOLKAR
Dopo aver eliminato la componente stagionale (ESAs : APPENDIX3, TABELLA N.2, col.1) dalla serie originale yt (APPENDIX3, TABELLA N.1, col.5) sottraendo yt – ESAs, si ottiene la serie destagionalizzata (dst ovvero y1t: APPENDIX3, TABELLA N.2, col.2). In questa serie sanno rimasti gli eventuali ciclo, TREND e la componente random. Sottopongo quest’ultima al programma CORR : i dati sono autocorrelati positivamente (la statistica di Durbin Watson , per k= 1, N=60 e rischio 0.05, cade a sinistra dell’intervallo dl-du (1.55-1.62) e si nota la presenza un TREND positivo (GRAF. N.4 a); dal periodogramma è completamente scomparso il picco di frequenza 5 (periodo 60/5) dell’oscillazione stagionale (GRAF. N.4 b), presente invece nel periodogramma della serie originale (GRAF. N.2 b) e nell’ESAs (GRAF. N.3 b). Leggere Appendice 1.
Smussiamo la serie y1t o dst con una media mobile pesata 3*3 (1,2,3,2,1), per eliminare la componente casuale. Si ottiene così la serie y1ts (CLTR : APPENDIX3, TABELLA N.2, col.3) che potrebbe contenere nelle previsioni ciclo e TREND (CLTR). Sottraendo da y1t o dst (ciclo+TREND+Random) la serie y1ts che potrebbe contenere ciclo+TREND si dovrebbe ottenere la componente casuale o serie random. Testando tale serie col programma CORR, risulta che essa è rumore di fondo (white noise), avvalorando il processo usato fino a questa fase. Infatti la DW, per k=1, n=60 e alfa =0.05, ha valore 2.57 (vedere tabella Appendice 2) per cui esce dall’intervallo ricavato dalle tabelle dl-du (1.55-1-62): assenza di correlazione interna. la statistica di LIN-MUDHOLKAR, per la gaussiana, per alfa=0.05 e r=+/- 0.403 ricavato dalle tabelle, ha il valore -0.0416, cioè cade all’interno dell’intervallo di r, per cui non posso rifiutare l’ipotesi nulla: la distribuzione dei residui così calcolati è da considerarsi gaussiana. Forse è proprio l’effetto di non aver esplicitata la serie CLTR con il calcolo del TREND a favorire la compatibilità dei residui alle ipotesi iniziali.
MODELLO DI REGRESSIONE LINEARE SEMPLICE (RLS) E TESTS RELATIVI.
ADEGUAMENTO DEL MODELLO DI REGRESSIONE ALLA POPOLAZIONE. COEFFICIENTI DELLA RETTA ED R-q
TEST SU R-q E LA F DI FISHER , TESTS SUI COEFFICIENTI DELLA RETTA, INTERVALLO DI CONFIDENZA.
RESIDUO DELLA REGRESSIONE E L’AFFIDABILITA’.
Applichiamo invece a y1t o y1ts (APPENDIX3, TABELLA N.2, col.2; TABELLA N.2, col.3) ) un modello di regressione per separare il TREND dai loro contenuti. Proviamo una regressione lineare con la sola variabile, il tempo, misurato in mesi (un solo regressore, k1=1 nelle tabelle DW), senza preoccuparci per ora se tale modello sia idoneo. Lo controlleremo dall’analisi dei residui. Se sono rispettate le assunzioni di linearità, una buona misura dell’adeguamento del modello lineare ai dati è il Coefficiente di Determinazione R-quadro. La sua radice quadrata R è il Coefficiente di correlazione di Pearson detto anche Multiple-R. Se R-q è 1, significa che tutte le osservazioni cadono sulla retta di regressione; se zero, nessuna associazione lineare fra le variabili, anche se può esserci una relazione non lineare. R-q può così essere interpretato come la proporzione della variazione di y ‘spiegata’ dal modello , come precisato in altre occasioni. Su y1t o su y1ts, si opera con una regressione lineare calcolando bo e b1 ed ottenendo in ambedue i casi, come era prevedibile, differendo le due serie per la sola componente casuale, la stessa retta di regressione seguente (APPENDIX3, TABELLA N.3, col.8 e APPENDIX3, TABELLA N.4, col.3 per i valori previsti):
y_predetto = TREND = TREND’ = 0.051 + 0.00005*t
Vedere APPENDIX3, TABELLA N.3, col.5, per i risultati intermedi al fine del cacolo dei coefficienti della retta.
Nel nostro caso R-q = 0.44, cioè il modella spiega il 44% della variazione complessiva della variabile dipendente. Per controllare l’ipotesi nulla che nella popolazione non esista relazione lineare (R-q_pop.=0), si procede con l’analisi della varianza. Per tutti i particolari dei ‘conti’ che seguono vedere, per es., il Post ‘Un percorso verso il periodogramma’ su questo stesso BLOG. Seguendo le indicazioni riportate nel paragrafo relativo a questo argomento nel Post su nominato, si ottiene la seguente tabella:
GL SOMMA DEI QUADRATI MEAN SQUARE
Variazione di regressione 1 0.00435 0.00435
Variazione residuale 58 0.00559 0.000096
TOT 0.00994
da cui: Somma quadrati reg./Somma quadrati tot = 0.44, cioè R-quadro.
La statistica F di Fisher che permette di saggiare l’ipotesi nulla: R-quadro pop.=0, è 0.00435/0.000096 = 45.31, da cui, riportata sulle tavole con 1 e 58 gradi di libertà (GL), si ricava una significanza per F minore di 0.00001, per cui si respinge l’ipotesi nulla e nella popolazione esisterà con alta probabilità una relazione lineare.
Procedendo ancora a prove incrociate si può testare l’ipotesi che b1_pop. =0; si calcola la statistica T per b1: pendenza/errore standard_pend, ottenendo ERb1=7.31*10^-5 perché b1=0.000492, risulta T=6.73, che dalle tabelle relative per 58 gradi di libertà (GL=N-2) si ha una significanza per T di 0.0000..<<0.05, per cui si respinge l’ipotesi nulla che la pendenza della popolazione sia zero (quindi esiste dipendenza lineare).
Procedendo, nell’intervallo di confidenza al 95% per la pendenza non potrà allora il valore zero. Infatti calcolando ESb1 come suggerito da altri interventi (0.000073), l’intervallo di confidenza al 95% per beta1 risulta (con 58 GL):
b1-1.96*ESb1 <= beta1 <= b1+ 1.96*ESb1
0.00492-0.00014 <= beta1 <= 0.00492+0.00014
0.00035 <= beta1 <=0.00063
Si vede chiaramente come i vari tests, se affidabili, confermano la presenza di un trend lineare nei dati.
Togliendo da y1t la serie del trend, si otterrà la serie CLRD ( APPENDIX3, TABELLA N.4, col.4) con l’eventuale ciclo + la componente casuale (random) I residui della regressione, per il modo con cui abbiamo proceduto, sono proprio i valori della serie CLRD. E’ prevedibile che questa serie, se davvero includerà una componente ciclica significativa,non risulterà rispetterà almeno qualche condizione fra quelle ipotizzate sui residui (indipendenza, varianza costante…). procederemo ad investigare questa serie sui residui. Applicando ad essi il programma CORR, otteniamo il grafico, GRAF. N.5 a) correlogramma) e 5b (periodogramma), il test per l’indipendenza di Durbin Watson e quello per la normalità di Lin Mudholkar. Il valore di DW è risultato 1.378, che (N=60, K’=1 e alfa =0.05) esce a sinistra dell’intervallo 1.55-1.62 e quindi l’autocorrelazione è positiva, mentre il test per la gaussiana (rischio 0.05, N=60, r=+/-0.403, fornisce rc=-0.0298, cioè all’inteno dell’intervallo, per cui non posso rifiutare l’ipotesi nulla (la serie ha distribuzione gaussiana). Graficando i residui standardizzati con la variabile pred pure standardizzata, si ottiene il GRAF. N. 6 a dove non appaiono patterns evidenti. Dal GRAF. N.6 b invece, ottenuto riportando i residui per ogni unità di tempo, si evidenzia una qualche variazione della varianza dei residui (eteroscedasticità, variazione a clessidra). Allora i tests che fanno riferimento al comportamento della popolazione universo (in particolare gli F-tests) possono non essere affidabili e quindi incerto il modello di regressione usata.
Al termine dell’analisi con un modello di regressione lineare semplice, tenteremo ulteriori approfondimenti alla ricerca di un maggiore R-quadro, ma specialmente di una maggior concordanza dei residui alle condizioni iniziali (linearità, normalità, indipendenza, omoscedasticità).
i
10 – SECONDA PARTE IN SINTESI
SECONDA PARTE IN SINTESI: UN ALTRO TENTATIVO SULLA CACCIA AI RESIDUI (senza passare attraverso una regresssione)
SCRIPTS IN BLOCCO NOTE: DA COPIARE DIRETTAMENTE SULLA CONSOLLE DI R
# Intanto trascriviamo nel vettore yt i 60 dati della conc. As da cui partire. Impariamo poi a calcolare con R gli altri 5 vettori dati che faranno parte dell'analisi della nostra serie
# reale e quindi della nostra esercitazione. Calcoliamo come primo vettore Mt (media mobile di ordine 12 su yt.
yt=c(.033,.043,.051,.059,.061,.063,.053,.036,.046,.056,.063,.048,.053,.043,.066,.053,.082,.06,.08,.076,.056,.036,.05,
.053,
.056,.058,.061,.063,.065,.068,.0815,.095,.079,.063,.069,.074,.08,
.0765,.073,.0695,.066,.093,.083,.073,.063,.074,.067,.06,.086,.08,.073,.067,.089,.064,.087,.079,.07,.065,.06,.063)
t=1
#Come primo passo grafichiamo i dati e osserviamo se ci sono regolarità all'interno (trend, oscillazioni), precisiamo le ipotesi con un correlogramma ed un periodogramma, I dati sono mensili: Ipotizziamo comunque una oscillazione di periodo 12.
# Calcoliamo, come primo vettore, Mt (media mobile centrata e pesata di ordine 12 su yt).
yt=as.vector(yt) ; n=length(yt); Mt=c()
for(t in 7:n){Mt[t] = (yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+
yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+(yt[t+6])/2)/12}
Mtc=Mt[7:54]
mt=filter(yt,filter=rep(1/13,13))
# calcolo della Mm col comando filter di R: confrontare i due risultati
mt #OK
# in Mt ci sono i 48 (60-12) dati Media mobile di yt, da cui costruisco i 12 Fattori Stagionali (FStag)
facendo la media dei 4 gennaio, dei 4 febbraio ecc. a partire da luglio, perchè Mt iniziava con luglio.
FSTag0 = matrix(Mtc, ncol=12, byrow=T)
# matrice di 4 righe (valori dei 12 mesi dei 4 anni) e 12 colonne con in ognuna le 4 conc. dei mesi dello stesso nome a partire da un luglio.
FStag1=colMeans(FSTag0)
# in FStag1 trovo le 12 medie dei 4 mesi dello stesso nome (inizio luglio, fine giugno)
FStag=c(FStag1[7:12], FStag1[1:6]) # da controllare! Ordino da gennaio. OK
ESAs=rep(FStag,5) # EFFETTO STAGIONALE As
ESAs # 60 dati
Yt1=yt-ESAs # Ciclo+Trend+Random
Yt1 # 60 dati
Yt1c=Yt1[3:58]
Yt1s=c()
for(i in 1:60){Yt1s[i]=(Yt1[i-2]+2*Yt1[i-1]+3*Yt1[i]+2*Yt1[i+1]+
Yt1[i+2])/9}
Yt1s=as.vector(Yt1s) # smusso Yt1 con Mm 3*3
ns=length(Yt1s) # più corto di 4 elementi
Yt1s # yt1 senza random; cioè Ciclo+Trend
par(ask=T)
Yt1s=Yt1s[3:(ns-2)]
RD=Yt1c-Yt1s # forse si tratta solo di random: il Ciclo?
#Riportiamo in una tabella 1 5 vettori dell'analisi su yt
#data <- data.frame(t,yt,ESAs,Yt1,RD)
# Facciamo i 5 correlogrammi dei vettori trovati: yt, ESAs, Yt1, Yt1s, RD
coyt=acf(yt)
coyt
coESAs=acf(ESAs)
coESAs
coYt1=acf(Yt1)
coYt1s=acf(Yt1s)
coYt1s
coRD=acf(RD)
coRD
# Interessante abbinare il correlogramma con il periodogramma e da controllare i correlogrammi con il programmino scritto dall'autore
RISULTATI DEL PROGRAMMA PRECEDENTE (come si vede gira senza errori!)
> # Interessante abbinare il correlogramma con il periodogramma.
> # Intanto trascriviamo nel vettore yt i 60 dati della conc. As da cui partire. Impariamo poi a calcolare con R gli altri 5 vettori dati che faranno parte dell'analisi della nostra serie
# reale e quindi della nostra esercitazione. Calcoliamo come primo vettore Mt (media mobile di ordine 12 su yt.
>
> yt=c(.033,.043,.051,.059,.061,.063,.053,.036,.046,.056,.063,.048,.053,.043,.066,.053,.082,.06,.08,.076,.056,.036,.05,
+ .053,
+ .056,.058,.061,.063,.065,.068,.0815,.095,.079,.063,.069,.074,.08,
+ .0765,.073,.0695,.066,.093,.083,.073,.063,.074,.067,.06,.086,.08,.073,.067,.089,.064,.087,.079,.07,.065,.06,.063)
>
> t=1
>
> #Come primo passo grafichiamo i dati e osserviamo se ci sono regolarità all'interno (trend, oscillazioni), precisiamo le ipotesi con un correlogramma ed un periodogramma, I dati sono mensili: Ipotizziamo comunque una oscillazione di periodo 12.
>
> # Calcoliamo, come primo vettore, Mt (media mobile centrata e pesata di ordine 12 su yt).
>
> yt=as.vector(yt) ; n=length(yt); Mt=c()
> for(t in 7:n){Mt[t] = (yt[t-6]/2+yt[t-5]+yt[t-4]+yt[t-3]+yt[t-2]+
+ yt[t-1]+yt[t]+yt[t+1]+yt[t+2]+yt[t+3]+yt[t+4]+yt[t+5]+(yt[t+6])/2)/12}
> Mtc=Mt[7:54]
>
> mt=filter(yt,filter=rep(1/13,13)) # 13 o 12?
> # calcolo della Mm col comando filter di R: confrontare i due risultati
> mt #OK
Time Series:
Start = 1
End = 60
Frequency = 1
[1] NA NA NA NA NA NA
[7] 0.05115385 0.05192308 0.05369231 0.05384615 0.05561538 0.05553846
[13] 0.05684615 0.05861538 0.06015385 0.05938462 0.05892308 0.05815385
[19] 0.05876923 0.05915385 0.06053846 0.06030769 0.06123077 0.06015385
[25] 0.06180769 0.06296154 0.06319231 0.06373077 0.06626923 0.06811538
[31] 0.07019231 0.07176923 0.07292308 0.07357692 0.07380769 0.07596154
[37] 0.07711538 0.07646154 0.07400000 0.07361538 0.07392308 0.07323077
[43] 0.07415385 0.07415385 0.07388462 0.07342308 0.07492308 0.07476923
[49] 0.07430769 0.07400000 0.07376923 0.07392308 0.07284615 0.07253846
[55] NA NA NA NA NA NA
>
> # in Mt ci sono i 48 (60-12) dati Media mobile di yt, da cui costruisco i 12 Fattori Stagionali (FStag) facendo la media dei 4 gennaio, dei 4 febbraio ecc. a partire da luglio, perchè Mt iniziava con luglio.
> FSTag0=matrix(Mtc, ncol=12, byrow=T)
> # matrice di 4 righe (valori dei 12 mesi dei 4 anni) e 12 colonne con in ognuna le 4 conc. dei mesi dello stesso nome a partire da un luglio.
> FStag1=colMeans(FSTag0)
> # in FStag1 trovo le 12 medie dei 4 mesi dello stesso nome (inizio luglio, fine giugno)
> FStag=c(FStag[7:12], FStag1[1:6]) # da controllare! Ordino da gennaio. OK
> ESAs=rep(FStag,5) # EFFETTO STAGIONALE As
> ESAs # 60 dati
[1] 0.06147115 0.06221154 0.06285577 0.06317308 0.06323077 0.06334615
[7] 0.05878846 0.05965385 0.06022115 0.06050962 0.06085577 0.06113462
[13] 0.06147115 0.06221154 0.06285577 0.06317308 0.06323077 0.06334615
[19] 0.05878846 0.05965385 0.06022115 0.06050962 0.06085577 0.06113462
[25] 0.06147115 0.06221154 0.06285577 0.06317308 0.06323077 0.06334615
[31] 0.05878846 0.05965385 0.06022115 0.06050962 0.06085577 0.06113462
[37] 0.06147115 0.06221154 0.06285577 0.06317308 0.06323077 0.06334615
[43] 0.05878846 0.05965385 0.06022115 0.06050962 0.06085577 0.06113462
[49] 0.06147115 0.06221154 0.06285577 0.06317308 0.06323077 0.06334615
[55] 0.05878846 0.05965385 0.06022115 0.06050962 0.06085577 0.06113462
> Yt1=yt-ESAs # Ciclo+Trend+Random
> Yt1 # 60 dati
[1] -0.0284711538 -0.0192115385 -0.0118557692 -0.0041730769 -0.0022307692
[6] -0.0003461538 -0.0057884615 -0.0236538462 -0.0142211538 -0.0045096154
[11] 0.0021442308 -0.0131346154 -0.0084711538 -0.0192115385 0.0031442308
[16] -0.0101730769 0.0187692308 -0.0033461538 0.0212115385 0.0163461538
[21] -0.0042211538 -0.0245096154 -0.0108557692 -0.0081346154 -0.0054711538
[26] -0.0042115385 -0.0018557692 -0.0001730769 0.0017692308 0.0046538462
[31] 0.0227115385 0.0353461538 0.0187788462 0.0024903846 0.0081442308
[36] 0.0128653846 0.0185288462 0.0142884615 0.0101442308 0.0063269231
[41] 0.0027692308 0.0296538462 0.0242115385 0.0133461538 0.0027788462
[46] 0.0134903846 0.0061442308 -0.0011346154 0.0245288462 0.0177884615
[51] 0.0101442308 0.0038269231 0.0257692308 0.0006538462 0.0282115385
[56] 0.0193461538 0.0097788462 0.0044903846 -0.0008557692 0.0018653846
> Yt1c=Yt1[3:58]
> Yt1s=c()
> for(i in 1:60){Yt1s[i]=(Yt1[i-2]+2*Yt1[i-1]+3*Yt1[i]+2*Yt1[i+1]+
+ Yt1[i+2])/9}
> Yt1s=as.vector(Yt1s) # smusso Yt1 con Mm 3*3
>
> ns=length(Yt1s) # più corto di 4 elementi
> Yt1s # yt1 senza random; cioè Ciclo+Trend
[1] NA NA -1.255983e-02 -6.694444e-03 -3.708333e-03
[6] -4.989316e-03 -9.090812e-03 -1.287073e-02 -1.140385e-02 -8.274573e-03
[11] -5.727564e-03 -8.419872e-03 -9.424145e-03 -1.017735e-02 -4.337607e-03
[16] -1.027778e-03 5.958333e-03 8.455128e-03 1.157585e-02 6.129274e-03
[21] -2.070513e-03 -1.060791e-02 -1.194979e-02 -9.530983e-03 -5.979701e-03
[26] -3.955128e-03 -2.004274e-03 -2.777778e-05 3.902778e-03 1.089957e-02
[31] 1.874252e-02 2.179594e-02 1.809615e-02 1.216987e-02 1.027244e-02
[36] 1.208013e-02 1.424252e-02 1.326709e-02 1.032906e-02 9.861111e-03
[41] 1.273611e-02 1.806624e-02 1.824252e-02 1.524038e-02 1.026282e-02
[46] 7.836538e-03 7.827991e-03 9.913462e-03 1.368697e-02 1.393376e-02
[51] 1.377350e-02 1.130556e-02 1.384722e-02 1.478846e-02 1.779808e-02
[56] 1.546261e-02 1.159615e-02 5.836538e-03 NA NA
>
> par(ask=T)
>
> Yt1s=Yt1s[3:(ns-2)]
>
> RD=Yt1c-Yt1s # forse si tratta solo di random: il Ciclo?
>
> #Riportiamo in una tabella 1 5 vettori dell'analisi su yt
>
> #data <- data.frame(t,yt,ESAs,Yt1,RD)
>
> # Facciamo i 5 correlogrammi dei vettori trovati: yt, ESAs, Yt1, Yt1s, RD
> coyt=acf(yt)
Aspetto per confermare cambio pagina...
> coyt
Autocorrelations of series ‘yt’, by lag
0 1 2 3 4 5 6 7 8 9 10
1.000 0.541 0.395 0.223 0.302 0.221 0.330 0.281 0.150 0.102 0.150
11 12 13 14 15 16 17
0.248 0.255 0.308 0.197 0.099 -0.006 0.042
> coESAs=acf(ESAs)
Aspetto per confermare cambio pagina...
> coESAs
Autocorrelations of series ‘ESAs’, by lag
0 1 2 3 4 5 6 7 8 9 10
1.000 0.542 0.187 -0.111 -0.349 -0.460 -0.455 -0.423 -0.309 -0.102 0.146
11 12 13 14 15 16 17
0.433 0.800 0.434 0.150 -0.088 -0.276 -0.362
> coYt1=acf(Yt1)
Aspetto per confermare cambio pagina...
> coYt1s=acf(Yt1s)
Aspetto per confermare cambio pagina...
> coYt1s
Autocorrelations of series ‘Yt1s’, by lag
0 1 2 3 4 5 6 7 8 9 10 11 12
1.000 0.908 0.757 0.610 0.519 0.457 0.396 0.326 0.271 0.256 0.277 0.317 0.335
13 14 15 16 17
0.321 0.263 0.198 0.145 0.123
> coRD=acf(RD)
Aspetto per confermare cambio pagina...
> coRD
Autocorrelations of series ‘RD’, by lag
0 1 2 3 4 5 6 7 8 9 10
1.000 -0.308 -0.166 -0.187 0.222 -0.198 0.195 0.066 -0.089 -0.097 0.014
11 12 13 14 15 16 17
0.004 -0.029 0.147 0.043 -0.114 -0.071 0.046
> # Interessante abbinare il correlogramma con il periodogramma: da fare.
L’EPILOGO
SEGUONO ULTERIORI APPROFONDIMENTI:
APPLICAZIONE DI UNA REGRESSIONE LINEARE MULTIPLA (RLM) OPPORTUNA (variabili "dummy").
COME CALCOLARE LA F DI FISHER NELLE REGRESSIONI RLM.
COME CALCOLARE L'ERRORE STANDARD SUI COEFFICIENTI DI REGRESSIONE NELLA RML
COME SI APPLICA UNA REGRESSIONE LINEARE MULTIPLA PESATA (RLMP)
CHI VOLESSE ESERCITARSI SU ESEMPI RELATIVI AL CALCOLO MATRICIALE APPLICATO ALL'ANALISI DI DATI SPERIMENTALI CERCARE IN QUESTO SITO "TIPS DI SCIENZA" (in particolare sui "conti" relativi alla regressione lineare multipla (MLR).
LO SCRITTO CHE SEGUE E' L'ULTIMA TRANCE DELL'ARTICOLO ORIGINALE CHE RIGUARDA GLI ULTERIORI APPROFONDIMENTI,ELENCATI SOPRA, SCRITTO ANCORA DALLO SCRIVENTE, RIVISITATO E INTERPRETATO CON R IN QUESTO POST. I RIFERIMENTI COME 1.1.2.2 ECC. RIGUARDANO RIMANDI A SUOI PARAGRAFI SPECIFICI. DATA LA NATURA A 'ZIBALDONE LEOPARDIANO DISPERSO' DI QUESTO LAVORO A GETTO ROBINSONIANO CI PROPONIAMO DI INSERIRE LA SECONDA PARTE DELL'ORIGINALE PRIMA DELLE APPENDICI. DOVREMMO SCANNERIZZARLO MEGLIO!
11-L'EPILOGO
14
15
i
i
GRAF. N.9
i
12 -APPENDICE1
APPENDICE1
Il correlogramma ed il test di Durbin-Watson. ([3], 949-953)
Ammettiamo che il lettore conosca il Coefficiente di Correlazione lineare di Pearson, ovvero date N paia di osservazioni su due variabili X e Y, tale Coefficiente di Correlazione fra esse e dato:
Quest’idea viene trasferita alle serie storiche per vedere se osservazioni successive sono correlate.
Date N osservazioni X1, X2,………Xn , in una serie storica discreta possiamo considerare N-1 paia di osservazioni (X1,X2), (X2,X3), . . . ,(X(n-1),Xn), le cui prime osservazioni di ogni paio costituiscono la prima variabile e le seconde, la seconda variabile. Se si applica la formula precedente, dove Xi sarebbe Xt e Yi sarebbe Y(t+1), mentre Xm sarebbe la media della prima variabile (da t=1 a t=N-1) e Ym sarebbe la media della seconda variabile (da t=2 a t=N, in ambedue i casi il numero degli elementi sarebbe N-1. Si otterrebbe una formula complessa con due medie diverse che vengono invece calcolate ambedue sulla serie originaria di numerosita N. Si usa cosi la formula approssimata scritta sotto, estesa al caso in cui si voglia trovare la correlazione tra serie di osservazioni a distanza H fra loro (slittate di h termini o di lag h)
I coefficienti di auto-correlazione rh , dove h=0,1,2…q e q è minore ad uguale a (N-2)/2, sono coefficienti di correlazione, calcolati per ogni valore di h, che misurano la concordanza o la discordanza tra i valori di una serie storica e quelli della stessa però slittati di h unità di tempo (lag h), consentendo di analizzare la sua struttura interna, ossia i legami fra i termini della stessa ([8] 18-20).
rh = Σi[(y(t)-ym)(y(t+h)-ym)]/[(n-h)*Σj(y(t)-ym)^2/n)] dove i va da t=1…n-h e j va da t=1 … n
in alcuni testi viene abolito il fattore n/(n-h).
Tale formula presenta la semplificazione di poter utilizzare una media unica per le Yt (quella dei dati originali), presupponendo una situazione stazionaria ([8] pag.19 e [2] pag.133). In particolare r0 = 1 (lag h =0, nessun slittamento) e gli altri rh assumono valori fra +1 (completa concordanza) e -1 (totale discordanza). Il correlogramma è la rappresentazione grafica dei coefficienti di auto-correlazione in funzione degli slittamenti (lags h) e permette di vedere se la serie storica possiede qualche regolarità interna.
CENNI DI LETTURA DEI CORRELOGRAMMI
-I coeff. di autocorr. di dati random hanno distribuzione campionaria che può essere approssimata da una curva gaussiana con media zero ed errore standard 1//N. Questo significa che il 95% di tutti i coeff. di autocorr. , calcolati da tutti i possibili campioni estratti, dovrebbero giacere entro un range specificato da: zero +/- 1.96 errori standard. I dati cioè della serie saranno da considerarsi random se questi coefficienti saranno entro i limiti:
-1.96 (1/√n)≤ rh ≤ +1.96 (1/√n); la fascia dell’errore: +/- 2/√n
Per l’interpretazione dei correlogrammi vedere ([8] 20-25) da cui ricaviamo le seguenti informazioni.
– Una serie storica completamente casuale, cioè i cui successivi valori sono da considerarsi tutti indipendenti fra loro (non correlati), tutti i valori di rh (eccetto r0 che è sempre +1, correlazione della serie con se stessa) oscilleranno accidentalmente intorno allo zero entro la fascia dell’errore. Se l’idea iniziale era questa in effetti 5 su 100 valori di rh potrebbero superare la fascia dell’errore e se plotto il correlogramma, 19 su 20 valori di rh potrebbero cadere all’interno della fascia, ma ci si potrebbe aspettare che uno possa eesere significativo sulla media. Insomma anche se la serie è casuale, ogni tanto verso lag più elevati potrebbero apparire picchi significativi. Se abbiamo a che fare con un numero elevato di coefficienti, potrebbero apparire risultati non aspettati. Questo rende il correlogramma uno strumento di investigazione incerto.
– I coeff. di autocorr. per i dati stazionari (assenza di TREND) vanno velocemente a zero dopo il 4° o 5° lag di tempo e sono significativamente diversi da zero per i primi lag. Anche su correlogrammi, ai lags più bassi, si possono notare coefficienti di autocorrelazione positivi rapidamente decrescenti e per i lag successivi oscillazioni intorno allo zero. Ciò significa che esiste nella serie una persistenza di valori a breve termine, nel senso che se la grandezza in studio ha valore più elevato della media in un mese, lo sarà anche in uno o due mesi successivi e così per valori inferiori alla media.
-Se la serie storica presenta oscillazioni, anche il correlogramma tende ad assumere valori positivi e negativi, oscillando con lo stesso periodo della serie fino a smorzarsi ai lags più elevati. Se es. esiste un componente stagionale di periodo 12 mesi, nei dintorni del coefficiente di lag 12 ci sarà una zona significativamente diversa da zero.
– Nelle serie non stazionarie (presenza di TREND) i valori di rh non scendono velocemente a zero, ma si mantengono significativi per più valori del lag e solo se l’effetto del TREND è paragonabile alle altre eventuali relazioni presenti nei dati è possibile intuirle nel grafico (GRAFICO. N.2)
IL TEST DI DURBIN WATSON
Così la lettura dei correlogrammi talora può risultare ardua. Un modo veloce, affidabile e quantitativo per testare l’ipotesi che esista all’interno di una serie storica correlazione fra i suoi termini, cioè i termini non siano indipendenti, è somministrare alla serie il test di Durbin Watson ([8] 18-20), la cui statistica è espressa dalla formula:
d =∑ (ei – ei-1)2 /∑ ei2
La sommatoria al numeratore inizia dal 2° termine (i=2) e coinvolge ni termini . La statistica d varia da 0 a 4 e quando l’ipotesi nulla è vera (autocorrelazione assente) d dovrebbe essere vicino a 2. Il test permette di decidere di respingere l’ipotesi nulla, di accettarla o essere inconclusivo. Utilizzando la tabella opportuna (allegata a queste note) si ottengono i valori critici di dl e du che servono per la decisione: all’interno dell’intervallo dl-du, la situazione è incerta; a sinistra di dl , si respinge l’ipotesi nulla. Vedremo in seguito come si calcola d con R e come si usa la tabella.
Il programma CORR, scritto in Qbasic, riportato in nota, permette il calcolo dei coefficienti di autocorrelazione con l’errore (un qualsiasi programma di grafica permetterà di costruire il correlogramma) e il calcolo della statistica di D. W. Abbiamo già visto (vedere programminosul correlogramma) come operare anche con il linguaggio R.
13 – APPENDICE2
APPENDICE2
Programmi in Qbasic e tabelle
PROGRAMMA CORR (coefficienti di autocorrelazione, il test di Durbin Watson, il test di Lin Mudholkar, Analisi spettrale per il periodogramma
i
i
i
i
i
i
i
GRAF. N.9
i
i
14 – APPENDICE3
APPENDIX3
TABELLE DEI RISULTATI
i
i
i
15 – APPENDICE4
APPENDIX4
ANALISI, CON IL LINGUAGGIO R, DELLA SERIE STORICA TRIMESTRALE RIVISITATA E AMPLIATA CON PERIODOGRAMMI E RISULTATI
Residual standard error: 0.008996 on 18 degrees of freedom Multiple R-squared: 0.4767, Adjusted R-squared: 0.4476 F-statistic: 16.4 on 1 and 18 DF, p-value: 0.0007524
Residual standard error: 0.007504 on 18 degrees of freedom Multiple R-squared: 0.5899, Adjusted R-squared: 0.5671 F-statistic: 25.89 on 1 and 18 DF, p-value: 7.671e-05
Far girare il precedente programma. Applicare a detrend_trim il periodogramma e trasformare in formula analitica l’oscillazione o le ascillazioni e provare a toglierla(toglierle) da medietrim (a da detrend _trim) per vedere se spariscono dal loro periodogramma i picchi rilevanti. E’ un buon metodo incrociato di testare il Periodogramma rivisitato.
16 – APPENDICE5
APPENDIX5
IL SENSO COMUNE, L’INSEGNAMENTO SCIENTIFICO ED I SAPERI PREPOSTI ALLE SCELTE – UN PRIMO APPROCCIO OPERATIVO ALL’ANALISI DI FOURIER COL SUPPORTO DEL COMPUTER del dott. Piero Pistoia
Analisi di serie storiche reali e simulate dott. Piero Pistoia
ATTENZIONE! le linee di programma attive non sono incluse fra apici. Cambiando opportunamente le inclusioni di linee nei diversi segmenti del programma, si possono fa girare i diversi esempi, e proporne di nuovi.
A0-Esempio N.0
ANALISI DELL’ESEMPIO N° 0
Le linee attive di questo esempio sono state evidenziate
Si trascriva manualmente o con copia/incolla i seguenti scripts sulla consolle del MATHEMATICA DI WOLFRAM (vers. non superiore alla 6.0); si evidenzi e si batta shift-enter: si otterranno i risultati ed i grafici non inseriti.
"Si forniscono diversi vettori di dati sperimentali di esempio immessi
direttamente o tramite Table; per renderli attivi basta eliminare agli
estremi le virgolette.Se l'analisi diventa più complessa rispetto ad una
ricerca di armoniche di Fourier a confronto con la serie iniziale, si può
utilizzare il SEGMENTO DELLE REGRESSIONI (lineare e quadratica) per ottenere
yg2 ed il SEGMENTO DELLE ARMONICHE RILEVANTI (yg3 e yg4) individuate in una
prova precedente. Abbiamo da sostituire il nome di qualche vettore e aprire o
chiudere (cancellando o inserendo virgolette) istruzioni nei diversi segmenti
del programma secondo ciò che vogliamo fare. In yg1 c'è il vettore dati
iniziale. In yg2 c'è il vettore detrendizzato. In yg3, quello delle armoniche
rilevanti. In v, il vettore di Fourier fornito dall'analisi. Altri segmenti
su cui intervenire: IL GRAFICO ygf dove va inserita la variabile (ygi) da
confrontare con Fourier (v); il segmento di IMPOSIZIONE NUMERO ARMONICHE m;
il segmento di SCELTA VARIABILI DA SOTTOPORRE A FOURIER (ygi); il segmento
per cambiare la variabile nell'ERRORE STANDARD. In ogni esempio si accenna
alle modifiche specifiche da apportare ai diversi segmenti";
"ESEMPIO N.0";
"Esempio illustrativo riportato alle pagine 3-4 dell'art.: imporre il numero \
di armoniche m=1 oppure 2 nel segmento relativo e confrontare il grafico ygf \
che gestisce la variabile yg1 dei dati seguenti, con quello di v (ygf1); \
controllare infine i risultati con i dati del testo";
yt=N[{103.585, 99.768, 97.968, 99.725, 101.379, 99.595, 96.376, 96.469, \
100.693, 104.443}]
"ESEMPIO N.1"
"Si sottopongono a Fourier i dati tabellati seguenti(yg1). Si confrontano yg1 \
(tramite ygf) e v di Fourier(tramite ygf1); calcolo automatico di m";
"yt=N[Table[100+4 Sin[2 t/21 2 Pi-Pi/2]+3 Sin[4 t/21 2 Pi+0]+6 Sin[5 t/21 2 \
Pi-1.745], {t,21}]]"
"Si detrendizza yg1 seguente ottenendo yg2 (si liberino le istruzioni del \
segmento TREND), che poniamo come variabile in ygf (si inserisca nella sua \
espressione); si sottopone yg2 a Fourier (v) nel segmento "SCELTA VETTORE \
DATI"; confrontiamo ygf1 (grafico di v) e ygf; inserire variabile yg2 \
nell'espressione errore"
"yt=N[Table[100+4 Sin[2 t/21 2 Pi-Pi/2]+3 Sin[4 t/21 2 Pi+0]+6 Sin[5 t/21 2 \
Pi-1.745]+0.5 t + (Random[]-1/2),{t,21}]]";
"ESEMPIO N.2";
"Si utilizza il vettore originale yg1 e si confronta con v di Fourier (ygf \
con ygf1), come nell'esempio N.1, prima parte; m automatico. Esempio \
interessante per controllare come Fourier legge i dati"
"yt=Table[N[Sin[2 Pi 30 t/256]+.05t+(Random[]-1/2)],{t,256}]"
"ESEMPIO N.3";
"Come l'esempio N.2. Ci insegna come Fourier <sente> i coseni"
"yt=N[Table[100+4 Cos[2 t/21 2 Pi-Pi/2]+3 Cos[4 t/21 2 Pi+0]+6 Cos[5 t/21 2 \
Pi-1.745],{t,21}]]";
"ESEMPIO N.4";
"Come il N.2. Ci assicura del funzionamento del programma"
"yt= N[Table[100+3 Sin[2 Pi 2 t/21+ Pi/2],{t,1,21}]]";
"I dati successivi sono stati campionati da Makridakis combinando l'esempio \
precedente ed un random (pag. 402, [])";
"yt={106.578,92.597,99.899,97.132,93.121,95.081,102.807,106.944,100.443,95.\
546,103.836,107.576,104.658,91.562,91.661,97.984,111.195,100.127,94.815,105.\
009,110.425}";
"ESEMPIO N.5"
"Prima parte.
Si detrendizza il vettore dati yg1, liberando, nel segmento TREND, il calcolo \
dei coefficienti B0 e B1 della retta interpolante, trovando yg2 che \
inseriremo in ygf nel segmento GRAFICO DA CONFRONTARE CON FOURIER. Calcolo \
automatico di m. Nel segmento SCELTA VETTORE PER FOURIER, poniamo yg2 in yt e \
nella formula dell'ERRORE STANDARD. Si fa girare il programma una prima volta \
e si osservano quali sono le armoniche rilevanti. Di esse si ricopiano i \
parametri trovati (numero armonica, ampiezza, fase), con i quali si \
tabellano le 4 armoniche rilevanti, trascrivendole nel segmento ARMONICHE \
RILEVANTI.
Seconda parte.
Nel segmento ARMONICHE RILEVANTI si tabellano le espressioni di queste 4 \
armoniche, si sommano i relativi vettori in yg3. Si liberano queste 4 \
armoniche e il loro vettore somma yg3. Si pone poi la variabile yg3 in ygf \
per confrontare yg3 con v (risultato di Fourier su yg2). Calcolo automatico \
di m. Si sceglie per Fourier la variabile yt=yg2. Nel segmento dell'ERRORE si \
pone yg3 e si rilancia il programma una seconda volta. E' un modo per \
cogliere le uniformità periodiche all'interno di dati storici"
"yt=N[{0.0330,0.0430,.0510,.0590,.0610,.0630,.053,.036,.0460,.0560,.0630,.\
0480,.0530,.0430,.0660,.053,.0820,.0600,.0800,.0760,.0560,
.0360,.0500,.053,.0560,.0580,.0610,.0630,.0650,.0680,.0815,.095,
.0790,.0630,.0690,.0740,.0800,.0765,.0730,.0695,.0660,.0930,.0830,
.0730,.0630,.0740,.0670,.06,.0860,.0800,.0730,.0670,.0890,.0640,
.0870,.079,.0700,.0650,.0600,.0630}]"
"Le successive righe sempre attive"
yg1=yt
n=Length[yt];
"SEGMENTO DELLE REGRESSIONI"
"f[x_]:=Fit[yt,{1,x,x^2},x]"
"f[x_]:=Fit[yt,{1,x},x]"
"yt1=N[Table[f[t],{t,60}]]?"
"La precedente istruzione dà problemi"
"Trovo l'ordinata all'origine e la pendenza"
"B0=f[x]/.x\[Rule]0"
"f1=f[x]/.x\[Rule]1"
"B1=f1-B0"
"B2=B0+B1 t"
"Un secondo modo di trovare B0 e B1";
"xt=Table[i, {i, 1, n}]";
"a=xt yt";
"Sxy=Apply[Plus, xt yt]";
"Sx=Apply[Plus, xt]";
"Sy=Apply[Plus, yt]";
"xq=xt^2";
"Sxq=Apply[Plus, xq]";
"yq=yt^2";
"qSx=Sx^2";
"B1=(n Sxy-Sx Sy)/(n Sxq-qSx)";
"B0=Sy/n-B1 Sx/n";
"B2=B0+B1 t";
"Tabello la retta"
"yt1=N[Table[B2,{t,n}]]"
"yt1=Flatten[yt1]"
"In yt1 ci sono i dati relativi alla retta di regressione"
"In yg2 c'è il vettore detrendizzato dei dati iniziali"
"yg2=yt-yt1"
"SEGMENTO DELLE ARMONICHE RILEVANTI"
"y4=Table[N[.004(Sin[.1333 Pi t+6.266])],{t,60}]";
"y5=Table[N[.007(Sin[.1667 Pi t+4.782])],{t,60}]";
"y8=Table[N[.004(Sin[.2667 Pi t+4.712])],{t,60}]";
"y9=Table[N[.004(Sin[.3000 Pi t+3.770])],{t,60}]";
"yg3=N[y4+y5+y8+y9]";
"In yg3 c'è il vettore dati di tutte le armoniche considerate rilevanti da \
precedente analisi. Se il programma passa da questo punto,
ha senso misurare per es. la differenza con il vettore di tutte le \
armoniche di Fourier sui dati detrendizzati yg2";
"yg4= N[yg3+yt1]";
"In yg4 c'è il vettore di tutte le componenti considerate rilevanti compreso \
il trend. Ha senso un confronto fra i dati iniziali Yg1 o v (vettore di \
Fourier) e Yg4 "
" IL GRAFICO ygf E' DA CONFRONTARE CON QUELLO DI FOURIER ygf1"
" La variabile nel ListPlot successivo rappresenta il vettore da confrontare \
con la combinazione di armoniche di Fourier applicato ad un vettore dati. yg \
rappresenta il grafico di tale vettore"
"In ygi (i=1,2...) ci va il vettore da confrontare con v"
ygf=ListPlot[yg1,PlotJoined\[Rule]True,PlotRange\[Rule]Automatic,
GridLines\[Rule]{Automatic,Automatic},
AxesLabel\[Rule]{"Tempo","Dati \
(unità)"},PlotLabel\[Rule]FontForm["DOMINIO DEL TEMPO",{"Times",12}]]
"CALCOLO AUTOMATICO DEL NUMERO ARMONICHE"
ny=Length[yg1]
n=ny;m=Mod[n,2]
If[m>0, m=(n-1)/2, m=n/2-1]
"IMPOSIZIONE MANUALE NUMERO ARMONICHE"
m=1
"m=2"
"SCELTA VETTORE DATI DA SOTTOPORRE A FOURIER"
"IN yt CI SONO I DATI CHE VOGLIO ANALIZZARE CON FOURIER E L'ANALISI E' POSTA \
IN v"
"Se voglio analizzare con Fourier i dati iniziali:"
yt=yg1
"Se voglio analizzare i dati detrendizzati:"
"yt=yg2"
"Se voglio analizzare i dati relativi alle armoniche considerate rilevanti:"
"yt=yg3"
"Se voglio analizzare i dati di tutte le componenti rilevanti:"
"yt=yg4"
"VALORI DEL PARAMETRO ak="
"Calcolo gli ak con il comando Sum, sommando cioè gli n prodotti yt * la \
funzione coseno, per t=1 a n; faccio questo per ogni valore di k (da k=0 a \
n/2)tramite Table"
a1=Table [Sum[yt[[t]] Cos[2 Pi k t/n],{t,1,n}],{k,0,m}];
a=2*a1/n;
"Divido per due il primo elemento, per ottenere ao=media; Sopprimo poi il \
primo elemento"
a0=a[[1]]/2
a=Delete[a,1]a=Chop[%]
"VALORI DEL PARAMETRO bk="
"Calcolo ora bk con la funzione seno con lo stesso procedimento di ak"
b1=Table[Sum[yt[[t]] Sin[2 Pi i t/n],{t,1,n}],{i,1,m}];
b=2 b1/n
b=Chop[%]
"Mentre ao/2 rappresenta la media, bo è sempre nullo"
b0=0
"AMPIEZZE ="
"Con ak e bk calcolo le ampiezze e le fasi dell'f(t) iniziale; Individuo il
vettore dei numeri da mettere sulle ascisse nel dominio della frequenza
(i/n o n/i) e con i vettori xi e yi
costruisco la lista {xi,yi}; disegno infine i plots"
ro=Sqrt[a^2+b^2]
ro=N[Chop[%]]
ro=Flatten[ro]Theta={}
i=1
While[i<m+1,
f2=Abs[a[[i]]/b[[i]]];
f2=180/Pi ArcTan[f2];
If[b[[i]]>0 && a[[i]]>0 , Theta=N[Append[Theta,f2]]];
If[b[[i]]<0 && a[[i]]>0, Theta=N[Append[Theta,180-f2]]];
If[b[[i]]<0 && a[[i]]<0, Theta=N[Append[Theta,180+f2]]];If[b[[i]]>0 && a[[
i]]<0, Theta=N[Append[Theta,360-f2]]];
If [(a[[i]]==0 && b[[i]]==0),Theta=N[Append[Theta,0]]];
If[((
b[[i]]<0 || b[[i]]>0) && a[[i]]\[Equal]0),Theta=N[Append[Theta,0]]];
If[b[[i]]\[Equal]0 && a[[i]]>0 ,Theta=N[Append[Theta,90]]];
If[b[[i]]\[Equal]0 && a[[i]]<0, Theta=N[Append[Theta,-90+360]]]; i++];
"FASE ="
Theta=Theta
"Theta=N[ArcTan[a,b]*180/Pi]"
"RISULTATI DI FOURIER"
v=Table[a0+Sum[(a[[k]] Cos[2 Pi k t/n]+b[[k]] Sin[2Pi k \
t/n]),{k,1,m}],{t,1,n}];
"GRAFICO RISULTATI DI FOURIER (ygf1)"
ygf1=ListPlot[v,PlotJoined\[Rule]False,GridLines\[Rule]{Automatic,Automatic},
PlotLabel\[Rule]FontForm["GRAFICI DI CONTROLLO",{"Times",12}]]
"CONFRONTO"
ygf2=Show[ygf,ygf1,PlotRange\[Rule]{Automatic,Automatic}]
"Calcolo l'ERRORE STANDARD DELLA STIMA"
ESS=Sqrt[Apply[Plus,(yg1-v)^2]/(n-2)]
"x=N[Table[i,{i,1,m}]]";
"c1=x";
Length[x];
Length[ro];
"For[i=1,i<m,i++,j=i*2;c=c1;yi=ro[[i]];
c=Insert[c,yi,j];c1=c]";
"d1=Partition[c,2]";
Needs["Graphics`Graphics`"]
BarChart[ro]
ListPlot[ro, PlotJoined\[Rule]True,PlotRange\[Rule]All,
GridLines\[Rule]{Automatic,Automatic},AxesOrigin\[Rule]{0,
0},AxesLabel\[Rule]{"Cicli in n dati", "Ampiezza \"},PlotLabel\[Rule]FontForm["DOMINIO DELLA FREQUENZA",{"Times",12}]]
"c1=x";
"For[i=1, i<m,i++,j=i*2;c=c1;yi=Theta[[i]];
c=Insert[c,yi,j];c1=c]";
"d2=Partition[c,2]";
ListPlot[Theta, PlotJoined\[Rule]True,PlotRange\[Rule]All, \
GridLines\[Rule]{Automatic,Automatic},AxesOrigin\[Rule]{0,0},
AxesLabel\[Rule]{"Frequenza","Fase"}]
———————————————————————————–
A1-Esempio N.1
————————————————————————
A2-Esempio N.2
RISULTATI ESEMPIO 2
A5-Esempio N.5
Serie detrendizzata delle concentrazioni As
ANALISI DEI DATI REALI DELL’ESEMPIO N° 5
L’IDEA E’ QUESTA:
– SUI SESSANTA DATI DELLA CONCENTRAZIONE ARSENICO (yt, GRAF. N.1) IN ALCUNE SORGENTI DELLA CARLINA (PROV. SIENA), SI FA UNA REGRESSIONE LINEARE ED I SUOI 60 VALORI PREDETTI SI SOTTRAGGONO DA yt, OTTENENDO LA SERIE DETRENDIZZATA.
– QUEST’ULTIMA SI SOTTOPONE AL PERIODOGRAMMA CHE, IN USCITA, PERMETTE DI CALCOLARE LE SUE COMPONENTI ARMONICHE.
– SOMMANDO LE COMPONENTI ARMONICHE RILEVANTI PIU’ I VALORI DEL TREND E SOTTRAENDO TALE SOMMA DALLA SERIE ORIGINALE yt, SI OTTERRA’ LA “STIMA DELL’ERRORE STANDARD” CHE DA’ UN’IDEA DELLA BONTA’ DEL PROCESSO.
Si trascriva manualmente i seguenti scripts sulla consolle del MATHEMATICA DI WOLFRAM (vers. non superiore alla 6.0); si evidenzi e si batta shift-enter: si otterranno i risultati e grafici riportati alla fine di questo programma (si noti in particolare il grafico ampiezza-numero armoniche eseguito sulla serie detrendizzata, dove è evidente il picco all’armonica n°5)
——————————————————————–
RISULTATI DEL PROGRAMMA ESEMPIO N.5 (conc. As detrend)
A4-Esempio N.4
ANALISI DELL’ESEMPIO N° 4 CON RISULTATI E GRAFICI (DATI SIMULATI)
A6-Esempio N.6
Oscillazione mensile ozono a Montecerboli (Pomarance,Pi); 2007-2011
RISULTATI GRAFICI OZONO
———————————————————————————-
ESEMPIO N° 5 CHE USA LE ARMONICHE RILEVANTI MESSE IN FORMULA IN UNA PRE-PROVA