重用R内置模型

在R中构build模型时,如何保存模型规范以便可以在新数据上重复使用? 假设我对历史数据进行逻辑回归,但直到下个月才会有新的观察结果。 什么是最好的方法?

我已经考虑过的事情:

  • 保存模型对象并加载到一个新的会话中
  • 我知道有些模型可以用PMML导出,但是还没有真正看到有关导入PMML的内容

简单地说,我试图了解当你需要在新的会话中使用你的模型时你做了什么。

提前致谢。

重新使用模型来预测新的观察结果

如果模型的计算成本不高,我倾向于在需要时重新运行的R脚本中logging整个模型构build过程。 如果在模型拟合中涉及一个随机元素,我确定设置一个已知的随机种子。

如果模型的计算成本很高,那么我仍然使用上面的脚本,但是使用save()将模型对象save()到rda对象中。 然后,我倾向于修改脚本,以便如果保存的对象存在,则加载它,否则,使用围绕代码的相关部分的简单if()...else子句重新装入模型。

加载保存的模型对象时,请确保重新加载所有需要的包,但是在您的情况下,如果logit模型通过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 

如果想要自动化,那么我可能会在脚本中执行以下操作:

 ## 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是原始的,保存的模型. ~ . . ~ . 是模型公式的变化,在这种情况下意味着包括~的左侧和右侧的所有现有variables(换句话说,不对模型公式进行修改), 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中进行所有的build模和未来预测,那么通过PMML或类似的方法将模型抽象出来似乎没有多less意义。

如果使用相同的数据框和variables名称,则可以(至less对于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) 

这是没有任何数据准备的情况下,等等。 它只是重新使用模型规格集。 请注意,如果您在此期间改变对比度,则新模型会更新为新的对比度,而不是旧对比度。

所以在大多数情况下使用脚本是更好的答案。 可以包括便利function中的所有步骤,只需使用数据框即可,因此您可以input脚本,然后在任何新数据集上使用该function。 也见加文的答案。