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

Инструкция для новичков в Machine Learning с примерами кода и популярными библиотеками

b50b3ab096825dc6d3e378fa5ad13d75.pngАлександр Рыжков

Ментор Skillfactory, руководитель команды LightAutoML и 4х Kaggle Grandmaster

Создаем Python-окружение и первый Jupyter Notebook

Прежде чем начать работу, необходимо создать виртуальное окружение, которое позволит изолировать зависимости вашего проекта. Затем установите Jupyter Notebook — удобную интерактивную среду для разработки.

Пример создания виртуального окружения и запуска Jupyter Notebook

# Создаем виртуальное окружение с помощью venv
python -m venv my_ml_env
# Активируем окружение (Windows)
my_ml_env\Scripts\activate.bat
# или для Unix-подобных систем:
source my_ml_env/bin/activate
# Устанавливаем необходимые библиотеки
pip install numpy pandas matplotlib seaborn scikit-learn jupyter
# Запускаем Jupyter Notebook
jupyter notebook

Кроме того, фиксирование случайного состояния (seed) важно для воспроизводимости результатов. Пример на Python:

import numpy as np
import random
SEED = 42
np.random.seed(SEED)
random.seed(SEED)

Скачиваем датасет

Для примера используем табличный датасет для бинарной классификации. В качестве источника возьмем набор данных с Kaggle (не Titanic!). В нашем примере это датасет кредитных карт, который можно скачать с Kaggle.

Пример скачивания и распаковки датасета

pip install kaggle
kaggle datasets download uciml/default-of-credit-card-clients-dataset
unzip default-of-credit-card-clients-dataset.zip

Типы задач в машинном обучении:

  • Классификация: разделение объектов на категории (например, является ли транзакция мошеннической или нет).

  • Регрессия: прогнозирование числовых значений (уровня заработной платы, количество поломок и т. п.)

  • Кластеризация: группировка объектов по схожим признакам. В нашей задаче мы будем определять, произойдет ли дефолт по кредитной карте (бинарная классификация).

EDA (Exploratory Data Analysis)

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

Пример кода для EDA

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# Загружаем датасет
PATH = 'UCI_Credit_Card.csv'
df = pd.read_csv(PATH)
df = df.rename(columns={'default.payment.next.month': 'target'})
print(df.head())
print(df.info())
# Проверяем наличие пропущенных значений
print(df.isna().sum())
# Описательная статистика
print(df.describe())

Визуализация распределения таргета

Если таргет распределен неравномерно, можно применять методы балансировки, например oversampling или undersampling.

Пример создания новых признаков

Иногда полезно создать новые признаки, например соотношение между возрастом и кредитным лимитом:

df['age_limit_ratio'] = df['AGE'] / df['LIMIT_BAL']
print(df[['AGE', 'LIMIT_BAL', 'age_limit_ratio']].head())

Моделирование

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

Пример обучения модели с использованием scikit-learn

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, f1_score, accuracy_score
# Подготавливаем данные
X = df.drop(['target', 'ID'], axis=1)
y = df['target']
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=SEED)
# Обучение модели логистической регрессии
model = LogisticRegression(random_state=SEED, max_iter=300)
model.fit(X_train, y_train)
# Оценка модели
y_pred_test_scores = model.predict_proba(X_test)[:,1]
y_pred_test_class = model.predict(X_test)
print(f'ROC-AUC Test: {roc_auc_score(y_test, y_pred_test_scores)}')
print(f'F1 Test: {f1_score(y_test, y_pred_test_class)}')
print(f'Accuracy Test: {accuracy_score(y_test, y_pred_test_class)}')

Обратите внимание:  функционал ошибки (например, log loss) используется для оптимизации модели, а метрики качества (ROC-AUC, Accuracy, F1) — для оценки ее производительности.

Особенности логистической регрессии

Логистическая регрессия требует корректного преобразования признаков. Например, категориальные признаки необходимо преобразовать в числовой формат (One-Hot Encoding или Label Encoding). Также важен процесс масштабирования данных, который помогает алгоритму быстрее сходиться.

Пример масштабирования данных

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Повторное обучение модели на масштабированных данных
model = LogisticRegression(random_state=SEED, max_iter=300)
model.fit(X_train_scaled, y_train)
y_pred_test_scores = model.predict_proba(X_test_scaled)[:,1]
y_pred_test_class = model.predict(X_test_scaled)
print(f'ROC-AUC Test: {roc_auc_score(y_test, y_pred_test_scores)}')

Кроме того, часто возникает проблема мультиколлинеарности (высокой корреляции признаков), что может снизить стабильность модели. Чтобы это исправить, можно удалить избыточные признаки или применить методы отбора признаков (например, PCA для снижения размерности).

Разделение данных — train_test_split

Правильное разделение данных нужно, чтобы предотвратить утечку информации (data leakage) и переобучение. Обычно данные делят на обучающую, валидационную и тестовую выборки. При этом следует использовать параметр stratify,  чтобы сохранить пропорции классов.

Пример разделения данных

from sklearn.model_selection import train_test_split
# Первичное разделение на обучающую и тестовую выборки
X_train_full_new, X_test_new, y_train_full_new, y_test_new = train_test_split(X, y, test_size=0.2, stratify=y, random_state=SEED)
# Из обучающей выборки выделяем валидационную
X_train_new, X_val_new, y_train_new, y_val_new = train_test_split(X_train_full_new, y_train_full_new, test_size=0.25, stratify=y_train_full_new, random_state=SEED)
print("Размеры выборок:")
print("Обучающая:", X_train_new.shape)
print("Валидационная:", X_val_new.shape)
print("Тестовая:", X_test_new.shape)

Пример обучения модели с подбором гиперпараметров

from sklearn.model_selection import GridSearchCV
param_grid = {
    'penalty': ['l1', 'l2'],
    'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]
}
grid_lr_clf = GridSearchCV(LogisticRegression(solver='liblinear'), param_grid, scoring='roc_auc', cv=3, n_jobs=-1, verbose=1)
grid_lr_clf.fit(X_train_scaled, y_train)
print("Лучшая оценка кросс-валидации:", grid_lr_clf.best_score_)
optimized_clf = grid_lr_clf.best_estimator_

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

Сравниваем результаты

Для оценки качества модели часто используют метрику ROC-AUC, которая измеряет способность модели различать классы. Сравнивая результаты на обучающей, валидационной и тестовой выборках, можно выявить признаки переобучения. Если метрика значительно выше на обучении по сравнению с тестом, стоит применять регуляризацию или собирать больше данных.

Пример визуализации ROC-кривой

from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt
fpr, tpr, thresholds = roc_curve(y_test, optimized_clf.predict_proba(X_test_scaled)[:,1])
auc = roc_auc_score(y_test, optimized_clf.predict_proba(X_test_scaled)[:,1])
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'ROC-AUC = {auc:.3f}')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC-Кривая для тестовой выборки')
plt.legend(loc='lower right')
plt.show()

LightAutoML — автоматизация создания моделей

LightAutoML — это библиотека, позволяющая автоматизировать этапы построения моделей. Она помогает быстро получить рабочий прототип с хорошей метрикой ROC-AUC без ручного подбора гиперпараметров.

Пример установки LightAutoML

pip install -U lightautoml

Пример кода построения LightAutoML-модели

from lightautoml.automl.presets.tabular_presets import TabularAutoML
from lightautoml.tasks import Task
# Создаем объект автоматизированного ML
automl = TabularAutoML(task=Task('binary'), timeout=600, cpu_limit=4, reader_params = {'random_state': SEED, 'cv': 5})
# Обучаем модель
X_train_full_new['TARGET'] = y_train_full_new
oof_pred = automl.fit_predict(X_train_full_new, roles = {'target': 'TARGET'}, verbose = 1)
# Предсказываем на тестовой выборке
test_pred = automl.predict(X_test_new)
print("ROC-AUC LightAutoML OOF:", roc_auc_score(y_train_full_new, oof_pred.data[:, 0]))
print("ROC-AUC LightAutoML TEST:", roc_auc_score(y_test_new, test_pred.data[:, 0]))

LightAutoML упрощает процесс построения модели, автоматически подбирая оптимальные гиперпараметры, алгоритмы и методы их комбинирования. Как итог, мы за 5 минут получили 77,9% метрики ROC-AUC против 72,6% у логистической регрессии с подобранными параметрами.

Этот опыт станет отличной отправной точкой для дальнейшего изучения и углубления знаний в области ML. Рекомендую новичкам экспериментировать с различными моделями и изучать успешные кейсы, а профессионалам — совершенствовать процессы предобработки данных и искать новые методы оптимизации.

Обучиться работе с моделями машинного обучения: от базовой математики до написания собственного алгоритма — можно на совместной магистратуре Skillfactory и МИФИ «Прикладной анализ данных и машинное обучение».

© Habrahabr.ru