Как вы можете (и почему вы должны) создавать собственные трансформеры
Преобразователи Scikit Learn (не путать с преобразователями глубокого обучения) — это классы в пакете Scikit Learn, которые облегчают преобразования в заданных наборах данных.
Эти преобразователи могут выполнять различные операции, такие как нормализация и анализ основных компонентов. Однако в некоторых ситуациях могут потребоваться операции, которые невозможно выполнить с помощью предоставленных инструментов.
В таких случаях пользователи могут выбрать создание пользовательских функций, отвечающих их конкретным потребностям. Однако для приложений машинного обучения доступен гораздо лучший вариант: создание пользовательских преобразователей.
Здесь мы исследуем преимущества использования пользовательских преобразователей вместо пользовательских функций в Scikit-Learn и рассмотрим 2 различных способа их создания пользователями.
Почему пользовательские преобразователи (в отличие от функций)?
Преобразователи Scikit Learn созданы для того, чтобы быть эффективными. Они реализуют метод fit
, который извлекает необходимые параметры модели из обучающего набора, и метод transform
, который использует эти параметры модели для преобразования обучающего и тестового наборов.
Кроме того, пакет Scikit Learn предоставляет такие классы, как Pipeline и ColumnTransformer. Такие инструменты идут рука об руку с преобразователями и позволяют пользователям построить аккуратную и организованную процедуру разработки признаков.
Основная проблема с пользовательскими функциями заключается в том, что их нельзя включить во многие из вышеупомянутых инструментов Scikit Learn. В результате пользователи будут вынуждены впихивать эти функции в свои процедуры разработки функций, что будет неэффективно и чревато ошибками.
Гораздо лучшим вариантом было бы выполнение пользовательских операций с помощью пользовательских преобразователей. Это гарантирует, что их можно будет использовать совместно с другими преобразователями с такими инструментами, как конвейер.
Вам действительно нужен специальный трансформатор?
Следующий вопрос, который следует рассмотреть, заключается в том, нужен ли вам вообще специальный трансформатор. В пакете Scikit Learn может не быть нужного вам преобразователя, но это не обязательно означает, что вам придется приложить дополнительные усилия для создания собственного преобразователя.
Существует ряд пакетов Python с открытым исходным кодом, специализирующихся на разработке функций, совместимых со Scikit Learn, таких как пакеты feature_engine и category_encoders. Эти пакеты содержат собственный набор трансформаторов, который может удовлетворить ваши потребности.
Итак, прежде чем вы даже начнете думать о написании дополнительного кода, тщательно изучите все доступные вам инструменты. Небольшое копание может избавить вас от многих проблем в долгосрочной перспективе.
Создание собственного преобразователя в Scikit-Learn
Идея создания преобразователя может показаться пугающей, но она не требует особых усилий благодаря потрясающим возможностям пакетов Scikit Learn.
Для тех, кто хочет создать собственный трансформер, есть два основных варианта.
Вариант 1 — Использование FunctionTransformer
Модуль Scikit Learn предлагает класс FunctionTransformer, который, как следует из названия, преобразует функции в преобразователи. Более того, преобразование достигается простым однострочником!
FunctionTransformer можно использовать для преобразования ранее существовавших функций numpy или pandas в преобразователи.
Его также можно использовать для преобразования пользовательских функций в преобразователи. Если интересующая функция требует аргументов, их можно ввести в параметре kw_args
.
Например, если мы хотим создать преобразователь, который умножает все значения на заданное число, мы можем создать функцию, которая выполняет задачу, а затем преобразовать ее в преобразователь.
Как только функция преобразуется в преобразователь, она обладает методами fit
и transform
, которые упрощают использование с другими преобразователями.
При этом у FunctionTransformer есть заметное ограничение.
К сожалению, он не хранит параметры, используемые для подбора обучающих данных, что может быть проблемой для определенных операций, требующих сохранения параметров модели, таких как нормализация и одно горячее кодирование.
Поскольку может быть трудно концептуализировать этот недостаток, было бы полезно использовать пример. Мы можем выполнить однократное горячее кодирование набора данных, используя преобразователь, созданный путем преобразования функции pandas.get_dummies
.
Предположим, у нас есть следующие данные.
Мы можем преобразовать функцию get_dummies
в преобразователь, а затем использовать ее метод fit_transform
для кодирования данных.
Вывод показывает столбцы «Fruit_Apple» и «Fruit_Banana». Чтобы преобразователь был жизнеспособным, он должен был бы генерировать те же столбцы при обработке невидимых данных.
Однако так ли обстоит дело с нашим трансформатором? Как это будет работать со следующим набором данных, в котором есть невидимые данные?
Преобразователь теперь дает столбцы «Fruit_Blueberry» и «Fruit_Strawberry», которые не соответствуют выходным данным обучающего набора. Это связано с тем, что новые столбцы получены из данных тестирования, а не из данных обучения.
Кстати, я обсуждаю решение этой дилеммы в отдельной статье:
В целом, класс FunctionTransformer служит простым способом преобразования функций в преобразователи, но он не идеален для случаев, когда необходимо сохранить параметры из обучающих данных.
Вариант 2 — Создание Scikit Learn Transformer с нуля
Вторым вариантом будет создание трансформатора с нуля. Опять же, эта перспектива не так сложна, как может показаться.
Лучший способ проиллюстрировать подход — это пример.
Предположим, что мы создаем преобразователь, который решает проблему высокой кардинальности (т. е. слишком большого количества уникальных значений) путем преобразования категорий меньшинства в одну конкретную категорию.
Трансформер будет использовать следующие модули:
Во-первых, мы можем создать класс с именем ReplaceMinority
. Для этого нам нужно наследовать два импортированных базовых класса BaseEstimator
и TransformMixin
.
Затем нам нужно инициализировать атрибуты с помощью конструктора __init__
. Этот преобразователь будет иметь параметр threshold
, указывающий минимальную долю категории, не являющейся меньшинством, и параметр replace_with
, указывающий категорию, которой следует заменить меньшинства.
Далее мы можем создать метод fit
. Для этого приложения нам нужно ввести данные и записать все категории, не относящиеся к меньшинству, для каждого столбца в данном фрейме данных.
После этого мы можем создать метод transform
. Здесь мы заменяем все категории меньшинств аргументом в параметре replace_with
для каждого столбца и возвращаем результирующий набор данных.
Вот и все!
Когда мы собираем все вместе, вот как выглядит класс.
Это не заняло слишком много времени, не так ли?
Проверим трансформатор. Предположим, у нас есть набор данных о фруктах, в котором есть несколько меньшинств.
Мы можем уменьшить количество уникальных категорий, заменив меньшинства на «Другие фрукты» с помощью этого преобразователя.
Давайте создадим объект ReplaceMinority
, а затем воспользуемся методом fit_transform
, чтобы заменить меньшинства на «Другие фрукты».
Здесь трансформатор признал «Apple» и «Banana» не меньшинствами. Все остальные фрукты были заменены на «Другие фрукты». Это приводит к уменьшению количества уникальных значений.
Преобразователь теперь будет обрабатывать любые невидимые данные на основе параметров в обучающих данных. Мы можем продемонстрировать это, преобразовав данные тестового набора:
Только в тестовом наборе ни одна категория не является меньшинством, но преобразователь распознал «Яблоко» и «Банан» как единственные категории, не относящиеся к меньшинству, поэтому любая другая категория будет заменена на «Другое». Фрукты'.
Кроме того, мы можем встроить новый преобразователь в конвейеры Scikit Learn. Здесь мы можем связать его с объектом OneHotEncoder
.
В целом, создание преобразователя с нуля позволяет пользователям выполнять процессы для более конкретных вариантов использования. Это также позволяет пользователям преобразовывать набор для тестирования на основе параметров из набора для обучения. Однако этот подход требует больше времени и может быть подвержен ошибкам.
Заключение
В целом преобразователи Scikit Learn эффективны благодаря своей эффективности и совместимости с такими инструментами, как Pipeline и ColumnTransformer. Чтобы поддерживать эту эффективность, лучше всего использовать преобразователи, совместимые со Scikit Learn, для разработки функций.
Если ни один из преобразователей в Scikit Learn не справляется со своей задачей, изучите другие совместимые пакеты. Если необходимый преобразователь недоступен, у вас есть возможность преобразовать пользовательскую функцию в преобразователь или создать собственный преобразователь Scikit Learn с нуля.
Желаю вам удачи в ваших начинаниях в области науки о данных!