close Warning: Can't synchronize with repository "(default)" (/var/svn/mms does not appear to be a Subversion repository.). Look in the Trac log for more information.

Ticket #904: _posEstimation.tol

File _posEstimation.tol, 10.2 KB (added by lmperez, 14 years ago)
Line 
1//////////////////////////////////////////////////////////////////////////////
2// FILE    : _posEstimation.tol
3// AUTHOR : Luis Miguel Pérez Liberal (lmperez@bayesinf.com)
4// PURPOSE : Post-Estimation diagnosis functions
5//////////////////////////////////////////////////////////////////////////////
6
7
8//////////////////////////////////////////////////////////////////////////////
9Set BPL(Serie serie, Text arima, Real autocorr, Real alpha)
10//////////////////////////////////////////////////////////////////////////////
11{
12  Text label = If(arima=="ARIMA","P1_7DIF0_1AR1_0MA0_7",arima);
13  Set  arima = GetArimaFromLabel(label);
14
15  Real rAR = Card(Monomes(ARIMAGetAR(arima))-[[ Polyn 1 ]]);
16  Real rMA = Card(Monomes(ARIMAGetMA(arima))-[[ Polyn 1 ]]);
17  Real deg = Degree(ARIMAGetDIF(arima));
18
19  Real bpl   = BoxPierceLjung(serie,autocorr,rAR,rMA);
20  Real bpl_D = BoxPierceLjung(serie,autocorr*deg,rAR,rMA);
21
22  Real gl  = autocorr     - rAR - rMA;
23  Real glD = autocorr*deg - rAR - rMA;
24
25  Real chi  = DistChiInv(1-alpha/2,gl);
26  Real chiD = DistChiInv(1-alpha/2,glD);
27
28  Real t_blp   = GT( Abs(bpl), chi );
29  Real t_blp_D = GT( Abs(bpl_D),chiD );
30
31  Set Eval("Set _.BPL."+Name(serie)+" = [[ t_blp, t_blp_D ]];")
32};
33//////////////////////////////////////////////////////////////////////////////
34PutDescription("Realiza un contraste de hipotesis BoxPierceLjung sobre las
35autocorrelaciones dadas (autocorr) dado un arima (como etiqueta).
36Devuelve verdadero si se rechaza la hipotesis y falso si se acepta.
37t_blp es el resultado para las autocorrelaciones dadas, y t_blp_D es el
38resultado del test para las autocorrelaciones dadas multiplicada por el grado
39de la diferencia del arima.",
40BPL);
41//////////////////////////////////////////////////////////////////////////////
42
43
44//////////////////////////////////////////////////////////////////////////////
45Set Analisis.Residuals(Serie serie,Real nParametros, Real nParametrosArima,
46  Real alpha)
47//////////////////////////////////////////////////////////////////////////////
48{
49  Real med = AvrS(serie);
50  Real sig = StDsS(serie);
51  Real asi = AsimetryS(serie);
52  Real kur = KurtosisS(serie);
53
54  Real asi_teo = AsimetryS(Gaussian(med,sig));
55  Real kur_teo = KurtosisS(Gaussian(med,sig));
56
57  Real t     = med/sig;
58  Real gl    = CountS(serie) - nParametrosArima - nParametros;
59  //Real alpha = 0.10;
60  Real p_med = DistTInv(1-alpha/2,gl);
61
62  Real test_med = GT( Abs(t),p_med );
63
64  Serie uno  = Not(serie)+Not(Not(serie));
65  Serie norm = (serie - med*uno)/StDsS(serie);
66  Real  sig1 = SumS(IfSer(GT(Abs(norm),uno*1),1,0))/SumS(uno);
67  Real  sig2 = SumS(IfSer(GT(Abs(norm),uno*2),1,0))/SumS(uno);
68  Real  sig3 = SumS(IfSer(GT(Abs(norm),uno*3),1,0))/SumS(uno);
69  Set   end  = [[ med,sig,asi,asi_teo,kur,kur_teo,test_med,sig1,sig2,sig3 ]];
70
71  Set Eval("Set "+Name(serie)+" = end;")
72};
73//////////////////////////////////////////////////////////////////////////////
74PutDescription("Dada una serie de residuos, devuelve:
75Media
76Sigma
77Asimetria y Asimetría teórica
78Kurtosis y Kurtosis teórica
79Test media distinta de cero
80Numero de residuos fuera de una, dos y tres sigmas.
81
82Precisa que le digamos el alpha como el área fuera de la curva para el test
83de la media",
84Analisis.Residuals);
85//////////////////////////////////////////////////////////////////////////////
86
87
88//////////////////////////////////////////////////////////////////////////////
89Set Analisis.Rachas(Serie residuos, Real max)
90//////////////////////////////////////////////////////////////////////////////
91{
92  // Crea un polinomio del tipo 1+B+B^2+...+B^k
93  Polyn PolAcu_K(Polyn operador,Real k){
94    SetSum( For(0,k,Polyn (Real j){ operador^j }) )
95  };
96
97  // Cuenta las fechas de una serie de rachas, cuenta hacia delante y hacia
98  // atras para evitar que se elimine la primera fecha de la racha
99  Set DatesRacha(Serie racha)
100  {
101    Set For(1,max,Set (Real j)
102    {
103      Serie I   = Not(racha)+Not(Not(racha));
104      Serie s1  = IfSer(EQ(PolAcu_K(B,j):racha,I*(j+1)),1,0);
105      Serie s2  = IfSer(EQ(PolAcu_K(F,j):racha,I*(j+1)),1,0);
106      Set dates = DatesInd(s1+s2)
107    })
108  };
109
110  // Calcula el numero de ocurrencias de cada racha
111  Set DistRacha(Set datesRacha, Serie residuos, Text signo)
112  {
113    Real med = AvrS(residuos);
114    // cojo la sigma de los residuos porque al caso lo que me interesa es la
115    // media, y así no tengo que tener en cuenta la transformación
116    Real sig = StDsS(residuos);
117    Real prb = Case(
118      signo=="+", 1-DistNormal(0,med,sig),
119      signo=="-", DistNormal(0,med,sig),
120      True,"ERROR"
121    );
122
123    Text label = Case(
124      signo=="+", "pos",
125      signo=="-", "neg",
126      True,"ERROR"
127    );
128
129    Set For(1,Card(datesRacha)-1,Set (Real j)
130    {
131      Set  dates     = datesRacha[j] - datesRacha[j+1];
132      Real observado = Card(dates);
133      // No es el número de observaciones, hay que restarle la racha menos 1
134      Real longitud  = CountS(residuos)-(j+1-1);
135      Real teorico   = Round((prb^(j+1))*longitud,2);
136      Set Eval("Set rch_"+IntText(j+1)+" = [[
137        Eval(\"Real observado_\"+label+\" = observado;\"),
138        Eval(\"Real teorico_\"+label+\" = teorico;\")
139      ]];")
140    })
141  };
142
143  Serie uno = Not(residuos)+Not(Not(residuos));
144  Serie not = Not(uno);
145
146  Serie rch_pos = IfSer(GT(residuos,not),1,0);
147  Serie rch_neg = IfSer(LT(residuos,not),1,0);
148
149  Set sDtsRchPos = DatesRacha(rch_pos);
150  Set sDtsRchNeg = DatesRacha(rch_neg);
151 
152  Set DistRacha(sDtsRchPos,residuos,"+")|DistRacha(sDtsRchNeg,residuos,"-")
153};
154//////////////////////////////////////////////////////////////////////////////
155PutDescription("Devuelve el numero de rachas de residuos de igual signo
156consecutivos junto a la esperada teóricamente.",
157Analisis.Rachas);
158//////////////////////////////////////////////////////////////////////////////
159
160
161//////////////////////////////////////////////////////////////////////////////
162Set LookFor.VarianceChanges(Serie serie, Real long)
163//////////////////////////////////////////////////////////////////////////////
164{
165//  Serie serie = var;
166//  Real long   = 40;
167  Date  iniDate = First(serie);
168  Date  endDate = Last(serie);
169  TimeSet tms   = Dating(serie);
170
171  Real  card = Floor(
172    SumS(Not(serie)+Not(Not(serie)))/long
173  );
174
175  Serie null = SubNullSer(tms,Succ(endDate,tms,-(long*card-1)),endDate);
176
177  Set sPerform = For(1,card,Serie (Real j)
178  {// Real j = 1;
179    Date iniPerform = Succ(endDate,tms,-long*(j-1));
180    Date endPerform = Succ(endDate,tms,-(long*j-1));
181       
182    //--> Las fechas están cambiadas bien.Es para empezar desde el final
183    Serie sub = SubSer(serie,endPerform,iniPerform );
184    Serie ci  = SubSer(CalInd(In(endPerform,iniPerform),tms),
185      endPerform,
186      iniPerform
187    );
188
189    //--> Saco la desviacion standard de los no nulos
190    Real  sig = StDsS(AutoDating(sub));
191
192    Serie end = sig*( null << ci >> null )
193  });
194
195  Serie sum = SetSumC(sPerform);
196  Serie dif = (1-B):sum;
197
198  //--> Elijo como candidatos a priori los mayores de dos sigmas
199  Serie candidates = IfSer(LT(Serie Abs(dif),2*StDsS(AutoDating(dif))),0,dif);
200 
201  //--> La Kurtosis me dice si la distribucion es una normal, si es una
202  //    uniforme o en cambio es un pico
203  Real  rKurtosis = KurtosisS(AutoDating(dif));
204 
205  //--> La Kurtosis de una normal es 0, le doy 0.4 más para evitarme problemas
206  //   de distribuciones muy parecidas a las normales
207  Real rCriterium = 0 + 0.4;
208  Set  sCandidates = If(Real Abs(rKurtosis)>rCriterium,
209    DatesInd(candidates),
210    Empty
211  );
212
213  //--> Me quedo con el último más long
214  Date day = If( Card(sCandidates)>0,
215    sCandidates[Card(sCandidates)],
216    iniDate
217  );
218
219  Set  [[ sum,dif,candidates,day,rKurtosis ]]
220};
221//////////////////////////////////////////////////////////////////////////////
222PutDescription("Busca cambios de varianza en una serie temporal. Recibe la
223serie que queramos estudiar y un numero real, que es un intervalo de dias. A
224continuacion divide la serie en intervalos de longitud \"long\" y estudia los
225cambios de varianza que se producen entre intervalos. Retorna un set con tres
226series. La primera muestra la varianza a intervalos (long), el segundo la
227serie diferenciada y la tercera la serie deiferenciada filtrada de candidatos
228pequeños las que informan sobre los posibles candidatos, junto con una fecha
229del dia más probable donde ocurra un cambio de varianza. Esto siempre y cuando
230la distribucion de los candidatos sea más picuda que una normal, en tal caso se
231considera que no hay cambio de varianza importante.",
232LookFor.VarianceChanges);
233//////////////////////////////////////////////////////////////////////////////
234
235
236//////////////////////////////////////////////////////////////////////////////
237Date VarianceChange(Serie serie, Real long)
238//////////////////////////////////////////////////////////////////////////////
239{
240  Real iniTest = Floor(long/20);
241  Real endTest = Floor(long/3);
242
243  Set test = For(iniTest,endTest,Set (Real j)
244  {
245    Set research = LookFor.VarianceChanges(serie,10*j);
246    Set proof    = If(Card(research)>0,research,Empty);
247
248    Set PutName("Intervalo_"+IntText(j),proof)
249  });
250
251  Set sPulses = For(1,Card(test),Serie (Real k)
252  {
253    Date d = test[k][4];
254    Serie SubSer(Pulse(d,Diario),First(serie),Last(serie))
255  });
256
257  Serie pulses = SetSum(sPulses);
258  Serie select = IfSer(LT(Serie Abs(pulses),StDsS(AutoDating(pulses))),0,pulses);
259 
260  Set  sSelectcandidates = DatesInd(select);
261
262  Date DayOfChange = If(Card(sSelectcandidates)>0,
263    sSelectcandidates[Card(sSelectcandidates)],
264    IniDate
265  )
266};
267//////////////////////////////////////////////////////////////////////////////
268PutDescription("Hace un estudio iterativo de la serie que le pasas, y devuelve
269la fecha que estima que se ha producido un cambio de varianza. Si no detecta
270cambio alguno, devuelve la primera fecha de la serie. El campo \"long\" es el
271intervalo de dias en los que divide internamente la serie",
272VarianceChange);
273//////////////////////////////////////////////////////////////////////////////
274
275
276//////////////////////////////////////////////////////////////////////////////
277// END
278//////////////////////////////////////////////////////////////////////////////