在MOJO或POJO格式中从磁盘加载保存的模型的R h2o方法

8

我正在了解 h2o 的 MOJO 和 POJO 模型格式。我能够使用 MOJO/POJO 将模型保存。

h2o.download_mojo(model, path = "/media/somewhere/tmp") # ok
h2o.download_pojo(model, path = "/media/somewhere/tmp") # ok

这段代码用于将一个名为mymodel.zipmymodel.java的对象写入目录。

但是,我不清楚如何在R服务器中读取它。我尝试过:

saved_model2 <- h2o.loadModel("/media/somewhere/tmp/mymodel.java") # not work
saved_model3 <- h2o.loadModel("/media/somewhere/tmp/mymodel.zip") # not work

但是收到了以下这样的错误消息:

ERROR: Unexpected HTTP Status code: 400 Bad Request (url = http://localhost:54321/99/Models.bin/)

java.lang.IllegalArgumentException
 [1] "java.lang.IllegalArgumentException: Missing magic number 0x1CED at stream start"  
....
Error in .h2o.doSafeREST(h2oRestApiVersion = h2oRestApiVersion, urlSuffix = page,  : 

ERROR MESSAGE:

Missing magic number 0x1CED at stream start
3个回答

10

如果你想在R中对H2O模型进行预测,那么你有三个选择(你选择哪种方法取决于你的用例):

  1. 你可以使用二进制模型(binary model)而不是 MOJO(或 POJO)。对于此方法,您可以使用 h2o.saveModel() 将模型导出到磁盘,并使用 h2o.loadModel() 将其加载回 H2O 集群中,并使用 predict(model, test) 进行预测。此方法需要运行一个 H2O 集群。
  2. 如果您仍然希望将模型导出为 MOJO(或 POJO) 格式,则可以使用 R 中的 h2o.mojo_predict_df()h2o.mojo_predict_csv() 函数在测试集上生成预测结果(从 R 数据框或 CSV 文件中)。
  3. 作为 #2 的替代方案,如果您的数据以 JSON 格式存在,则可以使用 h2o.predict_json(),但它只能一次评分一行。

你能提供一些有关每种方法的优缺点的详细信息吗?我一直在使用二进制模型,保存/加载都很好。但作为我每天运行的生产流水线的一部分,哪种方法更好呢?感谢您的回复。非常有帮助。 - horaceT
2
如果二进制方法对您有效,则可以坚持使用该方法。缺点是您必须始终运行H2O集群,并且二进制模型与特定版本的H2O绑定。 h2o.predict_json()方法更像是标准纯Java MOJO / POJO方法的便利包装器。在这种情况下,您不需要运行H2O集群,而且可以将模型编译到更大的Java项目中。 - Erin LeDell
1
MOJO/POJO的速度更快,因为在进行预测之前,您不必将测试框架(通常是一个1行数据框)转换为H2OFrame;您可以直接将值作为JSON传递。除非您处理亚毫秒级别的速度(并且这种加速对您很重要),否则如果您已经满意于二进制模型,则没有必要切换到MOJO/POJO。 - Erin LeDell

3
旨在与一起使用。如果您想编译和运行MOJO,需要执行以下操作:

首先,假设您从GBM创建了一个MOJO:

library(h2o)
h2o.init(nthreads=-1)
path = "http://h2o-public-test-data.s3.amazonaws.com/smalldata/prostate/prostate.csv"
h2o_df = h2o.importFile(path)
h2o_df$RACE = as.factor(h2o_df$RACE)
model = h2o.gbm(y="CAPSULE",
        x=c("AGE", "RACE", "PSA", "GLEASON"),
        training_frame=h2o_df,
        distribution="bernoulli",
        ntrees=100,
        max_depth=4,
        learn_rate=0.1)

然后将 MOJO 和生成的 h2o-genmodel.jar 文件下载到一个新的实验文件夹中。请注意,h2o-genmodel.jar 文件是支持评分的库,包含所需的读取器和解释器。当 MOJO 模型部署到生产环境时,该文件是必需的。

modelfile = model.download_mojo(path="~/experiment/", get_genmodel_jar=True)
print("Model saved to " + modelfile)
Model saved to /Users/user/GBM_model_R_1475248925871_74.zip"

那么您需要打开一个新的终端窗口,并切换到实验目录,那里有MOJO文件的.zip和.jar文件。

$ cd experiment

接下来,您需要在实验文件夹中创建一个名为main.java的新文件(例如,使用“vim main.java”),作为主程序。请包含以下内容。请注意,该文件引用了上面使用R创建的GBM模型。

import java.io.*;
import hex.genmodel.easy.RowData;
import hex.genmodel.easy.EasyPredictModelWrapper;
import hex.genmodel.easy.prediction.*;
import hex.genmodel.MojoModel;

public class main {
  public static void main(String[] args) throws Exception {
    EasyPredictModelWrapper model = new EasyPredictModelWrapper(MojoModel.load("GBM_model_R_1475248925871_74.zip"));

    RowData row = new RowData();
    row.put("AGE", "68");
    row.put("RACE", "2");
    row.put("DCAPS", "2");
    row.put("VOL", "0");
    row.put("GLEASON", "6");

    BinomialModelPrediction p = model.predictBinomial(row);
    System.out.println("Has penetrated the prostatic capsule (1=yes; 0=no): " + p.label);
    System.out.print("Class probabilities: ");
    for (int i = 0; i < p.classProbabilities.length; i++) {
      if (i > 0) {
    System.out.print(",");
      }
      System.out.print(p.classProbabilities[i]);
    }
    System.out.println("");
  }
}

然后在第二个终端窗口中编译并运行,以显示预测概率。

$ javac -cp h2o-genmodel.jar -J-Xms2g -J-XX:MaxPermSize=128m main.java
$ java -cp .:h2o-genmodel.jar main  

还有一个问题:POJO模型怎么样? - horaceT
@horaceT 是的,download_mojo 函数会保存一个 java 文件,它完全不依赖于 R。要运行此文件,则必须在 java 中进行编译。 - cd98

0
新版本的H2O具有通过Python API导入MOJO的功能:
# re-import saved MOJO
imported_model = h2o.import_mojo(path)

new_observations = h2o.import_file(path='new_observations.csv')
predictions = imported_model.predict(new_observations)

注意:在旧版本的H2O中缺少h2o.import_mojo()函数,因此无法将MOJO重新导入到Python中。

因此,h2o.save_model()似乎已经失去了作用 - 我们可以使用my_model.save_mojo()(请注意,这不是h2o方法,而是模型对象的属性),因为这些文件不仅可以用于Java应用程序部署,还可以在Python中使用(实际上它们仍然在内部使用Python-Java桥接器)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接