Я пытаюсь взять функциональный, адаптированный конвейер SparkML (Scala, Spark 2.1.1 по соображениям совместимости) и превратить его в PMML для обеспечения взаимодействия и хранения.
На данный момент конвейер имеет следующую форму: Массив (StringIndexer, StringIndexer, VectorAssembler, VectorIndexer). Я попробовал стандартный org.jpmml.sparkml.PMMLBuilder, который прекрасно работает в ситуациях, когда я уже проиндексировал строки в базе данных. (Я знаю, сколько разных строк есть в этих столбцах, и я абсолютно уверен, что они останутся категоричными.) Я планирую использовать их в дереве решений и некоторых других методах на основе дерева, и SparkML имеет прекрасная обработка категориальных переменных в деревьях, которые делают одноразовое кодирование менее чем идеальным.
val strCols = Array("stringCol1","stringCol2")
val strIndexers = strCols.map(c => new StringIndexer().setInputCol(c).setOutputCol(c+"_Indexed"))
val collist = df.columns.diff(strCols) ++ strCols.map(c => c+"_Indexed")
val vectorAssembler = new VectorAssembler()
.setInputCols(collist)
.setOutputCol("rawFeatures")
val vectorIndexer = new VectorIndexer().setInputCol("rawFeatures").setOutputCol("features").setMaxCategories(35)
val pipeintro = new Pipeline().setStages(strIndexers :+ vectorAssembler :+ vectorIndexer)
val pipeIntro = pipeintro.fit(df)
val pmmlBuilder = new org.jpmml.sparkml.PMMLBuilder(df.schema, pipeIntro).buildFile(new File("out.pmml"))
Я ожидал, что код завершит работу и выведет соответствующий PMML, но вместо этого я получаю:
java.lang.IllegalArgumentException: Field stringCol1 has valid values [MT, IP, OB, GA, ED, OP]
at org.jpmml.converter.PMMLEncoder.toCategorical(PMMLEncoder.java:209)
at org.jpmml.sparkml.feature.VectorIndexerModelConverter.encodeFeatures(VectorIndexerModelConverter.java:80)
at org.jpmml.sparkml.FeatureConverter.registerFeatures(FeatureConverter.java:47)
at org.jpmml.sparkml.PMMLBuilder.build(PMMLBuilder.java:114)
at org.jpmml.sparkml.PMMLBuilder.buildFile(PMMLBuilder.java:292)
Я проверил на нулевые значения; их нет и другие значения недопустимы. Где-то есть признаки того, что StringIndexers должны быть закодированы в горячем виде перед помещением в VectorAssembler, но это неоптимально для данного конкретного конвейера, поскольку он предназначен для подачи в определенное SparkML дерево, которое хорошо работает с многозначными категориальными столбцами , Это руководство жестко запрограммировано в PMML или кодировщик Spark-PMML? Есть ли какая-то другая ошибка, которую я пропускаю?