Подтвердить что ты не робот

Повторное использование модели, построенной в R

При построении модели в R, как вы сохраняете спецификации модели, чтобы их можно было повторно использовать для новых данных? Скажем, я построю логистическую регрессию по историческим данным, но не буду иметь новых наблюдений до следующего месяца. Какой лучший подход?

Вещи, которые я рассмотрел:

  • Сохранение объекта модели и загрузка в новый сеанс
  • Я знаю, что некоторые модели могут быть экспортированы с помощью PMML, но ничего не видели об импорте PMML

Просто я пытаюсь понять, что вы делаете, когда вам нужно использовать свою модель в новом сеансе.

Спасибо заранее.

4b9b3361

Ответ 1

Повторное использование модели для прогнозирования новых наблюдений

Если модель не является дорогостоящей вычислительной машиной, я склонен документировать весь процесс построения модели в R script, который я повторю, когда это необходимо. Если случайный элемент участвует в подгонке модели, я должен установить известное случайное семя.

Если вычислить вычислительную стоимость для вычисления, то я все еще использую script, как указано выше, но сохраняю объекты модели с помощью объекта save() в и rda. Затем я пытаюсь изменить script таким образом, что если сохраненный объект существует, загрузите его или, если нет, переустановите модель, используя простое предложение if()...else, обернутое вокруг соответствующих частей кода.

При загрузке сохраненного объекта модели обязательно перезагрузите все необходимые пакеты, хотя в вашем случае, если модель логита была установлена ​​с помощью glm(), не будет никаких дополнительных пакетов для загрузки за пределы R.

Вот пример:

> 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 

Если вы хотите автоматизировать это, то я, вероятно, сделаю следующее в script:

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

Конечно, код генерации данных будет заменен кодом, загружающим ваши фактические данные.

Обновление ранее установленной модели с новыми наблюдениями

Если вы хотите обновить модель, используя дополнительные новые наблюдения. Тогда update() является полезной функцией. Все, что он делает, это обновить модель с обновленным аргументом модели. Если вы хотите включить новые наблюдения в данные, используемые для соответствия модели, добавьте новые наблюдения в кадр данных, переданный в аргумент 'data', а затем выполните следующие действия:

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

где m1 - это исходная, сохраненная модель, . ~ . - это изменение формулы модели, которое в этом случае означает все существующие переменные как на левой, так и на правой сторонах ~ (другими словами, не вносите изменений в формулу модели), а df - это кадр данных, используемый для подгонки исходной модели, расширенный для включения новых доступных наблюдений.

Вот рабочий пример:

> 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

Другие упоминали в комментариях formula(), который извлекает формулу из подогнанной модели:

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

Однако, если подгонка модели включает дополнительные аргументы, такие как 'family' или 'subset' аргументы в более сложных функциях подгонки модели. Если доступны методы update() для вашей функции подгонки модели (что они предназначены для многих общих функций фитинга, таких как glm()), он обеспечивает более простой способ обновления модели, чем извлечение и повторное использование формулы модели.

Если вы намерены делать все моделирование и будущее предсказание в R, на самом деле нет особого смысла в абстрагировании модели через PMML или подобное.

Ответ 2

Если вы используете одно и то же имя фрейма данных и переменных, вы можете (по крайней мере для lm() и glm()) использовать функцию update в сохраненной модели:

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)

Это без курса, без подготовки данных и т.д. Он просто повторно использует набор спецификаций модели. Имейте в виду, что если вы измените контрасты в то же время, новая модель будет обновляться новыми контрастами, а не старыми.

Поэтому использование script в большинстве случаев является лучшим ответом. Можно включить все шаги в функцию удобства, которая просто принимает фреймворк данных, поэтому вы можете запустить script, а затем использовать эту функцию в любом новом наборе данных. См. Также ответ Гэвина на это.