Мне нужно сериализовать модели scikit-learn/statsmodels, чтобы все зависимости (код + данные) были упакованы в артефакт, и этот артефакт можно использовать для инициализации модели и создания прогнозов. Использование pickle module
не является вариантом, потому что это будет только заботиться о зависимости данных (код не будет упакован). Итак, я проводил эксперименты с Dill. Чтобы уточнить мой вопрос, следующий пример - пример создания модели и ее сохранения.
from sklearn import datasets
from sklearn import svm
from sklearn.preprocessing import Normalizer
import dill
digits = datasets.load_digits()
training_data_X = digits.data[:-5]
training_data_Y = digits.target[:-5]
test_data_X = digits.data[-5:]
test_data_Y = digits.target[-5:]
class Model:
def __init__(self):
self.normalizer = Normalizer()
self.clf = svm.SVC(gamma=0.001, C=100.)
def train(self, training_data_X, training_data_Y):
normalised_training_data_X = normalizer.fit_transform(training_data_X)
self.clf.fit(normalised_training_data_X, training_data_Y)
def predict(self, test_data_X):
return self.clf.predict(self.normalizer.fit_transform(test_data_X))
model = Model()
model.train(training_data_X, training_data_Y)
print model.predict(test_data_X)
dill.dump(model, open("my_model.dill", 'w'))
В соответствии с этим, вот как я инициализирую сохраненную модель (в новом сеансе) и сделаю прогноз. Обратите внимание, что этот код явно не инициализирует или не знает о значении class Model
.
import dill
from sklearn import datasets
digits = datasets.load_digits()
training_data_X = digits.data[:-5]
training_data_Y = digits.target[:-5]
test_data_X = digits.data[-5:]
test_data_Y = digits.target[-5:]
with open("my_model.dill") as model_file:
model = dill.load(model_file)
print model.predict(test_data_X)
Кто-нибудь использовал Уилла таким образом?. Идея состоит в том, чтобы ученый-данник расширил ModelWrapper class
для каждой модели, которую они реализуют, а затем построил инфраструктуру вокруг этого, которая сохраняет модели, развертывает модели как службы и управляет всем жизненным циклом модели.
class ModelWrapper(object):
__metaclass__ = abc.ABCMeta
def __init__(self, model):
self.model = model
@abc.abstractmethod
def predict(self, input):
return
def dumps(self):
return dill.dumps(self)
def loads(self, model_string):
self.model = dill.loads(model_string)
Помимо последствий для безопасности (выполнение произвольного кода) и требования о том, что модули, такие как scikit-learn
, должны быть установлены на машине, обслуживающей модель, есть ли и какие-либо другие подводные камни в этом подходе? Любые комментарии или слова совета были бы наиболее полезными.
Я думаю, что YHat и Dato приняли аналогичный подход, но выкатили собственный реализации Уилла для аналогичных целей.