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