R 水平数据预测(使用组模型)
我非常需要帮助:所以我使用dplyr按组运行回归。也就是说像这样的东西:R 水平数据预测(使用组模型),r,R,我非常需要帮助:所以我使用dplyr按组运行回归。也就是说像这样的东西: regressions <- mtcars %>% group_by(cyl) %>% do(fit = lm(wt ~ mpg + qsec + gear, .)) ## cyl fit ## (dbl) (chr) ## 1 4 <S3:lm> ## 2 6 <S3:lm> ## 3 8 <S3:lm&
regressions <- mtcars %>% group_by(cyl) %>%
do(fit = lm(wt ~ mpg + qsec + gear, .))
## cyl fit
## (dbl) (chr)
## 1 4 <S3:lm>
## 2 6 <S3:lm>
## 3 8 <S3:lm>
请记住,测试数据中包含所有级别/组
有没有更简单的方法。即按级别进行预测。目前,我正在尝试在扫帚包中使用增强,但它并没有真正起作用。它所做的是:它通过我所有的测试数据运行每个模型,而忽略级别
请帮忙!我正在做一个更大的规模和需要的东西是快速和有效的 我在到达data.frame中的
lm
对象时遇到了一些问题,因此第一个循环不漂亮:
A <- list()
for (i in unique(mtcars$cyl)) {
A[[as.character(i)]] <- predict(as.list(regressions[regressions$cyl == i, ])$fit[[1]],
newdata = mtcars[mtcars$cyl == i, ])
}
这种方法的唯一问题是系数更难解释,(即:组
cyl=6
的mpg
系数是mpg
的系数加上mpg:cyl6
)对于purrr以及dplyr和tidyr来说,这可能是一项不错的工作。purrr包是用来处理列表的,我相信从长远来看,它将取代do
例如,如果您有一个包含相同变量的测试数据集,我称之为mtcars\u test
mtcars_test = mtcars
您可以基于cyl
将此数据集拆分为三部分
test_split = split(mtcars_test, mtcars_test$cyl)
# check that regression with cyl == 4 and predictions gives the same result
lm_4 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 4))
predict(lm_4, newdata = subset(mtcars, cyl == 4))
scores %>%
filter(cyl == 4)
# check that regression with cyl == 8 and predictions gives the same result
lm_8 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 8))
predict(lm_8, newdata = subset(mtcars, cyl == 8))
scores %>%
filter(cyl == 8)
然后,您可以使用map2
运行三个模型以及分割测试数据,以进行预测。注意,这依赖于模型和数据集列表处于相同的柱面顺序,所以要小心
library(purrr)
map2(regressions$fit, test_split, predict)
结果是一个列表。使用map2\u dfr()
创建外观更好的函数输出,以将输出放入data.frame
在实际情况中,您可能希望在嵌套数据集中得到结果。我无法使用do()。unnest()
函数来自tidyr
library(tidyr)
regs2 = mtcars %>%
nest_by(cyl) %>%
mutate(fit = list(lm(wt ~ mpg + qsec + gear, data = data)))
要使用mutate()
中的map2()
循环浏览模型和新数据集列表,必须对数据集进行解组。在取消测试之前,我在这里删除了输出中的其他列表列,但这并不是绝对必要的
regs2 %>%
ungroup() %>%
mutate(test_pred = map2(fit, test_split, predict) ) %>%
select(-data, -fit) %>%
unnest(test_pred)
# A tibble: 32 x 2
cyl test_pred
<dbl> <dbl>
1 4 2.46
2 4 2.63
3 4 3.39
4 4 1.86
5 4 1.82
6 4 1.83
7 4 2.61
8 4 2.16
9 4 2.06
10 4 1.74
# ... with 22 more rows
regs2%>%
解组()%>%
突变(test_pred=map2(拟合、test_分割、预测))%>%
选择(-data,-fit)%%>%
unnest(测试前)
#一个tibble:32x2
气缸测试
1 4 2.46
2 4 2.63
3 4 3.39
4 4 1.86
5 4 1.82
6 4 1.83
7 4 2.61
8 4 2.16
9 4 2.06
10 4 1.74
# ... 还有22排
使用broom::augment
可以非常紧凑、轻松地实现这一点
你拟合回归和得分:
library(broom)
library(dplyr)
# fit the set of regressions by cyl
regressions = mtcars %>% group_by(cyl) %>%
do(fit = lm(wt ~ mpg + qsec + gear, .))
# score the regressions by cyl
scores = regressions %>%
augment(fit)
您可以检查其结果是否与由cyl
值定义的组的单独回归拟合和评分结果相同
test_split = split(mtcars_test, mtcars_test$cyl)
# check that regression with cyl == 4 and predictions gives the same result
lm_4 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 4))
predict(lm_4, newdata = subset(mtcars, cyl == 4))
scores %>%
filter(cyl == 4)
# check that regression with cyl == 8 and predictions gives the same result
lm_8 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 8))
predict(lm_8, newdata = subset(mtcars, cyl == 8))
scores %>%
filter(cyl == 8)
augment
非常适合在训练集中进行预测,但我没有看到如何使用它对新的测试集进行预测。@aosmith感谢您的评论augment
支持newdata
参数。请参阅augment.lm
的文档。在使用新数据之前,是否必须按因子进行分割,或者您是否可以定义正确的子集,以便以某种方式用于augment
中每个组的预测?@aosmith它的工作方式与对原始数据的工作方式完全相同(我已经演示过)。事实上,一瞬间的思考应该会让你相信,这种行为是不可能不同的。感谢所有回应的人,我真的很感激!非常感谢您的回复。有没有一种方法可以使用相同的逻辑来运行,比如使用auto.ARIMA函数的ARIMA模型或使用相同逻辑的Holtwiners?i、 e如上所述拆分数据集,运行holtwinters,然后返回预测,例如每个周期x个周期。
library(broom)
library(dplyr)
# fit the set of regressions by cyl
regressions = mtcars %>% group_by(cyl) %>%
do(fit = lm(wt ~ mpg + qsec + gear, .))
# score the regressions by cyl
scores = regressions %>%
augment(fit)
# check that regression with cyl == 4 and predictions gives the same result
lm_4 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 4))
predict(lm_4, newdata = subset(mtcars, cyl == 4))
scores %>%
filter(cyl == 4)
# check that regression with cyl == 8 and predictions gives the same result
lm_8 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 8))
predict(lm_8, newdata = subset(mtcars, cyl == 8))
scores %>%
filter(cyl == 8)