Как повторно использовать ваши модели Python без их переобучения

Введение в библиотеку сериализации объектов Python

Примечание. В информатике процесс сохранения объекта для последующего повторного использования называется сериализацией, а загрузка сохраненного объекта - десериализацией. .

Как специалист по анализу данных, вероятно, вы захотели повторно использовать одну из своих моделей без необходимости ее повторного обучения.

Избегать повторного обучения ваших моделей особенно полезно, потому что это позволяет «развернуть» модель, то есть перенести вашу обученную модель на общедоступный сервер, который может быть запрошен для прогнозов любым, у кого есть подключение к Интернету.

Например, предположим, что вы создали простую модель scikit-learn, которую хотите сохранить и использовать позже.

>>> from sklearn.datasets import load_iris
>>> from sklearn.tree import DecisionTreeClassifier
>>> model = DecisionTreeClassifier()
>>> X, y = load_iris(return_X_y=True)
>>> clf = model.fit(X,y)

В этом случае наша обученная модель хранится в объекте Python clf.

Чтобы сохранить объект clf для повторного использования позже, мы воспользуемся встроенной pickle библиотекой.

>>> import pickle
>>> with open('clf.pickle', 'wb') as f:
...     pickle.dump(clf, f)

Мы открыли файл с именем clf.pickle в режиме записи байтов, указав wb, и сохранили ссылку на этот файл в переменной f.

Затем мы использовали метод pickle.dump, чтобы сохранить объект clf в файле clf.pickle. За кулисами Python фактически преобразует объект clf в серию байтов, которые впоследствии можно преобразовать обратно в исходный объект clf.

Вы можете проверить, что содержимое рабочего каталога теперь содержит файл с именем clf.pickle.

>>> import os
>>> os.listdir()
['clf.pickle']

Если вы выйдете из текущего сеанса Python, набрав exit(), а затем запустите новое приглашение Python, вы можете перезагрузить объект clf, чтобы восстановить обученную модель.

>>> import pickle
>>> with open('clf.pickle', 'rb') as f:
...     clf = pickle.load(f)
>>> type(clf)
sklearn.tree._classes.DecisionTreeClassifier

Обратите внимание, как мы открыли файл clf.pickle в режиме «чтения байтов», указав rb, а затем сохранили ссылку на этот файл в переменной f.

Затем pickle.load смог прочитать файл clf.pickle и вернуть новый объект, который точно такой же, как объект clf, который мы изначально передали в pickle.dump.

Любой объект Python можно сохранить в файл с помощью pickle.dump, и точно такой же объект можно загрузить из файла с помощью pickle.load

Таким образом, мы можем использовать новый объект clf, загруженный из файла, чтобы делать прогнозы точно так же, как мы могли бы использовать исходный объект clf для прогнозирования.

>>> clf.predict([
...     [1,1,0,0],
...     [1,0,1,1]
... ])
[0,0]

Конечно, сохранение обученной модели в файл в локальном каталоге означает, что другие люди не смогут повторно использовать модель. Обученную модель удобнее сохранять в базе данных, доступной другим программам.

Сохранение маринованных моделей в базу данных

Модуль pickle позволяет преобразовывать объекты в байты в памяти, которые мы затем можем использовать для сохранения обученной модели в базе данных.

>>> pickled_clf = pickle.dumps(clf)
>>> type(pickled_clf)
bytes

Обратите внимание, как мы использовали метод pickle.dumps, т. Е. «dump s tring», а не метод pickle.dump.

Метод dumps возвратил объект байтов pickled_clf напрямую, а не записал его в файл. (Именование метода dumps было выбрано для согласования с другими библиотеками сериализации, и он не возвращает объект типа str).

Теперь мы можем сохранить объект pickled_clf байтов напрямую в базу данных.

Например, предположим, что у нас есть база данных sqlite3 с именем db.sqlite3, которая содержит таблицу с именем models с полем BLOB (т. Е. Байтами).

sqlite3 db.sqlite3 "create table models(name TEXT, data BLOB);"

Чтобы сохранить маринованную модель в эту таблицу, мы можем использовать модуль sqlite3.

>>> import sqlite3
>>> conn = sqlite3.connect('db.sqlite3')
>>> query = 'insert into models values (?, ?)'
>>> conn.execute(query, ['clf', pickled_clf])
>>> conn.commit()

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

>>> cursor = conn.execute('select * from models')
>>> name, pickled_clf = cursor.fetchone()
>>> clf = pickle.loads(pickled_clf)

Обратите внимание, как мы загрузили классификатор с помощью метода pickle.loads. Так же, как мы использовали pickle.load для восстановления объекта, который был сохранен с pickle.dump, мы можем использовать pickle.loads для восстановления объекта, который был сохранен с pickle.dumps.

Теперь вы можете повторно использовать модель без необходимости ее повторного обучения.

>>> clf.predict([
...     [1,1,0,0],
...     [1,0,1,1]
... ])
[0,0]

Спасибо за прочтение! Если вы нашли это руководство полезным, я пишу о трюках Python и Data Science на Medium, так что вы можете следить за мной, чтобы получать больше статей, подобных этой.