例如,假设我正在尝试训练一个采用以下形式的样本输入的二进制分类器
x = {d=(type of desk), p1=(type of pen on desk), p2=(type of *another* pen on desk)}
说我然后在样本上训练模型:
x1 = {wood, ballpoint, gel}, y1 = {0}
x2 = {wood, ballpoint, ink-well}, y2 = {1}.
并尝试预测新样本:
x3 = {wood, gel, ballpoint}
。在这种情况下,我希望的响应是y3 = {0}
,因为从概念上讲,哪个笔指定为p1或p2无关紧要(即,我不想让它重要)。尝试运行此模型时(在我的情况下,使用h2o.ai生成的模型),出现以下错误:
p2
的类别枚举无效(因为该模型从未在p2
中看到'ballpoint'训练期间的类别)(在h2o中:hex.genmodel.easy.exception.PredictUnknownCategoricalLevelException)我的第一个想法是为每个样本生成“笔”特征的排列以训练模型。有没有更好的方法来处理这种情况?具体来说,在h2o.ai Flow UI解决方案中,因为这就是我用来构建模型的方式。谢谢。
最佳答案
H2O二进制模型(在H2O集群中运行的模型)将自动处理看不见的分类级别,但是,当您使用纯Java POJO模型方法(如您的情况)生成预测时,这是一个可配置的选项。在EasyPredictModelWrapper
中,默认行为是未知类别级别引发PredictUnknownCategoricalLevelException,这就是为什么您看到该错误的原因。
EasyPredictModelWrapper Javadocs中有关于此的更多信息。
这是一个例子:
用于生成的POJO和MOJO模型的简单预测API。用法如下:
1.实例化EasyPredictModelWrapper
2.创建新的数据行
3.调用预测方法之一
这是一个例子:
// Step 1.
modelClassName = "your_pojo_model_downloaded_from_h2o";
GenModel rawModel;
rawModel = (GenModel) Class.forName(modelClassName).newInstance();
EasyPredictModelWrapper model = new EasyPredictModelWrapper(
new EasyPredictModelWrapper.Config()
.setModel(rawModel)
.setConvertUnknownCategoricalLevelsToNa(true));
// Step 2.
RowData row = new RowData();
row.put(new String("CategoricalColumnName"), new String("LevelName"));
row.put(new String("NumericColumnName1"), new String("42.0"));
row.put(new String("NumericColumnName2"), new Double(42.0));
// Step 3.
BinomialModelPrediction p = model.predictBinomial(row);