1 整洁模型结果 - broom 包
tidyverse 主张以‘‘整洁的” 数据框作为输入,但是lm, nls, t.test, kmeans 等模型的输出结果,却是‘‘不整洁的” 列表。
broom 包实现将模型输出结果转化为整洁的tibble,且列名规范一致,方便后续取用;另外,与
tidyr 包中的nest()/unnest() 函数以及purrr 包中的map_*() 系列函数连用,非常便于批量建模和
批量整合模型结果。
broom 包主要提供了如下3 个函数:
- tidy(): 模型系数估计及其统计量:返回结果tibble 的每一行通常表达的都是具有明确含义的概念,如回归模型的一项,一个统计检验,一个聚类或类;各列包括:
- term: 回归或模型中要估计的项
- estimate: 参数估计值
- statistic: 检验统计量
- p.value: 检验统计量的p 值
- conf.low, conf.high: estimate 的置信区间界
- df: 自由度
-
glance(): 模型诊断信息:返回一行的tibble, 各列是模型诊断信息:
-
augment(): 增加预测值列、残差列等. augment(model, data) 为原始数据增加新列,若data 参数缺失,则只包含模型涉及的列。
例子:
library(broom)
model = lm(mpg ~ wt, data = mtcars)
model %>% tidy()
model %>% glance()
model %>% augment()
model %>% augment() %>%
ggplot(aes(x = wt, y = mpg)) +
geom_point() +
geom_line(aes(y = .fitted), color = "blue") +
geom_segment(aes(xend = wt, yend = .fitted), color = "red")
2 辅助建模 - modelr 包
modelr 包提供了一系列辅助建模的函数,便于在tidyverse 框架下讲授建模.
- resample_*(): 重抽样:。常用的重抽样方法有,简单重抽样(留出, Holdout),自助重抽样(Bootstrap)、交叉验证重抽样(CrossValidation)、置换重抽样(Permutation).
这些重抽样结果:
rsample 包
另外,rsample 包提供了基本工具创建和分析数据集不同类型的重抽样,更适合与**机器学习包tidymodels **连用。
模型性能度量函数:
生成模型数据:
增加预测值列、残差列:
- add_predictions()
- add_residuals()
library(modelr)
ex = resample_partition(mtcars, c(test = 0.3, train = 0.7))
mod = lm(mpg ~ wt, data = ex$train)
rmse(mod, ex$test)
## [1] 3.207508
mod = lm(mpg ~ wt + cyl + vs, data = mtcars)
data_grid(mtcars, wt = seq_range(wt, 10), cyl, vs) %>%
add_predictions(mod)
10 折交叉验证建模的例
(1) 先用crossv_kfold() 生成10 折交叉验证的数据:
cv10 = crossv_kfold(mtcars, 10)
cv10
(2) 接着是批量建模(具体见下节),与普通的修改列是一样的:(用map)计算新列+ 赋值。
cv10 %>%
mutate(models = map(train, ~ lm(mpg ~ wt, data = .)),
rmse = map2_dbl(models, test, rmse))
(3)要计算最终的平均模型效果,对rmse 列做汇总均值即可.
3 批量建模
有时候需要对数据做分组,批量地对每个分组建立同样模型,并提取和使用批量的模型结果,这就是批量建模。
tidyverse 中的两种优雅、简洁的做法:
-
- 用嵌套数据框+ purrr::map 实现
(1)先分组
- 用嵌套数据框+ purrr::map 实现
by_region = ecostats %>%
group_nest(Region)
by_region
by_region$data[[1]] # 查看列表列的第1 个元素的内容
unnest(by_region, data) # 解除嵌套, 还原到原数据
(2)增加模型列
by_region = by_region %>%
mutate(model = map(data, ~ lm(Consumption ~ gdpPercap, data = .x)))
by_region
(3)继续用mutate() 修改列,借助map_* 函数从模型列、数据列计算均方根误差、R2、斜率、p 值
by_region %>%
mutate(rmse = map2_dbl(model, data, rmse),
rsq = map2_dbl(model, data, rsquare),
slope = map_dbl(model, ~ coef(.x)[[2]]),
pval = map_dbl(model, ~ glance(.x)$p.value))
(4)批量提取模型系数估计及其统计量:unnest() 函数解除嵌套
by_region %>%
mutate(result = map(model, tidy)) %>%
select(Region, result) %>%
unnest(result)
-
- 用dplyr 包的rowwise 技术
dplyr 包的rowwise 按行方式,可以理解为一种特殊的分组:每一行作为一组。
- 用dplyr 包的rowwise 技术
(1)若对ecostats 数据框用nest_by() 做嵌套就得到这样rowwise 化的嵌套数据框:
by_region = ecostats %>%
nest_by(Region)
by_region
(2)增加模型
by_region = by_region %>%
mutate(model = list(lm(Consumption ~ gdpPercap, data = data)))
by_region
(3)直接用mutate() 修改列,从模型列、数据列计算均方根误差、R2、斜率、p 值:
by_region %>%
mutate(rmse = rmse(model, data),
rsq = rsquare(model, data),
slope = coef(model)[[2]],
pval = glance(model)$p.value)
也可以配合broom 包的函数tidy(), glance(), augment() 批量、整洁地提取模型结果。
批量提取模型系数估计及其统计量:
by_region %>%
summarise(tidy(model))
批量提取模型诊断信息:
by_region %>%
summarise(glance(model))
批量增加预测值列、残差列等:
by_region %>%
summarise(augment(model))