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

时间:2017-04-10 13:19:24

标签: r h2o

我一直在使用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错了吗?我将提供一个示例数据集asap(训练数据集是机密的,350000行×350列)。

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

3 个答案:

答案 0 :(得分:3)

为了让H2O的GLM与R&G的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)) 

这是coefs(它们匹配):

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

答案 1 :(得分: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。

答案 2 :(得分:0)

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

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