Spark ML StringIndexer不同的标签培训/测试

oth*_*r15 2 apache-spark spark-dataframe apache-spark-ml

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

的问题是,在我的测试数据,类别的频率是不同的,因此StringIndexer分配不同的索引的类别,这阻止我正确地评估所述模型(随机森林).

我正在以完全相同的方式处理训练/测试数据,并且不保存模型.

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

java.lang.IllegalArgumentException: RandomForestClassifier was given input with invalid label column label, without the number of classes specified. See StringIndexer.
Run Code Online (Sandbox Code Playgroud)

似乎我必须使用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|
Run Code Online (Sandbox Code Playgroud)

我使用矢量汇编程序来准备功能

val assembler = new VectorAssembler().setInputCols(Array("x, y")).setOutputCol("features")
Run Code Online (Sandbox Code Playgroud)

使用上面的汇编程序转换mydata,它使用features列

val predValues = assembler.transform(mydata)
Run Code Online (Sandbox Code Playgroud)

因此该模型需要2列,功能和标签.所以我想用我自己的标签.我从predvalues中选择了特征

 val features = sqlContext.sql("SELECT features from predValues")
Run Code Online (Sandbox Code Playgroud)

并从我的df中选择标签

 val labelDF = sqlContext.sql("SELECT label FROM filterFeaturesOnly")
Run Code Online (Sandbox Code Playgroud)

然后将两者连接在一起,这样我就可以将功能和标签传递给模型

val featuresAndLabels = features.join(labelDF)
Run Code Online (Sandbox Code Playgroud)

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

val label = predValues.join(labelDF)
Run Code Online (Sandbox Code Playgroud)

Mat*_*ves 13

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

请考虑以下文档中的示例代码:

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

val indexed = indexer.fit(df).transform(df)
Run Code Online (Sandbox Code Playgroud)

indexer.fit(df)片段返回一个StringIndexerModel,然后可以运行该transform函数.所以与其:

val indexerModel = indexer.fit(trainDF)
val indexed = indexerModel.transform(trainDF)
Run Code Online (Sandbox Code Playgroud)

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