не может использовать обходной путь для конвейера PMML python

Я пытаюсь создать простой конвейер предварительной обработки для модели кластеризации, использующей K-Means, и экспортировать его в формат PMML. Мне удается заставить конвейер работать, но не удается, наконец, экспортировать его в pmml. Я разделил конвейер на два этапа: обрабатываю числовые данные и обрабатываю категориальные данные.

numeric_features = ['column1','column2','column3']

categorical_features = ['column4','column5']

num_mapper = sklearn_pandas.DataFrameMapper([([numeric_column],SimpleImputer(strategy='median')) for numeric_column in numeric_features] 
    ,df_out=True,default=None)

categorical_mapper = sklearn_pandas.DataFrameMapper([([categorical_column],LabelBinarizer()) for categorical_column in categorical_features]
,df_out=True,default=None)

pipeline = PMMLPipeline(steps=[
    ('num_mapper',num_mapper),
    ('cat_mapper',categorical_mapper)
])

Обратите внимание, что я установил значение по умолчанию None в первом dataFrameMapper, поскольку он позволяет выходному кадру данных сохранять столбцы, которые не были выбраны (столбцы, которые действительно понадобятся второму сопоставителю).

Эти обходные пути работают нормально, проблема возникает позже, когда я пытаюсь экспортировать конвейер в PMML.

sklearn2pmml.sklearn2pmml(pipeline,'mypath')

Эта строка кода дает следующую ошибку

java.lang.IllegalArgumentException: Attribute 'sklearn_pandas.dataframe_mapper.DataFrameMapper.default' has a missing (None/null) value
    at org.jpmml.sklearn.PyClassDict.get(PyClassDict.java:46)
    at org.jpmml.sklearn.PyClassDict.getObject(PyClassDict.java:97)

Я знаю, что эта ошибка, вероятно, вызвана тем фактом, что я устанавливаю по умолчанию значение None в обоих DataFrameMappers, но дело в том, что это был единственный обходной путь, который я нашел, чтобы сохранить столбцы, необходимые для второго сопоставителя. Есть ли какой-нибудь другой обходной путь, который я мог бы использовать? Я знаю, что могу выполнять все преобразования в первом DataFrameMapper, но мне не нравится эта идея, поскольку я хочу отделить числовое преобразование от категориального преобразования.


person Jesus Vasquez    schedule 02.08.2019    source источник


Ответы (1)


Недавно смог понять, как использовать FeatureUnion, и понял, что это может быть элегантное решение. Создайте таких же картографов

numeric_features = ['column1','column2','column3']

categorical_features = ['column4','column5']

num_mapper = sklearn_pandas.DataFrameMapper([([numeric_column],SimpleImputer(strategy='median')) for numeric_column in numeric_features] 
  )

categorical_mapper = sklearn_pandas.DataFrameMapper([([categorical_column],LabelBinarizer()) for categorical_column in categorical_features])

preprocessing = FeatureUnion(transformer_list=[('num_mapper',num_mapper),('cat_mapper',categorical_mapper)])

pipeline = PMMLPipeline(steps=[
    ('preprocessing',preprocessing)
])

sklearn2pmml.sklearn2pmml(pipeline,'mypath')

С помощью этого обходного пути даже удалось избежать использования флагов df_out и default при вызове функции.

person Jesus Vasquez    schedule 02.08.2019
comment
В вашем вопросе у вас есть конвейер, в котором один DataFrameMapper следует за другим - это не работает. FeatureUnion позволяет использовать оба DataFrameMappers в качестве первого шага конвейера - это работает. Почему бы вам просто не объединить эти два DataFrameMappers в один? В качестве альтернативы вы можете заменить DataFrameMapper на sklearn.compose.ColumnTransformer. - person user1808924; 02.08.2019