10.1. Несогласованная предварительная обработка ¶
Цель этой главы — проиллюстрировать некоторые распространенные ловушки и антишаблоны, которые возникают при использовании scikit-learn. В нем приведены примеры того, чего не следует делать, и соответствующий правильный пример.
scikit-learn предоставляет библиотеку преобразований набора данных , которые могут очищать (см. Предварительная обработка данных ), уменьшать (см. Неконтролируемое уменьшение размерности ), расширять (см. Аппроксимация ядра ) или генерировать (см. Извлечение функций ) представления функций. Если эти преобразования данных используются при обучении модели, они также должны использоваться в последующих наборах данных, будь то тестовые данные или данные в производственной системе. В противном случае пространство функций изменится, и модель не сможет работать эффективно.
В следующем примере давайте создадим синтетический набор данных с одной функцией:
>>> from sklearn.datasets import make_regression >>> from sklearn.model_selection import train_test_split >>> random_state = 42 >>> X, y = make_regression(random_state=random_state, n_features=1, noise=1) >>> X_train, X_test, y_train, y_test = train_test_split( ... X, y, test_size=0.4, random_state=random_state)
Неправильный
Набор данных поезда масштабируется, но не набор тестовых данных, поэтому производительность модели в наборе тестовых данных хуже, чем ожидалось:
>>> from sklearn.metrics import mean_squared_error >>> from sklearn.linear_model import LinearRegression >>> from sklearn.preprocessing import StandardScaler >>> scaler = StandardScaler() >>> X_train_transformed = scaler.fit_transform(X_train) >>> model = LinearRegression().fit(X_train_transformed, y_train) >>> mean_squared_error(y_test, model.predict(X_test)) 62.80...
Верно
Вместо того, чтобы передавать непреобразованное X_test
в predict
, мы должны преобразовать тестовые данные так же, как мы преобразовали данные обучения:
>>> X_test_transformed = scaler.transform(X_test) >>> mean_squared_error(y_test, model.predict(X_test_transformed)) 0.90...
В качестве альтернативы мы рекомендуем использовать Pipeline
, что упрощает цепочку преобразований с оценками и снижает возможность забыть преобразование:
>>> from sklearn.pipeline import make_pipeline >>> model = make_pipeline(StandardScaler(), LinearRegression()) >>> model.fit(X_train, y_train) Pipeline(steps=[('standardscaler', StandardScaler()), ('linearregression', LinearRegression())]) >>> mean_squared_error(y_test, model.predict(X_test)) 0.90...
Конвейеры также помогают избежать еще одной распространенной ошибки: утечки тестовых данных в обучающие данные.