在R中构建模型时,如何保存模型规范,以便在新数据上重用它?假设我在历史数据上构建了一个逻辑回归,但直到下个月才有新的观测值。最佳方法是什么?我考虑过的事情:
简单地说,我试图了解当你需要在一个新的会话中使用你的模型时你会做什么。
jhkqcmku1#
如果模型的计算成本不高,我倾向于在R脚本中记录整个模型构建过程,并在需要时重新运行。如果模型拟合中涉及随机元素,我会确保设置一个已知的随机种子。如果模型的计算成本很高,那么我仍然使用上面的脚本,但是使用save()将模型对象保存到rda对象中,然后我倾向于修改脚本,如果保存的对象存在,则加载它,如果不存在,则使用简单的if()...else子句 Package 代码的相关部分,重新调整模型。当加载您保存的模型对象时,请确保重新加载任何所需的包,尽管在您的情况下,如果logit模型是通过glm()拟合的,那么除了R之外将不会加载任何其他包。下面是一个例子:
save()
if()...else
glm()
> 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'的数据框中,然后执行以下操作:
update()
'data'
m2 <- update(m1, . ~ ., data = df)
其中m1是原始的、已保存的模型拟合,. ~ .是模型公式更改,在这种情况下意味着包括~左侧和右侧的所有现有变量(换句话说,不对模型公式进行更改),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()
> 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或类似的方法抽象出模型似乎没有多大意义。
'family'
'subset'
r8xiu3jd2#
如果使用相同名称的 Dataframe 和变量,则可以(至少对于lm()和glm())在保存的模型上使用函数update:
lm()
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)
这是在没有任何数据准备等的情况下偏离轨道的。它只是重用模型规范集。请注意,如果您在此期间更改对比度,新模型将使用新对比度更新,而不是旧对比度。因此,在大多数情况下,使用脚本是更好的答案。可以将所有步骤包含在一个只接受 Dataframe 的方便函数中,这样您就可以获取脚本,然后在任何新数据集上使用该函数。另请参见Gavin的答案。
2条答案
按热度按时间jhkqcmku1#
重用模型来预测新的观测值
如果模型的计算成本不高,我倾向于在R脚本中记录整个模型构建过程,并在需要时重新运行。如果模型拟合中涉及随机元素,我会确保设置一个已知的随机种子。
如果模型的计算成本很高,那么我仍然使用上面的脚本,但是使用
save()
将模型对象保存到rda对象中,然后我倾向于修改脚本,如果保存的对象存在,则加载它,如果不存在,则使用简单的if()...else
子句 Package 代码的相关部分,重新调整模型。当加载您保存的模型对象时,请确保重新加载任何所需的包,尽管在您的情况下,如果logit模型是通过
glm()
拟合的,那么除了R之外将不会加载任何其他包。下面是一个例子:
如果希望自动执行此操作,那么我可能会在脚本中执行以下操作:
当然,数据生成代码将被加载实际数据的代码所替换。
使用新观测值更新先前拟合的模型
如果要使用其他新观测值重新拟合模型,则
update()
是一个有用的函数。它所做的只是使用一个或多个更新的模型参数重新拟合模型。如果要在用于拟合模型的数据中包括新观测值,请将新观测值添加到传递给参数'data'
的数据框中,然后执行以下操作:其中
m1
是原始的、已保存的模型拟合,. ~ .
是模型公式更改,在这种情况下意味着包括~
左侧和右侧的所有现有变量(换句话说,不对模型公式进行更改),df
是用于拟合原始模型的数据框,扩展后包括新的可用观测。下面是一个工作示例:
其他人在评论中提到
formula()
,它从拟合模型中提取公式:但是,如果模型拟合涉及其他参数,如
'family'
或更复杂的模型拟合函数中的'subset'
参数。如果update()
方法可用于模型拟合函数(它们可用于许多常用拟合函数,如glm()
),则它提供了一种比提取和重用模型公式更简单的方法来更新模型拟合。如果您打算在R中进行所有的建模和未来预测,那么通过PMML或类似的方法抽象出模型似乎没有多大意义。
r8xiu3jd2#
如果使用相同名称的 Dataframe 和变量,则可以(至少对于
lm()
和glm()
)在保存的模型上使用函数update
:这是在没有任何数据准备等的情况下偏离轨道的。它只是重用模型规范集。请注意,如果您在此期间更改对比度,新模型将使用新对比度更新,而不是旧对比度。
因此,在大多数情况下,使用脚本是更好的答案。可以将所有步骤包含在一个只接受 Dataframe 的方便函数中,这样您就可以获取脚本,然后在任何新数据集上使用该函数。另请参见Gavin的答案。