r - partykit::mob() + mlogit: `错误没有指定合适的拟合函数`
问题描述
我正在尝试使用MOB 算法mlogit::mlogit()
生成的树的末端叶子来拟合条件 logit 。显然,它不能直接使用该功能(在我的尝试之下)。但是,我找到了LORET算法,但是我找不到任何带有示例的文档,所以我尝试从源代码中猜测我需要哪个函数,但不幸的是,我无法让它工作。 partykit::mob()
partykit::mob()
您是否知道 (1) 我可以在哪里找到 LORET 库的示例以及 (2) 是否可以使用该partykit:mob()
函数与 LORET 一起使用mlogit::mlogit
?提前致谢。
示例数据
为了说明,请仔细考虑以下数据。它表示来自 5 个个人 ( id_ind
) 的数据,他们在 3 个备选方案 ( altern
) 中进行选择。五个人每人选择了三遍;因此我们有 15 种选择情况 ( id_choice
)。每个备选方案由两个通用属性 (x1
和x2
) 表示,并且选择注册在y
(1
如果选择,0
否则)。最后,z1
是一个候选分区变量。
df <- read.table(header = TRUE, text = "
id_ind id_choice altern x1 x2 y
1 1 1 1 1.586788801 0.11887832 1
2 1 1 2 -0.937965347 1.15742493 0
3 1 1 3 -0.511504401 -1.90667519 0
4 1 2 1 1.079365680 -0.37267925 0
5 1 2 2 -0.009203032 1.65150370 1
6 1 2 3 0.870474033 -0.82558651 0
7 1 3 1 -0.638604013 -0.09459502 0
8 1 3 2 -0.071679538 1.56879334 0
9 1 3 3 0.398263302 1.45735788 1
10 2 4 1 0.291413453 -0.09107974 0
11 2 4 2 1.632831160 0.92925495 0
12 2 4 3 -1.193272276 0.77092623 1
13 2 5 1 1.967624379 -0.16373709 1
14 2 5 2 -0.479859282 -0.67042130 0
15 2 5 3 1.109780885 0.60348187 0
16 2 6 1 -0.025834772 -0.44004183 0
17 2 6 2 -1.255129594 1.10928280 0
18 2 6 3 1.309493274 1.84247199 1
19 3 7 1 1.593558740 -0.08952151 0
20 3 7 2 1.778701074 1.44483791 1
21 3 7 3 0.643191170 -0.24761157 0
22 3 8 1 1.738820924 -0.96793288 0
23 3 8 2 -1.151429915 -0.08581901 0
24 3 8 3 0.606695064 1.06524268 1
25 3 9 1 0.673866953 -0.26136206 0
26 3 9 2 1.176959443 0.85005871 1
27 3 9 3 -1.568225496 -0.40002252 0
28 4 10 1 0.516456176 -1.02081089 1
29 4 10 2 -1.752854918 -1.71728381 0
30 4 10 3 -1.176101700 -1.60213536 0
31 4 11 1 -1.497779616 -1.66301234 0
32 4 11 2 -0.931117325 1.50128532 1
33 4 11 3 -0.455543630 -0.64370825 0
34 4 12 1 0.894843784 -0.69859139 0
35 4 12 2 -0.354902281 1.02834859 0
36 4 12 3 1.283785176 -1.18923098 1
37 5 13 1 -1.293772990 -0.73491317 0
38 5 13 2 0.748091387 0.07453705 1
39 5 13 3 -0.463585127 0.64802031 0
40 5 14 1 -1.946438667 1.35776140 0
41 5 14 2 -0.470448172 -0.61326604 1
42 5 14 3 1.478763383 -0.66490028 0
43 5 15 1 0.588240775 0.84448489 1
44 5 15 2 1.131731049 -1.51323232 0
45 5 15 3 0.212145247 -1.01804594 0
")
df$z1 <- rnorm(n= nrow(df),mean = 0,sd = 1)
mlogit
+partykit::mob()
library(mlogit)
library(partykit)
mo <- mlogit(formula = y ~ x1 + x2 ,
data = df,
idx = c("id_choice", "altern"))
# Coefficients:
# (Intercept):2 (Intercept):3 x1 x2
# 0.036497 0.293254 0.821173 1.062794
mlogit_function <- function(y, x,
offset = NULL,
...){ mlogit(y ~ x ,
data = df)}
formula <- y ~ x1 + x2 | z1
mob(formula = formula,
data = df,
fit = mlogit_function,
control = mob_control(minsize = 10,
alpha = 0.01))
# Error in mob(formula = formula, data = df, fit = mlogit_function, control = mob_control(minsize = 10,
# no suitable fitting function specified
mlogit
+loret::multinomtree()
此函数运行树,但这不是我想要的,因为替代 2 缺少常量。
loret::multinomtree(formula = formula,
data = df)
# Model-based recursive partitioning (NULL)
# Model formula:
# y ~ x1 + x2 | z1
#
# Fitted party:
# [1] root: n = 45
# 1:(Intercept) 1:x1 1:x2
# -1.1046317 0.7663315 1.0418296
#
# Number of inner nodes: 0
# Number of terminal nodes: 1
# Number of parameters per node: 3
# Objective function: 22.62393
mlogit
+loret::clmtree()
loret::clmtree(formula = formula,
data = df)
# Error in clm.fit.default(y = c(1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, :
# is.list(y) is not TRUE
解决方案
我没有完整的解决方案,但希望有足够的反馈可以帮助您入门:
区分具有替代特定变量(您感兴趣)的所谓“条件 logit”模型和仅具有特定主题(或特定于个人)变量的经典“多项 logit 模型”非常重要。
mlogit::mlogit()
可以同时适用(也适用于混合版本),但nnet::multinom()
仅支持后者。为了拟合条件 logit 模型,您可以使用长格式和宽格式的数据。您以长格式指定数据,并且还有一个
z1
特定于替代的拆分变量。这意味着来自同一个人的数据最终可能会出现在树的不同节点中,这将是相当尴尬的。相反,最好将数据采用宽格式,以便每一行对应一个个体,然后您可以只考虑个体特定的变量进行拆分。这也将匹配提供个体特定梯度贡献的拟合对象
$gradient
元素的视图。mlogit
(这是sandwich::estfun()
提取的内容,而这又是 的基本信息partykit::mob()
。)也有可能基于替代特定变量进行合理的递归分区,但我发现很难看出这会产生什么样的模型以及这些模型意味着什么。在任何情况下,您都必须编写自己的代码来
estfun
从提供完全分解的替代特定梯度贡献的拟合模型对象中提取 。该
loret
软件包有些未完成,并且很长一段时间没有更新。因此,我目前不建议“在生产中”使用它。此外nnet::multinom()
(underlyingloret::multinomtree()
) 不适合您需要的模型 (如上所述) 并且ordinal::clm()
(underlyingloret::clmtree()
) 用于完全不同的模型。我们想要构建
loret
但尚未完成的一个特定方面是自动检测逻辑模型中的(准)完全分离并在树中适当地处理它。您的
mlogit
+partykit::mob()
方法不起作用,因为拟合功能没有正确的界面(因为您被正确告知)。有关vignette("mob", package = "partykit")
两个受支持的接口,请参阅。要编写适当的接口,您需要确保在每个子集中拥有所需的所有变量。请注意,响应变量加上回归矩阵是不够的,但您还需要索引变量!我建议通过
y
变量或x
为partykit::mob()
.mob_control()
然后你可以设置ytype = "data.frame"
和。xtype = "data.frame"
然后两者y
和x
都作为data.frame
对象提供,并且可以在调用 之前再次组合mlogit::mlogit()
。然后必须以某种方式提供formula
andidx
参数。mlogit()
在下面的示例中,我对它们进行了硬编码。
基于您的示例的说明:您可以设置一个模型拟合函数my_fit()
,该函数期望y
和x
成为数据框,然后使用formula = y ~ x1 + x2
和idx = c("id_choice", "altern")
来拟合mlogit()
模型。
my_fit <- function(y, x = NULL, start = NULL, weights = NULL, offset = NULL, ...) {
mlogit::mlogit(formula = y ~ x1 + x2, data = cbind(y, x), idx = c("id_choice", "altern"))
}
要指定树,您需要通过公式的变量传递mlogit()
模型的所有必需变量:x
mob()
tr <- mob(y ~ x1 + x2 + id_choice + altern | z1, data = df, fit = my_fit,
control = mob_control(ytype = "data.frame", xtype = "data.frame"))
从表面上看,这是可行的。至少它适合根节点中所需的模型,正如您通过检查看到的那样coef(tree)
。但是,它起作用的唯一原因是它甚至没有尝试进行任何分区,因为与参数数量相比,样本量被判断为太小。
但是,当您另外设置minsize = 10
时mob_control()
,分区过程将失败。这样做的原因是拆分变量的长度为 45,但梯度/estfunmlogit()
的长度仅为 15。这是长的替代特定格式与短的个体特定格式。
因此,要使事情正常进行,您必须使用宽格式的数据,然后相应地调整mob()
公式和mlogit()
内部调用my_fit()
。
推荐阅读
- pdf-viewer - 在c#中直接从字节数组显示PDF而不保存到硬盘中
- python - 使用 Python statsmodel 进行多元线性回归
- sql - SQL Server:更改具有固定值的列
- android - 有时 onPostExecute(Byte val) 没有被调用
- excel - 删除整行
- php - 注意:未定义的变量:PHP 中的 id
- active-directory - 从 Active Directory 获取部门编号
- python - 如何设置新创建的 csv 文件的位置?
- python - 使用具有多个元素的字典过滤数据框
- r - 循环基础 R 以获得每个区域的 pdf 图或该图的 ggplot 替代品