Ponowne wykorzystanie modelu wbudowanego w R

Budując model w R, Jak zapisać specyfikacje modelu, aby móc go ponownie wykorzystać na nowych danych? Powiedzmy, że zbuduję regresję logistyczną na danych historycznych, ale nie będę miał nowych obserwacji do przyszłego miesiąca. Jakie jest najlepsze podejście?

Rzeczy, które rozważałem:

  • zapisanie obiektu modelu i wczytywanie w nowej sesji
  • wiem, że niektóre modele mogą być eksportowane za pomocą PMML, ale tak naprawdę nie widziałem nic o importowaniu PMML

Po prostu staram się zrozumieć, co robisz, gdy musisz użyć swojego modelu w nowej sesji.

Z góry dzięki.

 63
Author: Btibert3, 2011-02-25

2 answers

Ponowne wykorzystanie modelu do przewidywania nowych obserwacji

Jeśli model nie jest kosztowny obliczeniowo, Zwykle dokumentuję cały proces budowania modelu w skrypcie R, który w razie potrzeby uruchamiam ponownie. Jeśli element losowy jest zaangażowany w dopasowanie modelu, upewniam się, że ustawiam znane losowe ziarno.

Jeśli obliczenie modelu jest kosztowne obliczeniowo, to nadal używam skryptu jak wyżej, ale zapisuję obiekty modelu używając save() into i RDA object. Następnie mam tendencję do modyfikowania skryptu jeśli zapisany obiekt istnieje, załaduj go, a jeśli nie, zmień model, używając prostej klauzuli if()...else owiniętej wokół odpowiednich części kodu.

Podczas ładowania zapisanego obiektu modelu, pamiętaj, aby przeładować wszystkie wymagane pakiety, chociaż w Twoim przypadku, jeśli model logit pasował do glm(), nie będzie żadnych dodatkowych pakietów do załadowania poza R.

Oto przykład:

> 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 

Jeśli chcesz to zautomatyzować, to prawdopodobnie wykonałbym następujące czynności w scenariusz:

## 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)

Oczywiście, kod generowania danych zostanie zastąpiony kodem ładującym rzeczywiste dane.

Aktualizacja wcześniej zamontowanego modelu o nowe obserwacje

Jeśli chcesz przerobić model przy użyciu dodatkowych nowych obserwacji. Wtedy update() jest użyteczną funkcją. Wszystko, co robi, to odświeżyć model z jednym lub więcej argumentów modelu zaktualizowane. Jeśli chcesz dodać nowe obserwacje do danych użytych do dopasowania modelu, dodaj nowe obserwacje do ramki danych przekazywany do argumentu 'data', a następnie wykonaj następujące czynności:

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

Gdzie m1 to oryginalny, zapisany model dopasowania, {[11] } to zmiany formuły modelu, co w tym przypadku oznacza włączenie wszystkich istniejących zmiennych po lewej i prawej stronie ~ (innymi słowy, nie wprowadzać zmian do Formuły modelu), a df to ramka danych używana do dopasowania oryginalnego modelu, rozszerzona o nowo dostępne obserwacje.

Oto przykład pracy:]}
> 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

Inne zostały wymienione w komentarzach formula(), które wyciągają wzór z dopasowanego modelu:

> 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)

Jednakże, jeśli dopasowanie modelu zawiera dodatkowe argumenty, takie jak 'family' lub 'subset' argumenty w bardziej złożonych funkcjach dopasowania modelu. Jeśli update() metody są dostępne dla funkcji dopasowania modelu (które są dla wielu popularnych funkcji dopasowania, takich jak glm()), zapewnia to prostszy sposób aktualizacji dopasowania modelu niż wyodrębnianie i ponowne wykorzystanie formuły modelu.

Jeśli zamierzasz zrobić wszystko modelowanie i przewidywanie przyszłości w R, nie wydaje się zbyt wiele sensu w abstrakcji modelu za pomocą PMML lub podobne.

 121
Author: Gavin Simpson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-25 15:19:37

Jeśli używasz tej samej nazwy ramki danych i zmiennych, możesz (przynajmniej dla lm() i glm() ) użyć funkcji update na zapisanym modelu:

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)

To jest kurs bez przygotowania danych i tak dalej. Po prostu ponownie wykorzystuje zestaw specyfikacji modelu. Pamiętaj, że jeśli w międzyczasie zmienisz kontrasty, nowy model zostanie zaktualizowany o nowe kontrasty, a nie Stare.

Więc użycie skryptu jest w większości przypadków lepszą odpowiedzią. Jeden może obejmować wszystkie kroki w wygodnej funkcji, która po prostu zajmuje ramkę danych, dzięki czemu można pobrać skrypt, a następnie użyć funkcji na każdym nowym zbiorze danych. Zobacz też odpowiedź Gavina na to pytanie.

 6
Author: Joris Meys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-25 15:22:20