Создание PMML из моделей sklearn с помощью GridSearch в Python

Я хочу обучить модели в sklearn и экспортировать их для выполнения в другие среды через PMML (используя https://github.com/jpmml/sklearn2pmml).

Я могу сгенерировать PMML из обычной модели (k-Nearest Neighbors) (без GridSearch), но с GridSearch получаю следующую ошибку:

TypeError: объект конвейера не является экземпляром PMMLPipeline

Ошибка имеет смысл (поскольку GridSearchCV не возвращает PMMLPipeline), но искал мысли о том, как экспортировать оптимизированную (с GridSearch) модель в PMML (например, есть ли способ включить GridSearch в PMMLPipeline).

Код ниже - TIA для любых мыслей.

from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import GridSearchCV

knn_pipe = PMMLPipeline([
("regressor", KNeighborsRegressor())
])

param_grid = {"regressor__n_neighbors": [3, 2,10],
          "regressor__weights": ["uniform","distance"],
          "regressor__algorithm": ["auto", "ball_tree", "kd_tree"]}

cv = GridSearchCV(knn_pipe, param_grid=param_grid)

print(train.drop('y',axis=1).shape)

cv.fit(X,Y)

best_parameters = cv.best_estimator_.get_params()
print("best parameter = {}".format(best_parameters))

from sklearn2pmml import sklearn2pmml
sklearn2pmml(cv, "kNNMercedes.pmml", with_repr = True)




['regressor__algorithm', 'regressor__n_neighbors', 'regressor__metric', 
'regressor__leaf_size', 'regressor', 'regressor__p', 
'regressor__metric_params', 'steps', 'regressor__n_jobs', 
'regressor__weights']
 (4209, 365)
best parameter = {'regressor__algorithm': 'auto', 'regressor__n_neighbors': 
10, 'regressor__metric': 'minkowski', 'regressor__leaf_size': 30, 'regressor': 
KNeighborsRegressor(algorithm='auto', leaf_size=30, metric='minkowski',
          metric_params=None, n_jobs=1, n_neighbors=10, p=2,
      weights='distance'), 'regressor__p': 2, 'regressor__metric_params': None, 'steps': [('regressor', KNeighborsRegressor(algorithm='auto', leaf_size=30, metric='minkowski',
      metric_params=None, n_jobs=1, n_neighbors=10, p=2,
      weights='distance'))], 'regressor__n_jobs': 1, 'regressor__weights': 
'distance'}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-d548c1bff799> in <module>()
 30 
 31 from sklearn2pmml import sklearn2pmml
---> 32 sklearn2pmml(cv, "kNNMercedes.pmml", with_repr = True)
 33 
 34 print("yeay PMML!")

/Users/venuv/.local/lib/python2.7/site-packages/sklearn2pmml/__init__.pyc in 
sklearn2pmml(pipeline, pmml, user_classpath, with_repr, debug)
125                 print("sklearn2pmml: ", __version__)
126         if(not isinstance(pipeline, PMMLPipeline)):
--> 127                 raise TypeError("The pipeline object is not an 
instance of " + PMMLPipeline.__name__)
128         cmd = ["java", "-cp", os.pathsep.join(_package_classpath() + user_classpath), "org.jpmml.sklearn.Main"]
129         dumps = []

TypeError: The pipeline object is not an instance of PMMLPipeline

person Arsene Lupin    schedule 20.06.2017    source источник
comment
Можете ли вы опубликовать полную трассировку стека ошибок? Кроме того, knn_pipe, который вы пытаетесь сохранить, еще не настроен (обучен).   -  person Vivek Kumar    schedule 20.06.2017
comment
@VivekKumar, спасибо. Я обновил код (и трассировку стека)   -  person Arsene Lupin    schedule 20.06.2017
comment
Вы можете использовать только объект PMMLPipeline внутри этой команды, отсюда и ошибка. Можете ли вы использовать cv.best_estimator_ внутри строки sklearn2pmml?   -  person Vivek Kumar    schedule 20.06.2017


Ответы (1)


Решение состоит в том, чтобы построить PMMLPipeline экземпляр из установленного GridSearchCV экземпляра:

pipeline = PMMLPipeline([
  ("best_estimator", cv.best_estimator_)
])
sklearn2pmml(pipeline, "pipeline.pmml")

Пользователь @ vivek-kumar сообщил об этой проблеме с проектом JPMML-SkLearn и получил там несколько дополнительных комментариев. См. jpmml / jpmml-sklearn # 42.

person user1808924    schedule 20.06.2017
comment
Это не работает. Основная проблема здесь связана с конкретным значением (расстоянием) параметра weights объекта KNeighborsRegressor. - person Vivek Kumar; 20.06.2017
comment
Итак, резюмируя ваши обсуждения с github.com/jpmml/jpmml-sklearn/issues/42 (подтверждено моим собственным прототипом) - 1. cv.best_estimator_ сам по себе PMMLPipeline, 2. 'distance' в настоящий момент не поддерживается aa weights fn. Итак, GridSearchCV без «расстояния» работает, когда я запускаю его с функцией разрешенных весов, без необходимости переносить его в другой конвейер. спасибо за ваши мысли - person Arsene Lupin; 20.06.2017
comment
GridSearchCV работает с uniform функцией весов, но не с distance. Если вы передадите PMMLPipeline в качестве первого аргумента для GridSearchCV, тогда нет необходимости что-либо повторно переносить (поскольку cv.best_estimator также будет PMMLPipeline). Но если первый аргумент является необработанной оценкой, вам нужно обернуть его, как показано выше. Исходное сообщение об ошибке. Объект конвейера не является экземпляром PMMLPipeline. Это означает, что вы имеете / имели дело с необработанным оценщиком, поэтому требуется упаковка. - person user1808924; 21.06.2017
comment
Да, упаковка необходима, когда cv используется внутри команды sklearn2pmml. Но в своем ответе вы используете cv.best_estimator_ и обертываете его, что не требуется. - person Vivek Kumar; 21.06.2017