Seite 1 von 2

Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mi Sep 27, 2017 3:14 pm
von daten_tim
Liebes Forum,
ich suche nach einer optimalen Regression, welche den niedrigsten BIC hat (siehe Code). Dabei möchte ich also nach der besten Regression suchen, die y erklären soll und dazu Daten mit bestimmten lags nehmen soll (z.B. data_lag_1). a,b,c und d sind dann die Anzahl an möglichen Daten - a bis d also vier mögliche Zeitreihen zur Erklärung von y (z.B. data_lag_2, data_lag_3, data_lag_7, data_lag_12). Es kann also auch sein, dass a=1, b=1, c=1 und d=1 und y damit am besten aus fix und data_lag_0 erklärt werden kann. Nun habe ich das Problem, dass ich eigentlich lieber noch mehr Zeitreihen einbauen würde um y zu erklären (e,f,g...), aber muss leider feststellen, dass schon die Hinzunahme der Möglichkeit d zeitlich unglaublich lange dauert - vor allem im Vergleich zu nur drei (a,b,c) unabhängigen Variablen. Ich weiss aber nicht, wie ich den Prozess schneller machen könnte. Habt Ihr dazu Ideen? Es sieht so aus, dass R von hinten anfängt und zuerst drei unabhängige Variablen auf 1 lässt und nur die vierte von 1 bis 13 einsetzt - so ist ja auch die Schleife aufgebaut. Dann kommt die zweite unabhängige Variable, bis es bei der vierten unglaublich lange dauert. Für eine Suche nach der optimalen Regression bestimmt eine Minute - was ich komisch finde. Habt Ihr dazu Ideen? Das das so lange dauert ist ziemlich schlecht. Eventuell kann man das besser codieren?

Code: Alles auswählen

mat[1,]<-data_lag_0
mat[2,]<-data_lag_1
mat[3,]<-data_lag_2
mat[4,]<-data_lag_3
mat[5,]<-data_lag_4
mat[6,]<-data_lag_5
mat[7,]<-data_lag_6
mat[8,]<-data_lag_7
mat[9,]<-data_lag_8
mat[10,]<-data_lag_9
mat[11,]<-data_lag_10
mat[12,]<-data_lag_11
mat[13,]<-data_lag_12


a<-1
b<-1
c=1
d=1


wertBIC = 10000000 # Startwert


for (i in 1:reps)   { 
  
  for (a in 1:13) {
    for (b in 1:13)  {
      for (c in 1:13)  {
        for (d in 1:13)  {
        #for (e in 1:13)  {
        # for (f in 1:13)  {
        # for (g in 1:13)  {

                
        test = lm(y[,i] ~ fix + mat[a,] + mat[b,] + mat[c,] + mat[d,]) #+ mat[e,]+ mat[f,] + mat[g,])
          
        wert1_neu<-BIC(test);
        
        if (wert1_neu < wertBIC){
          wertBIC<-wert1_neu;
          werta<-a;
          wertb<-b;
          wertc<-c;
          wertd<-d;
          
          print(wertBIC);
          print(werta);
          print(wertb);
          print(wertc);
          print(wertd);
          print(i);
        };
         };
         }; };}; }

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mi Sep 27, 2017 4:27 pm
von bigben
Hallo daten_tim,

da ist einiges in dem Code was ins Auge sticht und nicht sehr R-typisch ist. Ich verstehevor allem gar nicht, was die äußerste for-Schleife mit den reps tun soll, wenn bei jeder Wiederholung das gleiche passiert. Oder habe ich irgendwas übersehen, wozu die Variable reps gebraucht wird? Sonst ist das reine Zeitverschwendung.

Zum Beschleunigen würde ich mir überlegen, ob Du wirklich jede Kombination aus a, b, c und d wirklich brauchst. Die Kombination aus
a=1 und b=2 ist doch inhaltlich das gleiche wie a=2 und b=1. Warum dafür doppelt eine Regression rechnen?

Mit a bis d machst Du immerhin 13^4 = 28561 lineare Regressionen, mit a bis e wären es 13^5 = 371293. Das kann schon etwas dauern. 13*12*11*10 sind nur 60% von 13^4 und 13*12*11*10*9 sind nur 40% von 13^5 -- ein bisschen Überlegung in den korrekten Algorithmus kann die Rechenzeit also schnell halbieren.

Was genau bewirkt der Term "fix" in dem lm-Aufruf? Für einen Intercept brauchst Du den nicht.

Code: Alles auswählen

a<-1
b<-1
c=1
d=1
Das ist alles umsonst, weil es von den for-Anweisungen ohnehin so gesetzt wird. Spart aber leider keine Zeit, wenn Du das weglässt. Ebenso die Semikolons hinter den Schleifen. Die stören nur das Bild.


Alles in allem scheint mir Dein Vorgehen eine recht grobe Annäherung an die bereits etablierte schrittweise Regression zu sein. Anstelle von Detailverbesserungen in Deinem Code frage ich deshalb einfach mal ganz platt, ob Du mit dem AIC anstelle des BIC leben könntest und ob die Funktion step() nicht vielleicht schon implementiert hat, was Du machen möchtest. Dann könntest Du nämlich richtig viel Zeit sparen.

LG,
Bernhard

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mi Sep 27, 2017 4:47 pm
von bigben
Nachtrag: Schrittweise Regression mit BIC als Kriterium kann das leaps-Package. Hier gibt es eine schöne Einführung: http://www.stat.columbia.edu/~martin/W2024/R10.pdf

LG,
Bernhard

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mi Sep 27, 2017 9:31 pm
von EDi
Nachtrag: Schrittweise Regression mit BIC als Kriterium kann das leaps-Package.
geht auch direKt mit stats::step()
k: the multiple of the number of degrees of freedom used for the
penalty. Only ‘k = 2’ gives the genuine AIC: ‘k = log(n)’ is
sometimes referred to as BIC or SBC.

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Do Sep 28, 2017 5:42 pm
von daten_tim
Vielen dank für Euer Feedback. Trotzdem unter (2) noch ein Problem:

1) Ja, sorry. Hinter reps verbirgt sich eine weitere Schleife, weil ich diese Suche nach einem optimalen Modell für mehrere hundert Zeitreihen machen will. Das sind dann die reps.
2) Eure beiden Möglichkeiten habe ich mir angeschaut. Das Problem ist, dass ich mit dem optimalen Modell weiterrechnen will, d.h. ich brauhe die Koeffizienten, Residuen etc. und mache dann Tests und weitere Rechnungen. Ich habe bisher keine Möglichkeiten gefunden, dass mit den beiden Möglichkeiten von Euch zu machen, also das optimale Modell zu nehmen und weiterzurechnen?
3) Nein, fix ist keine Konstante sondern eine von mir eingesetzte Zeitreihe, die immer rein muss.

Ich freue mich über Feedback.
tim

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Do Sep 28, 2017 8:51 pm
von EDi
Step liefert ein lm objekt zurück, kann also direkt weitergerechnet werden.

http://rextester.com/UQLTD33556

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Do Sep 28, 2017 11:05 pm
von bigben
Hallo Tim,
Ohne jetzt das Wort "alternativlos" überstrapazieren zu wollen: Wenn Du 13^13 Kombinationen durchprobieren willst und für jede nur 1 ms bräuchtest, dann rechnest Du für jede Rep 9579 Jahre lang. Dein brute force Durchprobieren ist keine Alternative! Du musst dich für andere Wege öffnen.
LG,
Bernhard

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mo Okt 02, 2017 12:21 pm
von daten_tim
Vielen Dank für Eure Tipps. Ja, na klar macht das Sinn! :) Ich habe nun ein bisschen rumprobiert. Gut ist folgendes zum Abruf des optimalen Modells:

Code: Alles auswählen

test = lm(y[,i] ~ fix + mat[a,] + mat[b,] + mat[c,] + mat[d,]) + mat[e,]+ mat[f,] + mat[g,]
final.mod <- step(test, k=log(n))
k=log(n) dann für den BIC statt AIC (k=2).

Wie Du schreibst, EDi, soll der BIC über k=log(n) funtionieren. n ist dabei nach meiner Meinung length(mat[a,]), oder? ich habe da auch andere Meinungen gefunden, aber ich galube es ist die Anzahl der Datensätze...?

Und dann ist mir noch aufgefallen: Der AIC hat mit step() einen anderen Wert als manuell nachgerechnet!?

EDi hat geschrieben: Mi Sep 27, 2017 9:31 pm
Nachtrag: Schrittweise Regression mit BIC als Kriterium kann das leaps-Package.
geht auch direKt mit stats::step()
k: the multiple of the number of degrees of freedom used for the
penalty. Only ‘k = 2’ gives the genuine AIC: ‘k = log(n)’ is
sometimes referred to as BIC or SBC.

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mo Okt 02, 2017 8:43 pm
von EDi
n ist lenght(y [,i]), die Anzahl der Beobachtungen.

Wie hast du den AIC "manuell" berechnet? Bitte ein reproduzierbar Bsp posten.

Re: Schleife für Suche nach optimalem Regressionsmodell ist langsam

Verfasst: Mi Okt 04, 2017 10:50 am
von daten_tim
EDi hat geschrieben: Mo Okt 02, 2017 8:43 pm n ist lenght(y [,i]), die Anzahl der Beobachtungen.

Wie hast du den AIC "manuell" berechnet? Bitte ein reproduzierbar Bsp posten.
anbei das beispiel aus help: AIC(slm1) = 325.2408 vs. AIC aus slm1 <- step(lm1) ist 189.86 !?

Code: Alles auswählen

  summary(lm1 <- lm(Fertility ~ ., data = swiss))
  slm1 <- step(lm1)
  summary(slm1)
  AIC(slm1)