R语言按数据框分组拟合模型对非组内数据计算RMSE的实现问题
实现方案
原代码核心问题梳理
- RMSE计算逻辑错误:原代码中
sum(.y - .y)为笔误,且计算逻辑不符合RMSE的定义 - 作用域问题:在
map的匿名函数中调用cur_data()无法正确获取当前分组的信息 - 数据冗余:使用
group_by + mutate会让同一分组的所有行重复存储模型、测试集等非结构化对象,浪费内存 - 关于你提到的为什么要把模型包在list里:tibble的常规列要求每个元素是等长的原子向量,而lm模型、数据集这类长度不匹配的复杂对象,只能存储在列表列中,每个列表位置对应一个分组的对象。
优化后可运行代码
你可以用dplyr的nest_by()实现更简洁的分组建模逻辑,代码如下:
library(tidyverse) # 不需要额外安装依赖包的实现方案 res <- mtcars %>% # 按cyl分组,生成分组嵌套数据,每个cyl取值对应一行 nest_by(cyl) %>% mutate( # 拟合本组的线性模型 model = list(lm(mpg ~ wt, data = data)), # 生成排除本组的测试数据集 test_data = list(filter(mtcars, cyl != cur_group()$cyl)), # 用本组模型预测测试集的mpg值 pred = list(predict(model, newdata = test_data)), # 计算对应RMSE rmse = sqrt(mean((test_data$mpg - pred)^2)) ) # 提取最终每个cyl分组对应的RMSE结果 res %>% select(cyl, rmse)
结果说明
运行后得到的res中每行对应一个cyl分组的结果,你可以直接提取cyl和rmse列获得最终的评估指标,也可以取出对应分组的模型、测试集、预测值做后续分析。
内容的提问来源于stack exchange,提问作者Lenn
相关产品推荐
相关产品推荐

