Сгенерировать таблицу с параллельными моделями узлов объекта `partykit: mob ()`

#r #machine-learning #stargazer #party #modelsummary

#r #машинное обучение #звездочет #Вечеринка #итог моделей

Вопрос:

Допустим, я использую модель partykit:mob() . После этого я хотел бы сгенерировать параллельную таблицу со всеми узлами (включая модель, подобранную с использованием всего образца). Здесь я попытался сделать это с помощью stargazer() , но другие способы более чем приветствуются.

Ниже приведен пример и попытки получить таблицу.

 library("partykit")
require("mlbench")
## Pima Indians diabetes data
data("PimaIndiansDiabetes", package = "mlbench")
## a simple basic fitting function (of type 1) for a logistic regression
logit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {
  glm(y ~ 0   x, family = binomial, start = start, ...)
}
## set up a logistic regression tree
pid_tree <- mob(diabetes ~ glucose | pregnant   pressure   triceps   insulin  
                  mass   pedigree   age, data = PimaIndiansDiabetes, fit = logit)

pid_tree 
# Model-based recursive partitioning (logit)
# 
# Model formula:
#   diabetes ~ glucose | pregnant   pressure   triceps   insulin  
#   mass   pedigree   age
# 
# Fitted party:
#   [1] root
# |   [2] mass <= 26.3: n = 167
# |       x(Intercept)     xglucose
# |        -9.95150963   0.05870786
# |   [3] mass > 26.3
# |   |   [4] age <= 30: n = 304
# |   |       x(Intercept)     xglucose
# |   |        -6.70558554   0.04683748
# |   |   [5] age > 30: n = 297
# |   |       x(Intercept)     xglucose
# |   |        -2.77095386   0.02353582
# 
# Number of inner nodes:    2
# Number of terminal nodes: 3
# Number of parameters per node: 2
# Objective function: 355.4578
 

1. — Извлечь summary(pid_tree, node = x) stargazer() .

 ## I want to replicate this table extracting the the nodes from partykit object.   
library(stargazer)  
m.glm<-   glm(diabetes ~ glucose, family = binomial,data = PimaIndiansDiabetes)

typeof(m.glm)
## [1] "list"
class(m.glm)
## [1] "glm" "lm" 
stargazer(m.glm)
## ommited output.



## Extracting summary from each node
summ_full_data <- summary(pid_tree, node = 1)
summ_node_2    <- summary(pid_tree, node = 2)
summ_node_4    <- summary(pid_tree, node = 4)
summ_node_5    <- summary(pid_tree, node = 5)

## trying to create stargazer table with coefficients
stargazer(m.glm,
          summ_node_2, 
          summ_node_4,
          summ_node_5,title="MOB Results")
##Error: $ operator is invalid for atomic vectors
 

2. — Извлечь pid_tree[x] stargazer() .

 ## Second Attempt (extracting modelparty objects instead)
node_2    <- pid_tree[2]
node_4    <- pid_tree[4]
node_5    <- pid_tree[5]

class(node_5)
##[1] "modelparty" "party"     

stargazer(m.glm,
          node_2, 
          node_4,
          node_5,title="MOB Results")
# % Error: Unrecognized object type.
# % Error: Unrecognized object type.
# % Error: Unrecognized object type.
 

3. — Не очень элегантно, я знаю: заставить класс эмулировать объект glm.

 ## Force class of object to emulate glm one
class(m.glm)
class(summ_node_2) <- c("glm", "lm") 
stargazer(summ_node_2)
##Error in if (p > 0) { : argument is of length zero
 

Довольно прагматичным решением было бы просто перенастроить модель, восстанавливающую найденные правила partykit:mob() , а затем использовать stargaze() их, но, конечно, я здесь чего-то не хватает. Заранее спасибо.

Ответ №1:

Лучше всего извлечь (или изменить) список объектов модели для каждого узла, а затем применить выбранный пакет таблиц. Лично мне это не stargazer очень нравится, и я предпочитаю использовать modelsummary вместо этого, а иногда и старое доброе memisc .

Если дерево содержит модель $objects в $info (что касается pid_tree ), вы можете использовать nodeapply() for all nodeids() для извлечения этих:

 pid_models <- nodeapply(pid_tree, ids = nodeids(pid_tree), FUN = function(x) x$info$object)
 

Если вы просто хотите извлечь подогнанные модели для конечных узлов (листьев) дерева, то вы можете сделать это, установив ids = nodeids(pid_tree, terminal = TRUE) .

В качестве альтернативы, особенно когда объекты модели не сохранены, вы можете легко заменить их с помощью:

 pid_models <- refit.modelparty(pid_tree)
 

Здесь вы также можете включить node = nodeids(pid_tree, terminal = TRUE) только для изменения моделей конечных узлов.

Во всех случаях вы можете впоследствии использовать

 msummary(pid_models)
 

для создания сводной таблицы модели. Он поддерживает различные форматы вывода, и, конечно, вы можете дополнительно настроить список, чтобы изменить результаты, например, изменив их имена и т.д. Вывод по умолчанию выглядит следующим образом:

итоговый вывод msummary

Комментарии:

1. Чисто и просто. Одобрить 😉

2. Очень элегантный ответ, большое вам спасибо! Кроме того, будущим читателям может быть полезно знать, что если вы хотите включить только терминальные узлы (как в моем случае), вы можете извлечь их id просто с помощью nodeids(pid_tree, terminal = TRUE) .

3. Спасибо, хороший момент, добавлен в ответ сейчас.

4. Приятно! Кроме того, спасибо за упоминание modelsummary . Я понятия не имел об этом, и после того, как попробовал это всего на пару часов, я могу сказать, что это меняет правила игры (особенно kableExtra ). ). Будучи пользователем old-Stata, я никогда не видел такого гибкого генератора таблиц. Я очень впечатлен @Vincent, спасибо тебе за этот прекрасный инструмент!

Ответ №2:

К сожалению, это была небольшая разница, которая заставляет ее работать. Вот решение, не уверен, что это лучший способ, но оно выполняет свою работу.-

 library(stargazer)  
obj_node_full_sample<- pid_tree[1]$node$info$object
obj_node_2<- pid_tree[2]$node$info$object
obj_node_4<- pid_tree[4]$node$info$object
obj_node_5<- pid_tree[5]$node$info$object

stargazer(obj_node_full_sample,
          obj_node_2,
          obj_node_4,
          obj_node_5,title="Results", align=TRUE)
 

введите описание изображения здесь