yardstick::rmse 分组数据 returns 错误和不正确的结果
yardstick::rmse on grouped data returns error and incorrect results
我想评估几个回归模型的性能,并使用 yardstick
包来计算 RMSE。这是一些示例数据
model obs pred
1 A 1 1
2 B 1 2
3 C 1 3
当我运行下面的代码
library(yardstick)
library(dplyr)
dat %>%
group_by(model) %>%
summarise(RMSE = yardstick::rmse(truth = obs, estimate = pred))
我收到以下错误
Error in summarise_impl(.data, dots) :
no applicable method for 'rmse' applied to an object of class "c('double', 'numeric')".
然而,当我明确提供 .
作为第一个参数时(我认为这不是必需的),我没有收到任何错误,但结果不正确。
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
我期待以下内容
# A tibble: 3 x 2
model RMSE
<fctr> <dbl>
1 A 0
2 B 1.00
3 C 2.00
我知道这个函数有替代方法,但我仍然不明白这种行为。
数据
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")
根据帮助页面 ?yardstick::rmse
,它似乎需要一个数据框作为其第一个参数,这解释了您遇到的错误。
我不太了解那个新包的速度,但该函数似乎希望跨数据框计算汇总统计数据,而不是逐行计算。要强制它逐行 运行,您需要让它认为每一行都是它自己的数据框,并在每个数据框内应用该函数:
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
我们可以使用do
函数将rmse
函数应用到每个组。
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
函数。
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
或者我们可以将 obs
和 pred
列嵌套到列表列中,然后应用 rmse
函数。
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
包进行性能评估。
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
的语法。嵌套数据框将使我们能够轻松地汇总不同模型或不同组之间的信息。
我想评估几个回归模型的性能,并使用 yardstick
包来计算 RMSE。这是一些示例数据
model obs pred
1 A 1 1
2 B 1 2
3 C 1 3
当我运行下面的代码
library(yardstick)
library(dplyr)
dat %>%
group_by(model) %>%
summarise(RMSE = yardstick::rmse(truth = obs, estimate = pred))
我收到以下错误
Error in summarise_impl(.data, dots) : no applicable method for 'rmse' applied to an object of class "c('double', 'numeric')".
然而,当我明确提供 .
作为第一个参数时(我认为这不是必需的),我没有收到任何错误,但结果不正确。
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
我期待以下内容
# A tibble: 3 x 2
model RMSE
<fctr> <dbl>
1 A 0
2 B 1.00
3 C 2.00
我知道这个函数有替代方法,但我仍然不明白这种行为。
数据
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")
根据帮助页面 ?yardstick::rmse
,它似乎需要一个数据框作为其第一个参数,这解释了您遇到的错误。
我不太了解那个新包的速度,但该函数似乎希望跨数据框计算汇总统计数据,而不是逐行计算。要强制它逐行 运行,您需要让它认为每一行都是它自己的数据框,并在每个数据框内应用该函数:
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
我们可以使用do
函数将rmse
函数应用到每个组。
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
函数。
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
或者我们可以将 obs
和 pred
列嵌套到列表列中,然后应用 rmse
函数。
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
包进行性能评估。
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
的语法。嵌套数据框将使我们能够轻松地汇总不同模型或不同组之间的信息。