Spark ML StringIndexer 不同标签 Training/Testing

Spark ML StringIndexer Different Labels Training/Testing

我正在使用 Scala 并使用 StringIndexer 为训练集中的每个类别分配索引。它根据每个类别的频率分配索引。

问题是在我的测试数据中,类别的频率不同,因此 StringIndexer 为类别分配了不同的索引,这使我无法正确评估模型(随机森林)。

我正在以完全相同的方式处理 training/testing 数据,并且不保存模型。

我尝试过手动创建标签(通过获取类别索引),但出现此错误

java.lang.IllegalArgumentException: RandomForestClassifier was given input with invalid label column label, without the number of classes specified. See StringIndexer.

看来我必须使用 StringIndexer,那么如何确保我用于测试的未来数据集以与训练集相同的方式对类别进行索引?

编辑添加我尝试的解决方法的代码

这就是数据框的样子,称之为 mydata

+--------+-----+---------+---------+
|category|label|        x|        y|
+--------+-----+---------+---------+
| a|      0.0|  -0.166992|-0.256348|
| b|      1.0|  -0.179199| -0.22998|
| c|      2.0|  -0.172119|-0.105713|
| d|      3.0|  -0.064209| 0.050293|

我使用向量汇编器来准备特征

val assembler = new VectorAssembler().setInputCols(Array("x, y")).setOutputCol("features")

使用上面的汇编程序转换 mydata,这就是功能列

val predValues = assembler.transform(mydata)

所以模型需要 2 列,特征和标签。所以我想为此使用我自己的标签。 我 select 来自 predvalues

的特征
 val features = sqlContext.sql("SELECT features from predValues")

和 select 来自我的 df 的标签

 val labelDF = sqlContext.sql("SELECT label FROM filterFeaturesOnly")

然后将两者结合在一起,这样我就可以将特征和标签传递给模型

val featuresAndLabels = features.join(labelDF)

这是我传递给模型的,我得到了上面提到的错误。

val label = predValues.join(labelDF)

如果你想一致地标记东西,那么你需要保存合适的stringIndexer

考虑文档中的 this sample code

val indexer = new StringIndexer()
  .setInputCol("category")
  .setOutputCol("categoryIndex")

val indexed = indexer.fit(df).transform(df)

indexer.fit(df)片returns一个StringIndexerModel,然后可以运行transform的功能。所以改为:

val indexerModel = indexer.fit(trainDF)
val indexed = indexerModel.transform(trainDF)

稍后将允许您使用 indexerModel.transform(testDF) 为相同的输入获取相同的标签。