H2o GLM 仅与某些预测因子相互作用

Raa*_*wal 4 r glm h2o one-hot-encoding

我对在 h2o.glm() 中创建交互术语很感兴趣。但我不想生成所有的成对交互。例如,在 mtcars 数据集中...我想将“mpg”与所有其他因素(例如“cyl”、“hp”和“disp”)进行交互,但我不希望其他因素相互交互(所以我不想要 disp_hp 或 disp_cyl)。

我应该如何最好地使用 h2o.glm() 中的 (interactions = interacts_list) 参数来解决这个问题?

谢谢

C8H*_*4O2 5

根据?h2o.glminteractions= 参数采用:

要交互的预测器列索引列表。将为列表计算所有成对组合。

您不需要所有的成对组合,只需要特定的组合。

不幸的是,R H2O API 没有提供公式接口。如果确实如此,则可以通过编程方式指定任意一组交互,就像在 vanilla R glm 中一样。1

选项 1:使用 beta_constraints

一种解决方案是在模型中包含所有成对组合,然后通过将 beta 设置为 0 来抑制那些您不想要的组合。

根据glm docsbeta_constraints=用于:

指定要使用 beta 约束的数据集。所选帧用于约束系数向量以提供上限和下限。数据集必须包含具有有效系数名称的名称列。

根据H2O Glossary,格式为beta_constraints

一个 data.frame 或 H2OParsedData 对象,具有 [“names”, “lower_bounds”,”upper_bounds”, “beta_given”] 列,其中每一行对应于 GLM 中的一个预测器。“names”包含预测变量名称,“lower_bounds”和“upper_bounds”是beta的下限和上限,“beta_given”是一些提供的beta起始值。

现在我们知道如何填写我们的beta_constraints数据框,除了如何格式化交互术语名称。关于交互文档并没有告诉我们会发生什么。因此,让我们运行一个通过 H2O 进行交互的示例,看看交互的名称是什么。

library('h2o')
remoteH2O <- h2o.init(ip='xxx.xx.xx.xxx', startH2O=FALSE)

data(mtcars)

df1 <- as.h2o(mtcars, destination_frame = 'demo_mtcars')

target <- 'wt'
predictors <- c('mpg','cyl','hp','disp')

glm1 <- h2o.glm(x = predictors,
                y = target,
                training_frame = 'demo_mtcars',
                model_id = 'demo_glm',
                lambda = 0, # disable regularization, but your use case may vary
                standardize = FALSE, # we want to see the raw parameters, but your use case may vary
                interactions = predictors # create all interactions
                )
print(glm1) # output includes:
# Coefficients: glm coefficients
#        names coefficients
# 1  Intercept     4.336269
# 2    mpg_cyl     0.019558
# 3     mpg_hp     0.000156
# ..
Run Code Online (Sandbox Code Playgroud)

所以看起来交互术语被命名为v1_v2.

因此,让我们命名我们想要抑制的所有交互术语,使用setdiff()我们想要保留的术语。

library(tidyr)
intx_terms_keep <- # see footnote 1 for explanation
  expand.grid(c('mpg'),c('cyl','hp','disp')) %>%
    unite(intx, Var1, Var2, sep='_') %>% unlist()

intx_terms_suppress <- setdiff( # suppress all interactions minus those we wish to keep
                             combn(predictors,2,FUN=paste,collapse='_'), 
                             intx_terms_keep
                            )
constraints <- data.frame(names=intx_terms_suppress, 
                          lower_bounds=0, 
                          upper_bounds=0, 
                          beta_given=0)

glm2 <- h2o.glm(x = predictors,
                y = target,
                training_frame = 'demo_mtcars',
                model_id = 'demo_glm',
                lambda = 0,
                standardize = FALSE, 
                interactions = predictors, # create all interactions
                beta_constraints = constraints
)
print(glm2) # output includes:
# Coefficients: glm coefficients
#        names coefficients
# 1  Intercept     3.405154
# 2    mpg_cyl    -0.012740
# 3     mpg_hp    -0.000250
# 4   mpg_disp     0.000066
# 5     cyl_hp     0.000000
# 6   cyl_disp     0.000000
# 7    hp_disp     0.000000
# 8        mpg    -0.018981
# 9        cyl     0.168820
# 10      disp     0.004070
# 11        hp     0.000501
Run Code Online (Sandbox Code Playgroud)

如您所见,只有所需的交互项具有非零系数。其余的实际上被忽略了。 然而,由于它们仍然是模型中的项,它们可能计入自由度并可能影响某些指标(即调整后的 R 平方)。

选项 2:预先创建交互项

正如@Darren Cook 提到的,另一种解决方案是将交互预先创建为训练数据集中的变量。

这种方法将确保不需要的相互作用不计入自由度并影响调整后的 R 平方。

1香草glm配方界面的替代非 H2O 解决方案

glm()允许公式界面的香草 R 中,我将使用expand.grid创建一串交互术语并将其包含在公式中。

传递expand.grid两个向量——您希望将 v1 中的所有术语与 v2 中的所有术语进行交互。

要使用你的榜样,你要交互mpg使用cylhp以及disp

library(tidyr)
intx_term_string <- 
  expand.grid(c('mpg'),c('cyl','hp','disp')) %>%
    unite(intx, Var1, Var2, sep=':') %>% apply(2, paste, collapse='+')
Run Code Online (Sandbox Code Playgroud)

这为您提供了一串交互术语"mpg:cyl+mpg:hp+mpg:disp",您可以将其粘贴到一串其他预测变量中(可能使用粘贴折叠)并使用as.formula().