public BinomialModelPrediction predictBinomial(RowData data) throws PredictException {
double[] preds = this.preamble(ModelCategory.Binomial, data);
BinomialModelPrediction p = new BinomialModelPrediction();
double d = preds[0];
p.labelIndex = (int)d;
String[] domainValues = this.m.getDomainValues(this.m.getResponseIdx());
p.label = domainValues[p.labelIndex];
p.classProbabilities = new double[this.m.getNumResponseClasses()];
System.arraycopy(preds, 1, p.classProbabilities, 0, p.classProbabilities.length);
if(this.m.calibrateClassProbabilities(preds)) {
p.calibratedClassProbabilities = new double[this.m.getNumResponseClasses()];
System.arraycopy(preds, 1, p.calibratedClassProbabilities, 0, p.calibratedClassProbabilities.length);
}
return p;
}
例如:classProbabilities = [0.82333,0,276666] labelIndex = 1 label = true domainValues = [false,true]
这个labelIndex表示什么是类概率 order与域值顺序相同,如果order相同则表示此处false的概率为0.82333,true的概率为0.27666,但为什么此labelIndex显示为1且标签为true。
请帮我解决这个问题。
答案 0 :(得分:0)
就像汤姆评论的那样,预测并非错误"。您可以从中推断出H2O选择的阈值小于0.27666。你可能有不平衡的训练数据,否则H2O就没有选择一个低阈值来将预测值0.27666分类为1.你的训练集中包含的阳性分类的例子少于负分类吗?
如果您因任何原因不喜欢该阈值,那么您可以手动创建自己的阈值。只需确保您知道如何正确评估使用不同阈值对模型性能的影响,否则我建议您只使用默认阈值。
名称," classProbabilities"用词不当。这些不是实际概率,它们是预测值,尽管人们经常交替使用这些术语。二进制分类算法产生"预测值"当它们在0和1之间时看起来像是概率,但除非calibration process is performed,它们不会代表概率。校准不一定是直接的过程,并且有许多技术。这里有关于不平衡数据的校准方法的更多info。在H2O中,您可以使用calibrate_model
选项使用Platt缩放执行校准。但这可能不是你想要做的事情所必需的。
使用二元分类模型的原始输出的正确方法是仅查看正类的预测值(您可以简单地忽略负类的预测值)。然后您选择一个适合您需求的阈值,或者您可以使用H2O中的默认阈值,这是为了最大化F1分数而选择的。其他一些软件将使用0.5的硬编码阈值,但如果你的训练数据中没有偶数个正面和负面的例子,这将是一个糟糕的选择。如果您的训练数据中只有少数正面例子,那么最佳阈值将远低于0.5。