【问题标题】:h2o.glm does not match glm in R for linear regressions对于线性回归,h2o.glm 与 R 中的 glm 不匹配
【发布时间】:2020-07-16 02:29:26
【问题描述】:

我一直在将 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

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

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

【问题讨论】:

  • 从您自己的 cmets 并且不了解 h2o,看起来 h2o 处理 NA 的方式与 glm 的处理方式非常不同。在发布问题之前,您应该阅读两者的帮助文件
  • @Akabar,训练矩阵中没有 NA,所以这不是问题。我已阅读文档,并且 h2o.glm 声称要“通过迭代重新加权最小二乘法进行最大似然估计”,这应该为高斯模型提供与 ols 相同的参数估计。
  • 如果您在 h2o.glm 中仔细设置参数,则可以复制 glm,但默认设置肯定会做不同的事情。
  • 更具体地说,在我脑海中,看看 lambda_search 和 lambda 参数。我认为lambda_search = FALSE, lambda = 0 会让你更接近 glm 正在做的事情。

标签: r h2o


【解决方案1】:

为了使 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 以将此信息添加到文档中。

【讨论】:

  • 谢谢艾琳。这给了我与 lm 相同的结果。我现在将努力获得与 glmnet 相同的结果。
  • @fifthace 如果您使用 glmnet 默认值,请在 H2O 中设置 alpha = 1.0。请注意,glmnet 可能会找到与 H2O 不同的lambda,因此您可以先运行它,取最佳的lambda 值,然后在h2o.glm() 中使用它。
  • @ErinLeDell 我能够按照您的示例生成上面列出的相同系数;但是,当我尝试对 CAPSULE ~ AGE + RACE + PSA + DCAPS 执行逻辑回归时,与 glm 方法相比,我通过 h20.glm 方法得到了不同的系数;我将家庭从“高斯”更改为“binomail”,但为了获得相同的系数,我还需要指定其他参数吗?
【解决方案2】:

我的假设是 glm ≈ h2o.glm 错了吗?

h2o.glm的算法与R的glm不同。

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

在构建 H2O 的 glm 时,我们使用 glmnet 作为衡量标准,远远超过 R 的 glm。

说了这么多,你不应该期望结果的系数完全相同,但我也不会期望 MSE 如此显着变差。

【讨论】:

  • @Tom K,当使用 10 倍交叉验证来最小化 MSE 选择 alpha 时,glmnet 给我的结果与 glm 几乎相同。基本上,弹性网不太适合我的例子,你的解释是不正确的(在我的情况下)。
【解决方案3】:

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

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) 进行任何逻辑回归。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-01
    • 2020-04-27
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    相关资源
    最近更新 更多