Spark ML Pipelines:分类新示例

时间:2017-02-09 15:44:23

标签: classification apache-spark-mllib

我找不到如何使用Spark ML Pipeline来分类一组新的实例(带有未知标签)。 我找到的所有示例都基于具有已知标签的测试集(仅用于评估分类的性能)。

我有以下管道:

    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 });

它完美无缺,既适合估算器又适合运行变压器(针对包含金色标签的测试装置)

但是,当我尝试使用相同的管道来实现"真正的"没有黄金标签的例子(标签正是我们想要获得的),作为管道一部分的StringIndexer抛出异常:

Caused by: org.apache.spark.SparkException: Unseen label: UNKNOWN.

UNKNOWN是我用编程方式创建新的数据集元素时设置的假标签,其中包含新的看不见的示例,当然这种标签不存在于训练集中。我理解为什么会出现这个错误,但有没有办法告诉管道我不再是"培训"或"评估",但使用它进行真正的分类? 如何从新示例(没有已知标签)开始为管道构建有效输入以对其进行分类?

这是我在stackoverflow中的第一个问题,希望我已经清楚地解释了它。 在此先感谢: - )

1 个答案:

答案 0 :(得分:1)

我自己找到了解决方案。

TL; DR:StringIndexer应放在管道之外。

使用StringIndexer转换初始数据集以获取每个标签索引,但不在管道中包含转换。然后在管道的末尾设置一个IndexToString转换器,将预测的索引(用于分类/回归的 ML 算法的结果)转换回分类标签

这样,当存储管道模型以供以后在生产中使用时,将不会有StringIndexer导致上述问题,而IndexToString将解释结果预测模型的输出有意义的标签。