我想使用 h2o 进行Rglm 回归,但具有随机效应(HGLM,从本页看来是可能的)。我还没有设法让它工作,并出现我不明白的错误。
这是我的工作示例:我用辛普森悖论定义了一个数据集:全球呈上升趋势,但每组呈下降趋势
library(tidyverse)
library(ggplot2)
library(h2o)
library(data.table)
global_slope <- 1
global_int <- 1
Npoints_per_group <- 50
N_groups <- 10
pentes <- rnorm(N_groups,-1,.5)
centers_x <- seq(0,10,length = N_groups)
center_y <- global_slope*centers_x + global_int
group_spread <- 2
group_names <- sample(LETTERS,N_groups)
df <- lapply(1:N_groups,function(i){
x <- seq(centers_x[i]-group_spread/2,centers_x[i]+group_spread/2,length = Npoints_per_group)
y <- pentes[i]*(x- centers_x[i])+center_y[i]+rnorm(Npoints_per_group)
data.table(x = x,y = y,ID = group_names[i])
}) %>% rbindlist()
Run Code Online (Sandbox Code Playgroud)
您可以识别出类似于辛普森悖论 wiki 页面示例的内容:
ggplot(df,aes(x,y,color = as.factor(ID)))+
geom_point()
Run Code Online (Sandbox Code Playgroud)
没有随机效应的线性回归呈现增加趋势:
lm(y~x,data = df) %>%
summary()
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.28187 0.13077 9.803 <2e-16 ***
x 0.94147 0.02194 42.917 <2e-16 ***
Run Code Online (Sandbox Code Playgroud)
标准的多级回归如下所示:
library(lme4)
library(lmerTest)
lmer( y ~ x + (1+x|ID) ,data = df) %>%
summary()
Run Code Online (Sandbox Code Playgroud)
并会正确估计下降趋势:
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 11.7192 2.6218 8.8220 4.470 0.001634 **
x -1.0418 0.1959 8.9808 -5.318 0.000486 ***
Run Code Online (Sandbox Code Playgroud)
现在我测试h2o:
library(h2o)
h2o.init()
df2 <- as.h2o(df)
test_glm <- h2o.glm(family = "gaussian",
x = "x",
y = "y",
training_frame = df2,
lambda = 0,
compute_p_values = TRUE)
test_glm
Run Code Online (Sandbox Code Playgroud)
而且效果很好,类似于上面的线性模型:
Coefficients: glm coefficients
names coefficients std_error z_value p_value standardized_coefficients
1 Intercept 1.281868 0.130766 9.802785 0.000000 5.989232
2 x 0.941473 0.021937 42.916536 0.000000 3.058444
Run Code Online (Sandbox Code Playgroud)
但是当我想使用随机效果时:
test_glm2 <- h2o.glm(family = "gaussian",
x = "x",
y = "y",
training_frame = df2,
random_columns = "ID",
lambda = 0,
compute_p_values = TRUE)
Run Code Online (Sandbox Code Playgroud)
我有
.h2o.checkAndUnifyModelParameters(algo = algo, allParams = ALL_PARAMS, 中的错误:random_columns 的向量必须是数字类型,但具有字符类型。
即使我强迫df2$ID <- as.numeric(df2$ID)。
我究竟做错了什么?找到类似于混合效应模型lmer(即随机斜率和截距)的正确方法是什么?
按照 Erin LeDell 的建议,我改为使用列号。我现在收到一个不同的错误,我也不明白:
df2$ID <- as.factor(df2$ID)
test_glm2 <- h2o.glm(family = "gaussian",
x = "x",
y = "y",
training_frame = df2,
random_columns = c(3),
HGLM = TRUE,
lambda = 0,
compute_p_values = TRUE)
DistributedException from localhost/127.0.0.1:54321: 'null', caused by java.lang.NullPointerException
DistributedException from localhost/127.0.0.1:54321: 'null', caused by java.lang.NullPointerException
at water.MRTask.getResult(MRTask.java:660)
at water.MRTask.getResult(MRTask.java:670)
at water.MRTask.doAll(MRTask.java:530)
at water.MRTask.doAll(MRTask.java:482)
at hex.glm.GLM$GLMDriver.fitCoeffs(GLM.java:1334)
at hex.glm.GLM$GLMDriver.fitHGLM(GLM.java:1505)
at hex.glm.GLM$GLMDriver.fitModel(GLM.java:2060)
at hex.glm.GLM$GLMDriver.computeSubmodel(GLM.java:2526)
at hex.glm.GLM$GLMDriver.doCompute(GLM.java:2664)
at hex.glm.GLM$GLMDriver.computeImpl(GLM.java:2561)
at hex.ModelBuilder$Driver.compute2(ModelBuilder.java:247)
at hex.glm.GLM$GLMDriver.compute2(GLM.java:1188)
at water.H2O$H2OCountedCompleter.compute(H2O.java:1658)
at jsr166y.CountedCompleter.exec(CountedCompleter.java:468)
at jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:263)
at jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:976)
at jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1479)
at jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)
Run Code Online (Sandbox Code Playgroud)
我实际上找到了一种方法来消除上述错误,通过添加
rand_link = c("identity"),
rand_family = c("gaussian"),
Run Code Online (Sandbox Code Playgroud)
论据h2o.glm:
h2o.glm(family = "gaussian",
rand_link = c("identity"),
rand_family = c("gaussian"),
# compute_p_values = TRUE,
x = "x",
y = "y",
training_frame = df2,
random_columns = c(3),
HGLM = TRUE,
lambda = 0)
Run Code Online (Sandbox Code Playgroud)
作品。但是当我设置后compute_p_values = TRUE,又发现新的错误:
Error in .h2o.doSafeREST(h2oRestApiVersion = h2oRestApiVersion, urlSuffix = page, :
ERROR MESSAGE:
degrees of freedom (0)
Run Code Online (Sandbox Code Playgroud)
代码有一些问题(我们需要更好地记录参数random_columns)。目前该random_columns参数仅支持列索引(不支持列名称),我创建了一个JIRA来改进这一点。
该错误实际上并不是说该列必须是数字;而是说该列必须是数字。事实上它需要成为一个因素。最后,您需要设置HGLM = TRUE. 要修复上面的代码,您可以执行以下操作:
df2$ID2 <- as.factor(df2$ID2)
test_glm2 <- h2o.glm(family = "gaussian",
x = "x",
y = "y",
training_frame = df2,
random_columns = c(4),
HGLM = TRUE,
lambda = 0,
compute_p_values = TRUE)
Run Code Online (Sandbox Code Playgroud)
编辑:这仍然会导致错误,所以我在这里提交了错误报告。
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |