Tree and forest model wrappers
The examples in this article use the kenya child-level
data shipped with ineqTrees. The fitted models use
household wealth as the socioeconomic rank, under-five death as the
outcome, and a small set of demographic predictors.
data(kenya, package = "ineqTrees")
kenya_model_vars <- c(
"wealth",
"deadu5_num",
"rural",
"ed",
"reg",
"unskilled"
)
kenya_model_data <- kenya[
stats::complete.cases(kenya[, kenya_model_vars]),
kenya_model_vars
]
set.seed(20260512)
kenya_model_data <- kenya_model_data[
sample.int(nrow(kenya_model_data), 800L),
,
drop = FALSE
]
kenya_predictors <- c("rural", "ed", "reg", "unskilled")
data(kenya, package = "ineqTrees")
kenya_model_vars <- c(
"wealth",
"deadu5_num",
"rural",
"ed",
"reg",
"unskilled"
)
kenya_model_data <- kenya[
stats::complete.cases(kenya[, kenya_model_vars]),
kenya_model_vars
]
set.seed(20260512)
kenya_model_data <- kenya_model_data[
sample.int(nrow(kenya_model_data), 800L),
,
drop = FALSE
]
splitfun <- ci_splitfun(
rank_name = "wealth",
outcome_name = "deadu5_num",
type = "CI"
)
ctrl <- ci_tree_control(minsplit = 100, minbucket = 50, minprob = 0.05)
split <- splitfun(
model = NULL,
trafo = NULL,
data = kenya_model_data,
subset = seq_len(nrow(kenya_model_data)),
weights = rep(1, nrow(kenya_model_data)),
whichvar = match("reg", names(kenya_model_data)),
ctrl = ctrl
)
partykit::character_split(split, kenya_model_data)
#> $name
#> [1] "reg"
#>
#> $levels
#> [1] "Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang'a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi"
#> [2] "Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira"
data(kenya, package = "ineqTrees")
kenya_model_vars <- c(
"wealth",
"deadu5_num",
"rural",
"ed",
"reg",
"unskilled"
)
kenya_model_data <- kenya[
stats::complete.cases(kenya[, kenya_model_vars]),
kenya_model_vars
]
set.seed(20260512)
kenya_model_data <- kenya_model_data[
sample.int(nrow(kenya_model_data), 800L),
,
drop = FALSE
]
fit <- ci_tree(
formula = cbind(wealth, deadu5_num) ~ rural + ed + reg + unskilled,
data = kenya_model_data,
rank_name = "wealth",
outcome_name = "deadu5_num",
control = ci_tree_control(
minsplit = 100,
minbucket = 50,
minprob = 0.05,
maxdepth = 3
)
)
fitGreedy concentration-index tree
Formula:
cbind(wealth, deadu5_num) ~ rural + ed + reg + unskilled
Criterion: CI Tree size: 5 inner
nodes, 6 terminal nodes, max depth 3
| node | n | weight | depth | CI | outcome_mean | outcome_percent | rule |
|---|---|---|---|---|---|---|---|
| 9 | 209 | 209 | 3 | 0.322 | 0.048 | 4.8 | reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Mombasa, Kwale, Kilifi, Tharaka-Nithi, Embu, Makueni, Kiambu, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Kisii, Nyamira} & unskilled in {No} |
| 10 | 127 | 127 | 3 | 0.285 | 0.157 | 15.7 | reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Mombasa, Kwale, Kilifi, Tharaka-Nithi, Embu, Makueni, Kiambu, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Kisii, Nyamira} & unskilled in {Yes} |
| 11 | 86 | 86 | 2 | 0.147 | 0.244 | 24.4 | reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Tana River, Wajir, Mandera, Marsabit, Turkana, Homa Bay} |
| 6 | 137 | 137 | 2 | 0.011 | 0.029 | 2.9 | reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang’a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {Yes} |
| 5 | 132 | 132 | 3 | 0.003 | 0.023 | 2.3 | reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang’a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {No} & reg in {Meru, Nyeri, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} |
| 4 | 109 | 109 | 3 | 0.000 | 0.000 | 0.0 | reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang’a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {No} & reg in {Lamu, Taita Taveta, Garissa, Isiolo, Kitui, Machakos, Nyandarua, Kirinyaga, Murang’a, Trans Nzoia, Nandi, Baringo} |
ci_tree_terminal_summary(fit)
#> node n weight depth ci outcome_mean outcome_percent
#> <int> <int> <num> <int> <num> <num> <num>
#> 1: 4 109 109 3 0.000000000 0.00000000 0.000000
#> 2: 5 132 132 3 0.002525253 0.02272727 2.272727
#> 3: 6 137 137 2 0.010948905 0.02919708 2.919708
#> 4: 9 209 209 3 0.321531100 0.04784689 4.784689
#> 5: 10 127 127 3 0.285039370 0.15748031 15.748031
#> 6: 11 86 86 2 0.146733112 0.24418605 24.418605
#> rule
#> <char>
#> 1: reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang'a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {No} & reg in {Lamu, Taita Taveta, Garissa, Isiolo, Kitui, Machakos, Nyandarua, Kirinyaga, Murang'a, Trans Nzoia, Nandi, Baringo}
#> 2: reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang'a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {No} & reg in {Meru, Nyeri, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi}
#> 3: reg in {Lamu, Taita Taveta, Garissa, Isiolo, Meru, Kitui, Machakos, Nyandarua, Nyeri, Kirinyaga, Murang'a, Trans Nzoia, Nandi, Baringo, Laikipia, Nakuru, Kajiado, Vihiga, Busia, Kisumu, Migori, Nairobi} & unskilled in {Yes}
#> 4: reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Mombasa, Kwale, Kilifi, Tharaka-Nithi, Embu, Makueni, Kiambu, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Kisii, Nyamira} & unskilled in {No}
#> 5: reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Mombasa, Kwale, Kilifi, Tharaka-Nithi, Embu, Makueni, Kiambu, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Kisii, Nyamira} & unskilled in {Yes}
#> 6: reg in {Mombasa, Kwale, Kilifi, Tana River, Wajir, Mandera, Marsabit, Tharaka-Nithi, Embu, Makueni, Kiambu, Turkana, West Pokot, Samburu, Uasin Gishu, Elgeyo-Marakwet, Narok, Kericho, Bomet, Kakamega, Bungoma, Siaya, Homa Bay, Kisii, Nyamira} & reg in {Tana River, Wajir, Mandera, Marsabit, Turkana, Homa Bay}
data(kenya, package = "ineqTrees")
kenya_model_data <- kenya[
stats::complete.cases(kenya[, "wealth", drop = FALSE]),
"wealth",
drop = FALSE
]
set.seed(20260512)
kenya_model_data <- kenya_model_data[
sample.int(nrow(kenya_model_data), 800L),
,
drop = FALSE
]
wealth_quintile <- cut(
kenya_model_data$wealth,
breaks = stats::quantile(
kenya_model_data$wealth,
probs = seq(0, 1, by = 0.2),
na.rm = TRUE
),
include.lowest = TRUE
)
quintile_weights <- as.numeric(table(wealth_quintile))
as_caseweights(quintile_weights, scale = 1000L)
#> [1] 200 200 200 200 200
data(kenya, package = "ineqTrees")
kenya_model_vars <- c(
"wealth",
"deadu5_num",
"rural",
"ed",
"reg",
"unskilled"
)
kenya_model_data <- kenya[
stats::complete.cases(kenya[, kenya_model_vars]),
kenya_model_vars
]
set.seed(20260512)
kenya_model_data <- kenya_model_data[
sample.int(nrow(kenya_model_data), 800L),
,
drop = FALSE
]
set.seed(20260512)
forest_fit <- ci_forest(
formula = cbind(wealth, deadu5_num) ~ rural + ed + reg + unskilled,
data = kenya_model_data,
rank_name = "wealth",
outcome_name = "deadu5_num",
ntree = 10L,
mtry = 2L,
control = ci_tree_control(
minsplit = 100,
minbucket = 50,
minprob = 0.05,
maxdepth = 3
)
)
ci_forest_summary(forest_fit)
#> ntree mtry type n mean_outcome mean_prediction outcome_ci
#> <int> <int> <char> <int> <num> <num> <num>
#> 1: 10 2 CI 800 0.0725 0.07354455 0.4132759
#> prediction_ci mean_terminal_nodes mean_max_depth
#> <num> <num> <num>
#> 1: 0.1064643 3.2 1.8
head(stats::predict(forest_fit, OOB = FALSE))
#> [1] 0.11454554 0.15889920 0.12928239 0.07539547 0.07130924 0.10565666