Одним из самых важных навыков любого специалиста по данным или ML инженера является умение извлекать информативные признаки из исходного набора данных. Этот процесс называемый feature engineering (инженерия признаков), — одна из самых полезных техник при построении моделей машинного обучения.
Работа с данными требует значительных инженерных усилий. Хотя современные библиотеки вроде scikit-learn помогают нам с большей частью рутинных операций, по-прежнему критически важно понимать структуру данных и адаптировать её под задачу, которую вы решаете.
Создание новых, более качественных признаков позволяет модели лучше улавливать зависимости, отражающие особенности предметной области и влияющие на результаты факторы.
Разумеется, feature engineering — это времязатратный, креативный и нередко утомительный процесс, требующий экспериментов и опыта.
Недавно я наткнулся на интересный инструмент — Upgini. Следуя тренду на использование Large Language Models (LLM), Upgini применяет GPT от OpenAI, чтобы автоматизировать процесс feature engineering для ваших данных.
Подробнее о python библиотеке Upgini можно почитать на GitHub странице проекта.
👉 GitHub - upgini/upgini: Data search library for Machine Learning
Для примера возьмём известный датасет Amazon Fine Food Reviews (публичная лицензия CC0).
Он содержит около 500 000 отзывов на продукты питания с Amazon. Он охватывает период более 10 лет и включает примерно 500 000 отзывов, опубликованных до октября 2012 года.
Каждый отзыв содержит:
информацию о товаре и пользователе,
оценку (рейтинг),
текст отзыва в свободной форме.
Также в датасет входят отзывы из других категорий Amazon, не только “Fine Food”.
Используя эти данные, мы попробуем решить задачу предсказания релевантности отзыва, которую часто решают Ecom площадки при модерации отзывов на товары.
Для решения этой задачи мы могли бы потратить несколько дней, а то и недель на генерацию фичей на текстах, но мы покажем как это сделать за пару часов в Upgini.
Начнём с установки Upgini:
pip install upgini
Загрузим датасет и приведём его к удобному виду:
import pandas as pd
import numpy as np
# Чтение данных
df_full = pd.read_csv("/content/Reviews.csv")
# Преобразуем столбец времени
df_full['Time'] = pd.to_datetime(df_full['Time'], unit='s')
# Упорядочим колонки
df_full = df_full[['Time', 'ProfileName', 'Summary', 'Text',
'HelpfulnessNumerator', 'HelpfulnessDenominator', 'Score']]
Оставим только отзывы, опубликованные после 2011-01-01 и имеющие более 10 оценок полезности:
df_full = df_full[(df_full['HelpfulnessDenominator'] > 10) &
(df_full['Time'] >= '2011-01-01')]
Создадим бинарное целевое событие - метку релевантности отзыва:
df_full.loc[:, 'Helpful'] = np.where(
df_full.loc[:, 'HelpfulnessNumerator'] /
df_full.loc[:, 'HelpfulnessDenominator'] > 0.5, 1, 0)
Теперь объединим текст заголовка отзыва и содержания отзыва в один столбец:
df_full["combined"] = (
"Title: " + df_full["Summary"].str.strip() +
" ; Content: " + df_full["Text"].str.strip())
df_full.drop(['Summary', 'Text', 'HelpfulnessNumerator', 'HelpfulnessDenominator'], axis=1, inplace=True)
df_full.drop_duplicates(subset=['combined'], inplace=True)
df_full.reset_index(drop=True, inplace=True)
Теперь можно начать генерацию новых признаков. В Upgini это делается с помощью объекта FeaturesEnricher
. Базовая функция этого метода - находить новые полезные фичи.
Он принимает на вход SearchKey — перечень колонок в вашем датафрейме, по которому будет выполняться поиск новых фичей (например, дата, email, IP, телефон и т.д.). В нашем датафрейме из всех типов поддерживаемых ключей есть только Дата. Укажем ее.
from upgini import FeaturesEnricher, SearchKey
enricher = FeaturesEnricher(search_keys={'Time': SearchKey.DATE})
enricher.fit(df_full[['Time', 'ProfileName', 'Score', 'combined']], df_full['Helpful'])
После выполнения поиска Upgini вернет список найденных признаков — потенциально полезных фичей для дальнейшего обогащения ими ваших выборок.
Каждому признаку соответствует значение SHAP, показывающее его вклад в качество модели, а также источник данных.
Видно что значимым является только поле Score из исходного датафрейма, которое означает оценку выставленную пользователем (от 1 до 5).
Кроме того, библиотека оценивает качество модели на отобранных фичах с доверительным интервалом.
В документации указано, что FeaturesEnricher
поддерживает параметр generate_features
, который позволяет создавать признаки на основе текстовых столбцов — как в нашем случае combined
и ProfileName
.
Запустим процесс генерации:
enricher = FeaturesEnricher(
search_keys={'Time': SearchKey.DATE},
generate_features=['combined', 'ProfileName']
)
enricher.fit(df_full[['Time', 'ProfileName', 'Score', 'combined']], df_full['Helpful'])
Результат — 9 новых значимых признака. Для каждого из них доступен отчёт с SHAP-оценкой, источником и охватом данных.
Среди значимых фичей - две являются результатом Автогенерации поверх GPT — Кластер на текстовых эмбеддингах GPT и Расстояние до центроида на нормализованных векторах:
Интересно, что эти фичи поверх эмбеддингов на GPT дали вклад 20% в суммарный SHAP. Эту информацию также видно в отчете.
Благодаря добавленным признакам качество модели выросло с 0.522 Gini только на поле Score до 0.656 Gini. Итого поиск и ненерация новых фичей в Upgini позволили увеличить метрику Gini на 25.7%.
Теперь попробуем обогатить нашу выборку найденными фичами для дальнейшего моделирования уже локально:
df_full_enrich = enricher.transform(df_full)
При запуске Upgini вернул ошибку:
Эта ошибка означает, что обогащение данным типом фичей невозможно без регистрации. Окей, регистрация в Upgini бесплатная. Идем на сайт, нажимаем Войти (Sign In). Система запрашивает мой email:
После ввода email-а и нажатия Login, на почту которую я ввел пришла уникальная ссылка для авторизации.
Нажимаем Sign-In и получаем доступ в Личный Кабинет с персональным API KEY.
Чтобы воспользоваться этим ключом, нужно заново запустить Поиск данных, уже авторизованный:
enricher = FeaturesEnricher(
search_keys={'Time': SearchKey.DATE},
generate_features=['combined', 'ProfileName'],
api_key="УКАЖИТЕ_СВОЙ_КЛЮЧ"
)
enricher.fit(df_full[['Time', 'ProfileName', 'Score', 'combined']], df_full['Helpful'])
Результат вернулся из кэша моментально, поскольку этот поиск уже запускался мной ранее, правда без авторизации.
Снова запускаем обогащение:
df_full_enrich = enricher.transform(df_full)
Upgini обогатил нашу выборку новыми фичами, полученными по ключу Дата, и фичами полученными с помощью генерации, включая генерацию с использованием GPT.
Теперь используя этот датафрейм мы можем продолжить построение локально используя найденные полезные фичи. Всю генерацию и обогащение мы осуществили бесплатно.
Upgini — новая Python библиотека с открытым кодом, которая позволяет экономить тонну времени специалистам по данным и ML инженерам. Он упрощает рутину генерации признаков, находит полезные внешние данные, а использование GPT-моделей делает возможным автоматическое создание информативных признаков из текстов. Все это в совокупности помогает значимо улучшить качество вашей модели и продемонстрировать лучший результат либо в каком-нибудь соревновании, либо на работе.
Я продолжаю исследовать возможности пакета, но уже сейчас могу сказать: GPT-генерация признаков — это действительно крутая штука, которая помогает увеличить точность моделей.
Попробуйте на своих данных и поделитесь результатами!