Вопрос или проблема
Я заполняю свои данные с помощью простого заполняющего устройства из sklearn. Я хочу протестировать множество различных способов применения преобразований к данным. То есть для логистической регрессии я хотел бы
- удалить nans и заменить их на моду
- заменить +infs на максимумы, а -infs на минимумы
- использовать стандартный масштабировщик.
Затем для использования xgboost я хотел бы:
- просто заменить -infs/+infs на очень большие или отрицательные большие числа.
Я играл с конвейером sklearn, и мне хотелось бы узнать, как я могу передать пользовательские заполняющие устройства через конвейер? Например:
logistic_pipeline = Pipeline( steps = [('imputer', SimpleImputer(strategy = 'most frequent') ),
( 'std_scaler', StandardScaler() ),
( 'model', LinearRegression() )] )
Но как мне интегрировать следующую функцию, в которой я заменяю infs в обучающем наборе данных (df) на максимальное значение этого столбца, а затем использую этот максимум для заполнения теста… как я могу сделать это с помощью конвейера?
def replace_pos_inf(df, dftest, numeric_features):
for col in df[numeric_features].columns:
m = df.loc[df[col] != np.inf, col].max()
df[col].replace(np.inf,m,inplace=True)
dftest[col].replace(np.inf,m,inplace=True)
for col in df[numeric_features].columns:
mini = df.loc[df[col] != -np.inf, col].min()
df[col].replace(-np.inf,mini,inplace=True)
dftest[col].replace(-np.inf,mini,inplace=True)
return df,dftest
Поскольку вы хотите сохранить минимумы/максимумы для обучения и использовать их для замены inf в тестовом наборе, вам нужно пользовательское преобразователь. Чтобы создать надежный преобразователь, вам следует использовать некоторые функции проверки из sklearn. И лучше работать в numpy, поскольку, как вы указываете, предыдущий преобразователь в конвейере уже преобразует входной датафрейм в nparray. (Вы можете оставаться с датафреймами и либо преобразовывать в вашем преобразователе (потеряв некоторую эффективность), либо убедиться, что ваш преобразователь всегда первый в конвейере (что в порядке, если вы единственный, кто использует свой код).)
Вот простая версия. Я предпочитаю не использовать numeric_features
как входные данные; вам, вероятно, стоит использовать ColumnTransformer
, чтобы выполнять такой выбор для вас.
from sklearn.utils import check_array
from sklearn.utils.validation import check_is_fitted
from sklearn.base import TransformerMixin, BaseEstimator
class ReplaceInf(TransformerMixin, BaseEstimator):
'''Заменить +-np.inf на максимальные/минимальные конечные значения в каждом столбце.
Атрибуты
----------
mins_ : np.ndarray
Минимальные конечные значения по столбцам.
maxs_ : np.ndarray
Максимальные конечные значения по столбцам.
'''
def fit(self, X, y=None):
# проверка и преобразование, если возможно:
X = check_array(X, force_all_finite=False)
# с использованием `where=np.isfinite(X)`, nan не повлияют на расчет мин/макс,
# и с использованием `clip` для преобразования будут сохранены nan.
self.mins_ = np.amin(X, axis=0, where=np.isfinite(X), initial=np.inf)
self.maxs_ = np.amax(X, axis=0, where=np.isfinite(X), initial=-np.inf)
return self
def transform(self, X):
X = check_array(X, force_all_finite=False)
return np.clip(X, self.mins_, self.maxs_)
Ответ или решение
Чтобы провести процедуру импутации данных с использованием SimpleImputer
из библиотеки sklearn
и эффективно интегрировать ваши собственные функции преобразования в пайплайн, вам необходимо создать кастомный трансформер. В этом ответе мы подробно разберем, как создать такой трансформер для обработки бесконечных значений и взаимодействия с каналами для логистической регрессии и XGBoost.
Создание кастомного трансформера
Кастомный трансформер позволит вам обрабатывать ваше множество данных, заменяя бесконечные значения (+inf
и -inf
) на максимальные и минимальные значения в тренировочных данных, соответственно.
import numpy as np
from sklearn.utils import check_array
from sklearn.base import TransformerMixin, BaseEstimator
class ReplaceInf(TransformerMixin, BaseEstimator):
'''Заменяет +-np.inf на максимальные и минимальные конечные значения в каждом столбце.'''
def fit(self, X, y=None):
# Проверка и преобразование данных
X = check_array(X, force_all_finite=False)
self.mins_ = np.amin(X, axis=0, where=np.isfinite(X), initial=np.inf)
self.maxs_ = np.amax(X, axis=0, where=np.isfinite(X), initial=-np.inf)
return self
def transform(self, X):
X = check_array(X, force_all_finite=False)
# Замена +inf и -inf на максимальные и минимальные значения соответственно
return np.clip(X, self.mins_, self.maxs_)
Интеграция кастомного трансформера в пайплайн
Теперь, когда у вас есть кастомный трансформер ReplaceInf
, вы можете интегрировать его в ваши пайплайны для логистической регрессии и XGBoost.
1. Логистическая регрессия
Ваш пайплайн для логистической регрессии будет включать преобразование данных, использование SimpleImputer
для замены NaN, замену бесконечных значений и стандартизацию данных.
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
logistic_pipeline = Pipeline(steps=[
('replace_inf', ReplaceInf()),
('imputer', SimpleImputer(strategy='most_frequent')),
('std_scaler', StandardScaler()),
('model', LogisticRegression())
])
2. XGBoost
Для XGBoost, вы можете создать простой пайплайн. Здесь мы можем использовать ваш кастомный трансформер для обработки только бесконечных значений.
from xgboost import XGBClassifier
xgboost_pipeline = Pipeline(steps=[
('replace_inf', ReplaceInf()),
('model', XGBClassifier())
])
Заключение
Использование кастомных трансформеров в scikit-learn
позволяет вам гибко управлять процессом обработки данных. С помощью вышеописанных примеров вы сможете адаптировать свои данные для различных моделей машинного обучения, таких как логистическая регрессия и XGBoost, избегая потери информации и обеспечивая качество ваших данных. Помните, что ключ к успешному моделированию — это не только выбор моделей, но и качество и целостность данных, которые вы используете.
Если у вас возникли дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться!