h2o.glm 与线性回归的 R 中的 glm 不匹配

h2o.glm does not match glm in R for linear regressions

我一直在将 H2O.ai(版本 3.10.3.6)与 R 结合使用。

我正在努力用 h2o.glm 复制 glm 的结果。我希望得到完全相同的结果(在这种情况下,根据均方误差进行评估),但我发现 h2o 的准确性必须更差。由于我的模型是高斯模型,我希望这两种情况都是普通的最小二乘(或最大似然)回归。

这是我的例子:

train <- model.matrix(~., training_df)
test <- model.matrix(~., testing_df)

model1 <- glm(response ~., data=data.frame(train))
yhat1 <- predict(model1 , newdata=data.frame(test))
mse1 <- mean((testing_df$response - yhat1)^2) #5299.128

h2o_training <- as.h2o(train)[-1,]
h2o_testing <- as.h2o(test)[-1,]

model2 <- h2o.glm(x = 2:dim(h2o_training)[2], y = 1,
                  training_frame = h2o_training,
                  family = "gaussian", alpha = 0)

yhat2 <- h2o.predict(model2, h2o_testing)
yhat2 <- as.numeric(as.data.frame(yhat2)[,1])
mse2 <- mean((testing_df$response - yhat2)^2) #8791.334

h2o 模型的 MSE 高 60%。我的假设 glm ≈ h2o.glm 错了吗?我会尽快提供一个示例数据集(训练数据集是机密的,350000 行 x 350 列)。

一个额外的问题:出于某种原因,as.h2o 添加了一个充满 NA 的额外行,因此 h2o_training 和 h2o_testing 有一个额外的行。在构建模型之前删除它(就像我在这里所做的那样:as.h2o(train)[-1,])不会影响回归性能。没有 NA 值传递给 glm 或 h2o.glm;即训练矩阵没有 NA 值。

Is my hypothesis that glm ≈ h2o.glm wrong?

h2o.glm的算法和R的glm不一样

h2o.glm 实际上与 glmnet R 包更相似,因为它们都支持 Elastic Net 正则化(glmnet 的两位作者 Hastie 和 Tibshirani 是 H2O.ai 的顾问)。

在构建 H2O 的 glm 时,我们更多地使用 glmnet 作为衡量标准,而不是 R 的 glm。

话虽如此,您不应该期望结果的系数完全相同,但我也不希望 MSE 如此糟糕。

为了使 H2O 的 GLM 与 R 的 GLM 匹配,您需要设置一些参数,因为默认情况下,它们的功能不同。以下是您需要设置以获得相同结果的示例:

library(h2o)
h2o.init(nthreads = -1)

path <- system.file("extdata", "prostate.csv", package = "h2o")
train <- h2o.importFile(filepath)

# Run GLM of VOL ~ CAPSULE + AGE + RACE + PSA + GLEASON
x <- setdiff(colnames(train), c("ID", "DPROS", "DCAPS", "VOL"))

# Train H2O GLM (designed to match R)
h2o_glmfit <- h2o.glm(y = "VOL", 
                      x = x, 
                      training_frame = train, 
                      family = "gaussian",
                      lambda = 0,
                      remove_collinear_columns = TRUE,
                      compute_p_values = TRUE,
                      solver = "IRLSM")

# Train an R GLM
r_glmfit <- glm(VOL ~ CAPSULE + AGE + RACE + PSA + GLEASON, 
                data = as.data.frame(train)) 

这是系数(它们匹配):

> h2o.coef(h2o_glmfit)
  Intercept     CAPSULE         AGE 
-4.35605671 -4.29056573  0.29789896 
       RACE         PSA     GLEASON 
 4.35567076  0.04945783 -0.51260829 

> coef(r_glmfit)
(Intercept)     CAPSULE         AGE 
-4.35605671 -4.29056573  0.29789896 
       RACE         PSA     GLEASON 
 4.35567076  0.04945783 -0.51260829 

我添加了 JIRA ticket 以将此信息添加到文档中。

我想扩展第一个答案并提出建议:

solver = "IRLSM"
lambda = 0
remove_collinear_columns = TRUE
compute_p_values = TRUE
objective_epsilon = 1e-8
max_iterations = 25

glm() 使用 glm.control(epsilon = 1e-8, maxit = 25, trace = FALSE) 进行任何逻辑回归。