h2o.deeplearning 中的意外预测

Unexpected predictions in h2o.deeplearning

我正在使用 h2o 包试验深度学习二元分类器。当我构建模型然后在一些新的(保留的)数据集上使用 h2o.predict 时,我注意到对于某些行,Predict 输出与概率最高的值不匹配。

这是一个可重现的例子,改编自h2o's deeplearning tutorial

library(h2o)

h2o.init(nthreads=-1, max_mem_size="2G")
h2o.removeAll()


df <- h2o.importFile(path = "https://raw.githubusercontent.com/h2oai/h2o-tutorials/master/tutorials/data/covtype.full.csv")

splits <- h2o.splitFrame(df, c(0.6,0.2), seed=1234)
train  <- h2o.assign(splits[[1]], "train.hex") # 60%
valid  <- h2o.assign(splits[[2]], "valid.hex") # 20%
test   <- h2o.assign(splits[[3]], "test.hex")  # 20%

response <- "Cover_Type"
predictors <- setdiff(names(df), response)

train$bin_response <- ifelse(train[,response]=="class_1", 0, 1)
train$bin_response <- as.factor(train$bin_response) ##make categorical

# apply same transforms to test
test$bin_response <- ifelse(test[,response]=="class_1", 0, 1)
test$bin_response <- as.factor(test$bin_response)

dlmodel <- h2o.deeplearning(
  x=predictors,
  y="bin_response", 
  training_frame=train,
  hidden=c(10,10),
  epochs=0.1
  #balance_classes=T    ## enable this for high class imbalance
)

pred <- h2o.predict(dlmodel, test)

现在让我们操作它以将其引入 R 并添加一些新列,为简单起见使用 dplyr

pred_df <- bind_cols(
  select(as.data.frame(test), actual = bin_response),
  as.data.frame(pred)
) %>%
  tbl_df %>%
  mutate(
    derived_predict = factor(as.integer(p1 > p0)),
    match = predict == derived_predict
  )

现在我认为预测应该始终与概率最高的列匹配,但情况并非总是如此:

> pred_df %>% summarize(sum(match) / n())
# A tibble: 1 x 1
  sum(match)/n()
           <dbl>
1      0.9691755

为什么这个值不正好是 1?在我最近的 运行 上面的代码中, p0p1 值非常接近

> pred_df %>% filter(!match)
# A tibble: 3,575 x 6
   actual predict        p0        p1 derived_predict match
   <fctr>  <fctr>     <dbl>     <dbl>          <fctr> <lgl>
1       1       1 0.5226679 0.4773321               0 FALSE
2       0       1 0.5165302 0.4834698               0 FALSE
3       0       1 0.5225683 0.4774317               0 FALSE
4       0       1 0.5120126 0.4879874               0 FALSE
5       1       1 0.5342851 0.4657149               0 FALSE
6       0       1 0.5335089 0.4664911               0 FALSE
7       0       1 0.5182881 0.4817119               0 FALSE
8       0       1 0.5094492 0.4905508               0 FALSE
9       0       1 0.5309947 0.4690053               0 FALSE
10      0       1 0.5234880 0.4765120               0 FALSE
# ... with 3,565 more rows

但这仍然不能解释为什么 h2o.predict 选择可能性较小的值。

我是不是做错了什么?这是h2o中的错误吗? h2o 在选择预测时是否有意使用比它在此处显示给我的信息更多的信息?

有趣的是,使用我的 derived_predict 会产生稍微高一点的准确度,差一点:

> pred_df %>%
+   summarize(
+     original = sum(actual == predict)         / n(),
+     derived  = sum(actual == derived_predict) / n()
+   )
# A tibble: 1 x 2
   original   derived
      <dbl>     <dbl>
1 0.7794946 0.7827452

我运行遇到了同样的问题。试图解释预测值与 p1 值的关系。

H2O 默认使用最大 F1 分数进行分类。使用 p1 列,您可以指定自己的阈值。

看文档不是很明显。但你可以在 R 小册子中找到它。在 de DRF、GBM 或深度学习小册子中,St运行 足够多了。