Могу ли я использовать StringIndexer без One-Hot-Encoding в PMML (экспорт из Spark)? - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь взять функциональный, адаптированный конвейер 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? Есть ли какая-то другая ошибка, которую я пропускаю?

1 Ответ

0 голосов
/ 10 мая 2019

Это конкретное исключение касается конфликтующего определения "stringCol1" - его пространство значений было определено как StringIndexer ([MT, IP, OB, GA, ED, OP]), и теперь VectorIndexer пытается повторноопределить его с другим пространством значений.Одна из этих попыток неверна.

Возможно, это ошибка библиотеки JPMML-SparkML или вашего скрипта.Возможно, вывод StringIndexerModel вообще не должен быть VectorIndexed?

...