Честная проверка модели

train_test_split без рассинхронизации X и y

Содержание курса

Согласованность индексов X и y и ошибка раздельного разбиения

После совместного вызова train_test_split(X, y, ...) каждая строка X_train гарантированно соответствует элементу y_train с тем же индексом — при условии, что исходные X и y были согласованы до вызова. Убедиться в этом можно прямо:

print((X_train.index == y_train.index).all())  # True
print((X_test.index  == y_test.index).all())   # True

Когда X и y — pandas-объекты, train_test_split сохраняет оригинальные метки строк, перенося их вместе с данными. Сравнение .index == .index показывает, что одна и та же перестановка была применена к обоим массивам синхронно. Такая проверка полезна: она ловит многие случаи рассинхронизации — например, если X и y случайно имеют разный порядок строк до разбиения.

Теперь представьте альтернативу — два отдельных вызова:

# Опасный антипаттерн
X_train, X_test = train_test_split(X, test_size=0.2, random_state=0)
y_train, y_test = train_test_split(y, test_size=0.2, random_state=0)

При одинаковом random_state и одинаковой длине входов перестановка формально совпадёт. Но стоит кому-то поменять random_state во втором вызове, добавить фильтрацию между строками или случайно передать другой порядок — и строки рассинхронизируются. Модель начнёт учиться на парах (признаки пациента A, показатель прогрессирования заболевания пациента B), и Python не бросит никакого исключения. Ошибка может пройти незамеченной, если не проверить индексы явно.

Совместный вызов устраняет этот риск именно на этапе разделения: одна перестановка применяется ко всем переданным массивам внутри одной функции, и рассинхронизировать их в момент разбиения невозможно. Это и есть главный аргумент в его пользу — не удобство синтаксиса, а структурная защита от целого класса ошибок при самом разбиении.