首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >标准::rmse关于分组数据返回错误和不正确结果

标准::rmse关于分组数据返回错误和不正确结果
EN

Stack Overflow用户
提问于 2018-01-06 20:32:43
回答 2查看 1.1K关注 0票数 2

我想评估几个回归模型的性能,并使用yardstick包来计算RMSE。以下是一些示例数据

代码语言:javascript
复制
  model obs pred
1     A   1    1
2     B   1    2
3     C   1    3

当我运行以下代码时

代码语言:javascript
复制
library(yardstick)
library(dplyr)
dat %>%
 group_by(model) %>%
 summarise(RMSE = yardstick::rmse(truth = obs, estimate = pred))

我得到以下错误

Summarise_impl中的错误(.data,dots):对于"c('double','numeric')“类的对象,没有适用的'rmse‘方法。

但是,当我显式地提供.作为第一个参数(我认为这不应该是必要的)时,我没有错误,但是结果是不正确的。

代码语言:javascript
复制
dat %>%
 group_by(model) %>%
 summarise(RMSE = yardstick::rmse(., truth = obs, estimate = pred))
# A tibble: 3 x 2
  model   RMSE
  <fctr> <dbl>
1 A       1.29
2 B       1.29
3 C       1.29

我以为会有以下情况

代码语言:javascript
复制
# A tibble: 3 x 2
  model   RMSE
  <fctr> <dbl>
1 A       0
2 B       1.00
3 C       2.00

我知道这个函数还有其他的选择,但我仍然不理解这种行为。

数据

代码语言:javascript
复制
dat <- structure(list(model = structure(1:3, .Label = c("A", "B", "C"), class = "factor"), obs = c(1, 1, 1), pred = 1:3), .Names = c("model", "obs", "pred"), row.names = c(NA, -3L), class = "data.frame")
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-06 22:21:42

我们可以使用do函数将rmse函数应用于每个组。

代码语言:javascript
复制
dat %>%
  group_by(model) %>%
  do(data_frame(model = .$model[1], obs = .$obs[1], pred = .$pred[1], 
     RMSE = yardstick::rmse(., truth = obs, estimate = pred)))
# # A tibble: 3 x 4
# # Groups: model [3]
# model    obs  pred  RMSE
#  <fctr> <dbl> <int> <dbl>
# 1 A       1.00     1  0   
# 2 B       1.00     2  1.00
# 3 C       1.00     3  2.00

或者,我们可以拆分数据帧并应用rmse函数。

代码语言:javascript
复制
dat %>%
  mutate(RMSE = dat %>%
           split(.$model) %>%
           sapply(yardstick::rmse, truth = obs, estimate = pred))
#   model obs pred RMSE
# 1     A   1    1    0
# 2     B   1    2    1
# 3     C   1    3    2

或者,我们可以将obspred列嵌套到list列,然后应用rmse函数。

代码语言:javascript
复制
library(tidyr)

dat %>%
  nest(obs, pred) %>%
  mutate(RMSE = sapply(data, yardstick::rmse, truth = obs, estimate = pred)) %>%
  unnest()
#   model RMSE obs pred
# 1     A    0   1    1
# 2     B    1   1    2
# 3     C    2   1    3

这三种方法的输出略有不同,但都包含正确的RMSE计算。在这里,我使用microbenchmark包进行性能评估。

代码语言:javascript
复制
library(microbenchmark)

microbenchmark(m1 = {dat %>%
    group_by(model) %>%
    do(data_frame(model = .$model[1], obs = .$obs[1], pred = .$pred[1], 
                  RMSE = yardstick::rmse(., truth = obs, estimate = pred)))},
    m2 = {dat %>%
        mutate(RMSE = dat %>%
                 split(.$model) %>%
                 sapply(yardstick::rmse, truth = obs, estimate = pred))},
    m3 = {dat %>%
        nest(obs, pred) %>%
        mutate(RMSE = sapply(data, yardstick::rmse, truth = obs, estimate = pred)) %>%
        unnest()})

# Unit: milliseconds
# expr      min       lq     mean   median       uq       max neval
#   m1 43.18746 46.71055 50.23383 48.46554 51.05639 174.46371   100
#   m2 14.08516 14.78093 16.14605 15.74505 16.89936  24.02136   100
#   m3 28.99795 30.90407 32.71092 31.89954 33.94729  44.57953   100

结果表明,m2是最快的,m1是最慢的。我认为这意味着do操作通常比其他方法慢,所以如果可能的话,我们应该避免使用do操作。虽然m2是最快的,但就我个人而言,我最喜欢m3的语法。嵌套数据框架将使我们能够轻松地总结不同模型或不同组之间的信息。

票数 3
EN

Stack Overflow用户

发布于 2018-01-06 22:12:57

基于帮助页?yardstick::rmse,它似乎期望一个数据框架作为它的第一个参数,这解释了您所得到的错误。

我还不太了解这个新包的速度,但是这个函数似乎希望在一个数据框架中计算一个汇总统计数据,而不是逐行计算。要强制它逐行运行,您需要让它认为每一行都是自己的数据帧,并在每个数据帧中应用该函数:

代码语言:javascript
复制
library(tidyverse)
dat %>%
  group_by(model) %>%
  nest() %>% 
  mutate(rmse_res = map(data, rmse, truth = obs, estimate = pred)) %>% 
  unnest(rmse_res)

# A tibble: 3 x 3
  model  data              rmse
  <fctr> <list>           <dbl>
1 A      <tibble [1 x 2]>  0   
2 B      <tibble [1 x 2]>  1.00
3 C      <tibble [1 x 2]>  2.00
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48131632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档