Участие в соревнованиях Kaggle — отличный способ отточить навыки Data Science, но победительское решение в ноутбуке и промышленный конвейер — это две большие разницы. Миграция кода с Kaggle в продакшн-среду — критический этап, который часто упускают из виду. Эта инструкция проведет вас через весь процесс: от извлечения логики из сырого ноутбука до создания модульного, тестируемого и развертываемого пайплайна.
Шаг 1: Анализ и декомпозиция ноутбука. Не пытайтесь перенести ноутбук целиком. Откройте его и выделите логические блоки: загрузка данных, предобработка (EDA, очистка, feature engineering), разделение на train/val/test, определение и обучение модели, инференс, создание сабмита. Каждый из этих блоков станет отдельным модулем или скриптом. Создайте новую структуру проекта:
my_kaggle_pipeline/
├── config/
│ └── params.yaml # Конфигурация путей, гиперпараметров
├── data/
│ ├── make_dataset.py # Скачивание/загрузка сырых данных
│ └── preprocess.py # Вся предобработка и feature engineering
├── features/
│ └── build_features.py # Создание фичей (может быть частью preprocess)
├── models/
│ ├── train.py # Обучение модели
│ ├── predict.py # Прогнозирование
│ └── model.py # Архитектура модели (наследник torch.nn.Module или tf.keras.Model)
├── notebooks/
│ └── original_kaggle.ipynb # Исходный ноутбук для справки
├── tests/ # Unit-тесты
├── requirements.txt # Зависимости
├── setup.py # Для упаковки в пакет (опционально)
└── main.py # Точка входа для обучения или инференса
Шаг 2: Вынос конфигурации. Жестко закодированные пути и параметры — главный враг продакшена. Вынесите их в YAML или JSON файл. Используйте библиотеку like Hydra, OmegaConf или просто `yaml`.
# config/params.yaml
data:
raw_path: "data/raw/train.csv"
processed_path: "data/processed/train.parquet"
model:
name: "lightgbm"
params:
n_estimators: 1000
learning_rate: 0.01
num_leaves: 31
training:
test_size: 0.2
random_state: 42
target_column: "target"
# В коде загружаем конфиг:
import yaml
with open('config/params.yaml', 'r') as f:
config = yaml.safe_load(f)
raw_data_path = config['data']['raw_path']
Шаг 3: Рефакторинг предобработки данных. Это самая важная часть. Код из ноутбука, где все происходит в глобальном пространстве имен, нужно превратить в воспроизводимые функции, которые сохраняют fitted состояния (например, `sklearn` трансформеры) для применения на новых данных (тесте и в продакшене).
# data/preprocess.py
import joblib
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
def build_preprocessor(train_df, config):
"""Обучает препроцессор на тренировочных данных и возвращает его."""
# 1. Импьютер для числовых колонок
num_cols = train_df.select_dtypes(include=['number']).columns.tolist()
num_imputer = SimpleImputer(strategy='median')
num_imputer.fit(train_df[num_cols])
# 2. Скалер
scaler = StandardScaler()
scaler.fit(num_imputer.transform(train_df[num_cols])) # fit на импутированных данных
preprocessor = {
'num_imputer': num_imputer,
'scaler': scaler,
'num_cols': num_cols
}
# Сохраняем fitted препроцессор!
joblib.dump(preprocessor, 'models/preprocessor.joblib')
return preprocessor
def apply_preprocessing(df, preprocessor):
"""Применяет обученный препроцессор к новым данным."""
num_imputer = preprocessor['num_imputer']
scaler = preprocessor['scaler']
num_cols = preprocessor['num_cols']
df_processed = df.copy()
df_processed[num_cols] = scaler.transform(num_imputer.transform(df[num_cols]))
return df_processed
Шаг 4: Создание воспроизводимого конвейера обучения. Обучение модели не должно зависеть от порядка ячеек в ноутбуке.
# models/train.py
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from .model import save_model
from data.preprocess import build_preprocessor, apply_preprocessing
def train_pipeline(config):
# Загрузка данных
df = pd.read_csv(config['data']['raw_path'])
# Разделение ДО любой предобработки, чтобы избежать data leakage
train_df, val_df = train_test_split(
df, test_size=config['training']['test_size'],
random_state=config['training']['random_state']
)
# Построение и применение препроцессора
preprocessor = build_preprocessor(train_df, config)
X_train = apply_preprocessing(train_df.drop(columns=[config['training']['target_column']]), preprocessor)
y_train = train_df[config['training']['target_column']]
X_val = apply_preprocessing(val_df.drop(columns=[config['training']['target_column']]), preprocessor)
y_val = val_df[config['training']['target_column']]
# Обучение модели
model = lgb.LGBMRegressor(**config['model']['params'])
model.fit(
X_train, y_train,
eval_set=[(X_val, y_val)],
callbacks=[lgb.early_stopping(50), lgb.log_evaluation(100)]
)
# Сохранение модели
save_model(model, 'models/trained_model.pkl')
print("Модель обучена и сохранена.")
return model, preprocessor
Шаг 5: Подготовка инференс-скрипта. Скрипт для предсказаний должен загружать сохраненные артефакты (модель, препроцессор) и применять их к новым данным.
# models/predict.py
import joblib
import pandas as pd
import lightgbm as lgb
from data.preprocess import apply_preprocessing
def load_artifacts(model_path='models/trained_model.pkl',
preprocessor_path='models/preprocessor.joblib'):
model = joblib.load(model_path)
preprocessor = joblib.load(preprocessor_path)
return model, preprocessor
def predict(input_data_path, config, model=None, preprocessor=None):
"""Делает предсказания для данных по указанному пути."""
if model is None or preprocessor is None:
model, preprocessor = load_artifacts()
df_new = pd.read_csv(input_data_path)
# Важно: применять ту же предобработку, что и к train
X_new = apply_preprocessing(df_new, preprocessor)
predictions = model.predict(X_new)
# Сохранение предсказаний в формате, готовом для сабмита на Kaggle
output_df = pd.DataFrame({
'id': df_new['id'], # предполагая, что есть колонка id
'prediction': predictions
})
output_df.to_csv('data/predictions/submission.csv', index=False)
print("Предсказания сохранены в data/predictions/submission.csv")
return predictions
Шаг 6: Добавление тестов и логирования. Напишите простые unit-тесты для критических функций (например, `apply_preprocessing`). Добавьте логирование с помощью библиотеки `logging`, чтобы отслеживать прогресс обучения и ошибки в продакшене. Оберните основной пайплайн в `main.py`, который может принимать аргументы командной строки (с помощью `argparse`) для выбора режима: обучение или предсказание.
Такой структурированный подход превращает одноразовый исследовательский ноутбук в надежный, воспроизводимый и готовый к развертыванию конвейер машинного обучения, который можно запускать по расписанию, дообучать на новых данных и легко интегрировать в более крупные системы.
Как мигрировать Kaggle: пошаговая инструкция с примерами кода для переноса ноутбуков в продакшн
Подробное руководство по переносу кода из ноутбука Kaggle в продакшн-окружение: от декомпозиции и выноса конфигурации до создания модульного пайплайна предобработки, обучения и инференса с примерами на Python.
295
4
Комментарии (11)