Machine Learning Academy · Урок

Сохранение и загрузка конвейера с помощью joblib

Вы сериализуете обученный Pipeline на диск с помощью joblib.dump, а затем загрузите его в новом сеансе Python, чтобы делать прогнозы без повторного обучения.

Урок 4 из 413 шагов

«Сохранение и загрузка конвейера с помощью joblib» — бесплатный урок Machine Learning Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Machine Learning Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Machine Learning Academy содержит 4 уроков всего.

Зачем сохранять обученный конвейер?

Обучение конвейера машинного обучения может занимать минуты или часы. После обучения его нужно сохранить на диске, чтобы позднее загружать для прогнозирования без повторного обучения. Сохранение также необходимо для развёртывания: Вы обучаете модель на машине разработки, а прогнозы выполняете на рабочем сервере. Сохранённый файл должен включать и шаги предварительной обработки, и веса модели.

Два варианта сериализации: pickle и joblib

Встроенный модуль Python pickle может сериализовать любой объект Python, включая конвейеры sklearn. Сторонняя библиотека joblib (входящая в состав scikit-learn) обычно предпочтительнее для объектов машинного обучения, поскольку эффективнее работает с большими массивами NumPy — использует отображение в память вместо копирования — и может автоматически сжимать выходной файл.

import pickle
import joblib

# Both approaches work; joblib is recommended for sklearn objects
print('pickle version:', pickle.HIGHEST_PROTOCOL)
import sklearn
print('sklearn version:', sklearn.__version__)

Сохранение с помощью joblib.dump

joblib.dump(obj, filename) сериализует конвейер в файл. При необходимости установите compress=3, чтобы использовать сжатие zlib (уровни 1–9; значение 3 обеспечивает баланс между скоростью и размером). Функция возвращает список созданных файлов. Для большинства конвейеров создаётся один файл .pkl или .joblib.

import joblib
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('clf', LogisticRegression(C=1.0, max_iter=200))
])
pipe.fit(X, y)

# Save
joblib.dump(pipe, '/tmp/iris_pipeline.joblib')
print('Pipeline saved!')

Загрузка с помощью joblib.load

joblib.load(filename) десериализует конвейер обратно в объект Python. Загруженный конвейер идентичен исходному: у него те же параметры обученного масштабировщика (среднее и дисперсия) и те же веса модели. Можно сразу вызвать predict, predict_proba или score без повторного обучения.

import joblib
from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)

# Load the saved pipeline
loaded_pipe = joblib.load('/tmp/iris_pipeline.joblib')

# Predict and verify
predictions = loaded_pipe.predict(X[:5])
print('Predictions:', predictions)
print('Test accuracy:', loaded_pipe.score(X, y).round(4))

Проверка точности после сохранения и загрузки

После загрузки убедитесь, что загруженный конвейер выдаёт идентичные прогнозы исходному. Любое несовпадение указывает на ошибку сериализации или несовместимость версий. Простая проверка — сравнить прогнозы поэлементно с помощью np.array_equal.

import joblib
import numpy as np
from sklearn.datasets import load_iris

X, _ = load_iris(return_X_y=True)

# Reload and compare
loaded = joblib.load('/tmp/iris_pipeline.joblib')

# Reload the original reference predictions
# (in practice, save original predictions before reload)
original_preds = loaded.predict(X)  # use loaded as reference
loaded2 = joblib.load('/tmp/iris_pipeline.joblib')
reloaded_preds = loaded2.predict(X)

print('Predictions match:', np.array_equal(original_preds, reloaded_preds))

Варианты сжатия в joblib

Большие конвейеры (например, с RandomForest из 1000 деревьев) могут занимать сотни MB. Используйте joblib.dump(pipe, path, compress=3), чтобы сжимать данные непосредственно во время сохранения. Другой вариант — явно указать алгоритм сжатия: compress=('zlib', 3) или compress=('lz4', 1) для максимальной скорости. LZ4 работает быстрее всего, а zlib создаёт файлы меньшего размера, но работает медленнее.

import joblib
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
import os

X, y = load_iris(return_X_y=True)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())]).fit(X, y)

# Uncompressed
joblib.dump(pipe, '/tmp/pipe_raw.joblib')
# Compressed
joblib.dump(pipe, '/tmp/pipe_compressed.joblib', compress=3)

print('Raw size:', os.path.getsize('/tmp/pipe_raw.joblib'), 'bytes')
print('Compressed size:', os.path.getsize('/tmp/pipe_compressed.joblib'), 'bytes')

Использование pickle как альтернативы

Если joblib недоступен, для конвейеров sklearn подойдёт pickle. Открывайте файл в двоичном режиме ('rb'/'wb'). Для небольших моделей или одноразовых инструментов в виде скриптов pickle вполне подходит; для рабочих систем, обрабатывающих большие массивы NumPy, настоятельно рекомендуется joblib.

import pickle
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())]).fit(X, y)

# Save with pickle
with open('/tmp/model.pkl', 'wb') as f:
    pickle.dump(pipe, f)

# Load with pickle
with open('/tmp/model.pkl', 'rb') as f:
    loaded = pickle.load(f)

print('Loaded score:', loaded.score(X, y).round(4))

Предупреждения о совместимости версий

Критически важный вопрос для рабочей среды: конвейер, сериализованный с помощью scikit-learn 1.2, может некорректно загрузиться в scikit-learn 1.5. Всегда записывайте версии библиотек, использованные во время обучения, в файл метаданных рядом с сохранённой моделью. Используйте pip freeze > requirements.txt или программно сохраните версии рядом с файлом модели.

import sklearn
import numpy as np
import json
import os

metadata = {
    'sklearn_version': sklearn.__version__,
    'numpy_version': np.__version__,
    'model_file': 'iris_pipeline.joblib'
}

with open('/tmp/model_metadata.json', 'w') as f:
    json.dump(metadata, f, indent=2)

print(json.dumps(metadata, indent=2))

Загрузка конвейера в рабочем скрипте

В рабочем сервисе последовательность действий такова: загрузить конвейер один раз при запуске (а не для каждого запроса), получить входные признаки, выполнить предварительную обработку встроенными преобразованиями конвейера и вернуть прогнозы. Поскольку конвейер включает всю предварительную обработку, обслуживающему коду не нужно знать о масштабировании, кодировании или PCA — всё это инкапсулировано в сохранённом объекте.

import joblib
import numpy as np

# At startup (once)
model = joblib.load('/tmp/iris_pipeline.joblib')

def predict(sepal_length, sepal_width, petal_length, petal_width):
    features = np.array([[sepal_length, sepal_width, petal_length, petal_width]])
    label = model.predict(features)[0]
    proba = model.predict_proba(features)[0]
    return {'label': int(label), 'confidence': round(float(proba.max()), 4)}

result = predict(5.1, 3.5, 1.4, 0.2)
print('Prediction result:', result)

Вопросы безопасности при работе с моделями pickle

Никогда не загружайте файл pickle из ненадёжного источника. Файлы pickle могут выполнять произвольный код при загрузке — это фундаментальное ограничение безопасности Python. Для внешнего обмена моделями рассмотрите более безопасные альтернативы в специализированных форматах: ONNX для сериализации между разными платформами или файлы joblib, которыми обмениваются только внутри доверенной инфраструктуры. Перед загрузкой всегда проверяйте контрольную сумму файла.

import hashlib

def file_sha256(path):
    h = hashlib.sha256()
    with open(path, 'rb') as f:
        for chunk in iter(lambda: f.read(65536), b''):
            h.update(chunk)
    return h.hexdigest()

checksum = file_sha256('/tmp/iris_pipeline.joblib')
print('Model SHA-256:', checksum)

# In production: compare this checksum with the one stored in your model registry

Быстрая проверка загрузки и прогнозирования

Ещё одна полезная практика: включите в пакет модели короткий сценарий проверки, который загружает конвейер, подаёт известные входные данные и проверяет ожидаемый результат. Запускайте этот тест в конвейере CI/CD каждый раз при переводе модели в рабочую среду, чтобы убедиться, что файл не повреждён, а окружение совместимо.

import joblib
import numpy as np

# Sanity test
model = joblib.load('/tmp/iris_pipeline.joblib')

# Known input (setosa): sepal_length=5.1, sepal_width=3.5, petal_length=1.4, petal_width=0.2
X_test = np.array([[5.1, 3.5, 1.4, 0.2]])
pred = model.predict(X_test)[0]

# Iris class 0 = setosa
assert pred == 0, f'Expected setosa (0) but got {pred}'
print('Sanity test PASSED — model predicts setosa correctly.')

Быстрая проверка

Проверьте, насколько хорошо Вы поняли сохранение и загрузку конвейеров из этого урока.

Итоги урока

В этом уроке Вы узнали: joblib.dump и joblib.load сохраняют и восстанавливают полностью обученный конвейер, включая все параметры предварительной обработки; всегда сохраняйте версии библиотек вместе с сохранённой моделью, чтобы обеспечить воспроизводимую загрузку; и никогда не загружайте файлы pickle из ненадёжных источников, поскольку они могут выполнять произвольный код. Далее мы рассмотрим несбалансированные наборы данных: научимся выявлять дисбаланс классов и поймём, почему в таких случаях точность вводит в заблуждение.

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «Сохранение и загрузка конвейера с помощью joblib» бесплатный?

Да — полный текст урока «Сохранение и загрузка конвейера с помощью joblib» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Machine Learning Academy, подпишись на CoddyKit PRO. Курс Machine Learning Academy содержит 4 уроков всего.

Чему я научусь в уроке «Сохранение и загрузка конвейера с помощью joblib»?

Вы сериализуете обученный Pipeline на диск с помощью joblib.dump, а затем загрузите его в новом сеансе Python, чтобы делать прогнозы без повторного обучения. Ты практикуешь Machine Learning Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Machine Learning Academy?

Предыдущий опыт не требуется. Machine Learning Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Сохранение и загрузка конвейера с помощью joblib»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Machine Learning Academy?

Да. Каждый урок Machine Learning Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Ваш первый конвейер: масштабирование и классификатор
  2. ColumnTransformer внутри конвейера
  3. Перекрёстная проверка и поиск по сетке для полного конвейера
  4. Сохранение и загрузка конвейера с помощью joblib
← Назад к Machine Learning Academy