Spark ML Pipelines:对新示例进行分类时看不见的标签异常
Spark ML Pipelines: unseen label exception when classifying new examples
我找不到如何使用 Spark ML 管道对一组新实例(具有未知标签)进行分类。
我找到的所有示例都是基于具有已知标签的测试集(仅用于评估分类性能)。
我有以下管道:
StringIndexer indexer = new StringIndexer().setInputCol("category").setOutputCol("categoryIndex");
Tokenizer tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words");
HashingTF hashingTF = new HashingTF().setNumFeatures(NUM_FEATURES).setInputCol(tokenizer.getOutputCol())
.setOutputCol("rawFeatures");
IDF idf = new IDF().setInputCol(hashingTF.getOutputCol()).setOutputCol("rescaledFeatures");
NaiveBayes naiveBayes = new NaiveBayes().setFeaturesCol(idf.getOutputCol()).setLabelCol("categoryIndex");
Pipeline pipeline = new Pipeline()
.setStages(new PipelineStage[] { indexer, tokenizer, hashingTF, idf, naiveBayes });
它工作完美,既适合估计器又适合 运行 转换器(针对包含金色标签的测试集)
但是当我尝试对没有黄金标签的 "real" 示例使用相同的管道时(标签正是我们想要获得的),作为管道一部分的 StringIndexer 抛出一个例外:
Caused by: org.apache.spark.SparkException: Unseen label: UNKNOWN.
UNKNOWN 是我在使用新的未见示例以编程方式创建新数据集元素时设置的假标签,当然训练集中不存在此类标签。我明白为什么会出现这个错误,但是有没有办法告诉管道我不再是 "training" 或 "evaluating",而是将其用于真正的分类?
我如何才能从新示例(没有已知标签)开始为管道构建有效输入以对其进行分类?
这是我在 Whosebug 中的第一个问题,希望我已经解释清楚了。
提前致谢:-)
我自己找到了解决办法。
TL;DR: StringIndexer
应该放在 管道 .
之外
用StringIndexer
转换初始数据集以获得每个标签索引,但不包括管道中的转换。然后在 管道 的末尾设置一个 IndexToString
转换器来转换预测索引(ML 算法的结果用于 classification/regression) 回到分类标签。
这样,在存储pipeline模型供以后生产使用时,就不会出现StringIndexer
造成上述问题,而IndexToString
将解释预测模型的结果以输出有意义的标签。
我找不到如何使用 Spark ML 管道对一组新实例(具有未知标签)进行分类。 我找到的所有示例都是基于具有已知标签的测试集(仅用于评估分类性能)。
我有以下管道:
StringIndexer indexer = new StringIndexer().setInputCol("category").setOutputCol("categoryIndex");
Tokenizer tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words");
HashingTF hashingTF = new HashingTF().setNumFeatures(NUM_FEATURES).setInputCol(tokenizer.getOutputCol())
.setOutputCol("rawFeatures");
IDF idf = new IDF().setInputCol(hashingTF.getOutputCol()).setOutputCol("rescaledFeatures");
NaiveBayes naiveBayes = new NaiveBayes().setFeaturesCol(idf.getOutputCol()).setLabelCol("categoryIndex");
Pipeline pipeline = new Pipeline()
.setStages(new PipelineStage[] { indexer, tokenizer, hashingTF, idf, naiveBayes });
它工作完美,既适合估计器又适合 运行 转换器(针对包含金色标签的测试集)
但是当我尝试对没有黄金标签的 "real" 示例使用相同的管道时(标签正是我们想要获得的),作为管道一部分的 StringIndexer 抛出一个例外:
Caused by: org.apache.spark.SparkException: Unseen label: UNKNOWN.
UNKNOWN 是我在使用新的未见示例以编程方式创建新数据集元素时设置的假标签,当然训练集中不存在此类标签。我明白为什么会出现这个错误,但是有没有办法告诉管道我不再是 "training" 或 "evaluating",而是将其用于真正的分类? 我如何才能从新示例(没有已知标签)开始为管道构建有效输入以对其进行分类?
这是我在 Whosebug 中的第一个问题,希望我已经解释清楚了。 提前致谢:-)
我自己找到了解决办法。
TL;DR: StringIndexer
应该放在 管道 .
用StringIndexer
转换初始数据集以获得每个标签索引,但不包括管道中的转换。然后在 管道 的末尾设置一个 IndexToString
转换器来转换预测索引(ML 算法的结果用于 classification/regression) 回到分类标签。
这样,在存储pipeline模型供以后生产使用时,就不会出现StringIndexer
造成上述问题,而IndexToString
将解释预测模型的结果以输出有意义的标签。