Wiederverwendung eines in R eingebauten Modells

82

Wie speichern Sie beim Erstellen eines Modells in R die Modellspezifikationen, damit Sie sie für neue Daten wiederverwenden können? Angenommen, ich baue eine logistische Regression auf historischen Daten auf, werde aber erst nächsten Monat neue Beobachtungen machen. Was ist der beste Ansatz?

Dinge, die ich berücksichtigt habe:

  • Speichern des Modellobjekts und Laden in einer neuen Sitzung
  • Ich weiß, dass einige Modelle mit PMML exportiert werden können, habe aber nichts über den Import von PMML gesehen

Ich versuche einfach, ein Gefühl dafür zu bekommen, was Sie tun, wenn Sie Ihr Modell in einer neuen Sitzung verwenden müssen.

Danke im Voraus.

Btibert3
quelle
Nun, Sie können jederzeit eine Modellformel "speichern" und aktualisierte Daten in dataArgumenten bereitstellen ... vorausgesetzt, ich habe Sie richtig verstanden ...
aL3xa
Hmm, was meinst du mit Wiederverwendung? Vorhersagen für die neuen Beobachtungen oder Aktualisieren des Modells, um die neuen und die alten Beobachtungen zu verwenden?
Gavin Simpson
@ Gavin. Ich möchte das von mir entwickelte Modell verwenden, um neue Werte für Daten vorherzusagen, die ich noch nicht habe und möglicherweise für einige Zeit nicht habe.
Btibert3
1
@ Bitbert3 OK, dann ist der erste Abschnitt meiner Antwort das, was ich tun würde. Speicher das Modellobjekt auf der Festplatte ist mehr als akzeptabel, aber es ist wichtig , das R - Code / script verwendet zu speichern , das Modell in erster Linie , so dass Ihre Forschung / Modellierung ist reproduzierbar zu erzeugen.
Gavin Simpson

Antworten:

143

Wiederverwendung eines Modells zur Vorhersage neuer Beobachtungen

Wenn das Modell nicht rechenintensiv ist, dokumentiere ich den gesamten Modellierungsprozess in einem R-Skript, das ich bei Bedarf erneut ausführe. Wenn ein zufälliges Element an der Modellanpassung beteiligt ist, stelle ich sicher, dass ein bekannter zufälliger Startwert festgelegt wird.

Wenn die Berechnung des Modells rechenintensiv ist, verwende ich immer noch ein Skript wie oben, speichere jedoch die save()Modellobjekte mit into und rda object. Ich neige dann dazu, das Skript so zu ändern, dass wenn das gespeicherte Objekt vorhanden ist, es geladen wird oder wenn nicht, das Modell mithilfe einer einfachen if()...elseKlausel, die um die relevanten Teile des Codes gewickelt ist , neu angepasst wird .

Stellen Sie beim Laden Ihres gespeicherten Modellobjekts sicher, dass Sie alle erforderlichen Pakete neu laden. In Ihrem Fall glm()müssen jedoch keine zusätzlichen Pakete über R geladen werden, wenn das Logit-Modell über angepasst wurde.

Hier ist ein Beispiel:

> set.seed(345)
> df <- data.frame(x = rnorm(20))
> df <- transform(df, y = 5 + (2.3 * x) + rnorm(20))
> ## model
> m1 <- lm(y ~ x, data = df)
> ## save this model
> save(m1, file = "my_model1.rda")
> 
> ## a month later, new observations are available: 
> newdf <- data.frame(x = rnorm(20))
> ## load the model
> load("my_model1.rda")
> ## predict for the new `x`s in `newdf`
> predict(m1, newdata = newdf)
        1         2         3         4         5         6 
6.1370366 6.5631503 2.9808845 5.2464261 4.6651015 3.4475255 
        7         8         9        10        11        12 
6.7961764 5.3592901 3.3691800 9.2506653 4.7562096 3.9067537 
       13        14        15        16        17        18 
2.0423691 2.4764664 3.7308918 6.9999064 2.0081902 0.3256407 
       19        20 
5.4247548 2.6906722 

Wenn ich dies automatisieren möchte, würde ich wahrscheinlich Folgendes in einem Skript tun:

## data
df <- data.frame(x = rnorm(20))
df <- transform(df, y = 5 + (2.3 * x) + rnorm(20))

## check if model exists? If not, refit:
if(file.exists("my_model1.rda")) {
    ## load model
    load("my_model1.rda")
} else {
    ## (re)fit the model
    m1 <- lm(y ~ x, data = df)
}

## predict for new observations
## new observations
newdf <- data.frame(x = rnorm(20))
## predict
predict(m1, newdata = newdf)

Natürlich würde der Datengenerierungscode durch Code ersetzt, der Ihre tatsächlichen Daten lädt.

Aktualisieren eines zuvor angepassten Modells mit neuen Beobachtungen

Wenn Sie das Modell mithilfe zusätzlicher neuer Beobachtungen anpassen möchten. Dann update()ist eine nützliche Funktion. Es wird lediglich das Modell mit einem oder mehreren aktualisierten Modellargumenten angepasst. Wenn Sie neue Beobachtungen in die Daten aufnehmen möchten, die zur Anpassung an das Modell verwendet werden, fügen Sie die neuen Beobachtungen dem an das Argument übergebenen Datenrahmen hinzu 'data'und führen Sie dann die folgenden Schritte aus:

m2 <- update(m1, . ~ ., data = df)

Wo m1ist die ursprüngliche, gespeicherte Modellanpassung, . ~ .sind die Modellformeländerungen, was in diesem Fall bedeutet, dass alle vorhandenen Variablen sowohl auf der linken als auch auf der rechten Seite von enthalten sind ~(mit anderen Worten, nehmen Sie keine Änderungen an der Modellformel vor), und dfist die Datenrahmen für das ursprüngliche Modell, erweitert um die neu verfügbaren Beobachtungen.

Hier ist ein Arbeitsbeispiel:

> set.seed(123)
> df <- data.frame(x = rnorm(20))
> df <- transform(df, y = 5 + (2.3 * x) + rnorm(20))
> ## model
> m1 <- lm(y ~ x, data = df)
> m1

Call:
lm(formula = y ~ x, data = df)

Coefficients:
(Intercept)            x  
      4.960        2.222  

> 
> ## new observations
> newdf <- data.frame(x = rnorm(20))
> newdf <- transform(newdf, y = 5 + (2.3 * x) + rnorm(20))
> ## add on to df
> df <- rbind(df, newdf)
> 
> ## update model fit
> m2 <- update(m1, . ~ ., data = df)
> m2

Call:
lm(formula = y ~ x, data = df)

Coefficients:
(Intercept)            x  
      4.928        2.187

Andere haben in Kommentaren erwähnt formula(), die die Formel aus einem angepassten Modell extrahieren:

> formula(m1)
y ~ x
> ## which can be used to set-up a new model call
> ## so an alternative to update() above is:
> m3 <- lm(formula(m1), data = df)

Wenn die Modellanpassung jedoch zusätzliche Argumente wie 'family'oder 'subset'Argumente in komplexeren Modellanpassungsfunktionen enthält. Wenn update()Methoden für Ihre Modellanpassungsfunktion verfügbar sind (z. B. für viele gängige Anpassungsfunktionen glm()), bietet dies eine einfachere Möglichkeit zum Aktualisieren einer Modellanpassung als das Extrahieren und Wiederverwenden der Modellformel.

Wenn Sie beabsichtigen, die gesamte Modellierung und zukünftige Vorhersage in R durchzuführen, scheint es nicht wirklich sinnvoll zu sein, das Modell über PMML oder ähnliches zu abstrahieren.

Gavin Simpson
quelle
1
+1 und wenn Sie sich freundlicherweise weigern würden, Ihre Antworten so zu bearbeiten, dass sie in die von mir vorbereitete Antwort passen ... ;-)
Joris Meys
@Joris ist keine Hündin! ;-) +1 fürupdate von mir
Gavin Simpson
1
Dies ist eine wirklich gute Antwort. Ich hoffe, jemand kuratiert die SO [r] -Antworten wie diese und stellt sie als Tutorial zusammen.
JD Long
1
Hervorragende Antwort. Vielen Dank für die Beispiele, die Sie gegeben haben.
Nhern121
1
Genau das, wonach ich gesucht habe. Ich möchte +1000 tun ... Danke
Adjeiinfo
7

Wenn Sie denselben Namen für den Datenrahmen und die Variablen verwenden, können Sie (zumindest für lm()und glm()) die Funktion updatefür das gespeicherte Modell verwenden:

Df <- data.frame(X=1:10,Y=(1:10)+rnorm(10))

model <- lm(Y~X,data=Df)
model

Df <- rbind(Df,data.frame(X=2:11,Y=(10:1)+rnorm(10)))

update(model)

Dies ist natürlich ohne Vorbereitung der Daten und so weiter. Es werden nur die festgelegten Modellspezifikationen wiederverwendet. Beachten Sie, dass das neue Modell, wenn Sie die Kontraste in der Zwischenzeit ändern, mit den neuen Kontrasten aktualisiert wird, nicht mit den alten.

Daher ist die Verwendung eines Skripts in den meisten Fällen die bessere Antwort. Man könnte alle Schritte in eine Komfortfunktion aufnehmen, die nur den Datenrahmen übernimmt, sodass Sie das Skript als Quelle verwenden und die Funktion dann für jedes neue Dataset verwenden können. Siehe auch die Antwort von Gavin dazu.

Joris Meys
quelle