В настоящее время выбор модели для многих проектов машинного обучения превращается в автоматизацию, в то время как разработка функций по-прежнему в основном выполняется вручную. Важность этого процесса может быть важнее, чем выбор модели, а искусственно полученные признаки всегда имеют определенные ограничения. В этой статье автор расскажет нам, как использовать библиотеку Feature Tools Python для автоматизации разработки функций, и проект имеет открытый исходный код.
адрес проекта:docs.featuretools.com/
Кодовый адрес:GitHub.com/will KO, а окрашивание…
Машинное обучение все больше уходит от моделей, разработанных вручную, к инструментам, которые автоматически оптимизируются с помощью таких инструментов, как H20, TPOT и auto-sklearn. Эти библиотеки, наряду с такими методами, как случайный поиск (см. Случайный поиск для оптимизации гиперпараметров), призваны упростить процесс выбора модели и настройки машинного обучения путем поиска оптимальной модели, соответствующей набору данных, с минимальным вмешательством человека или без него. Однако разработка признаков, возможно, самый ценный аспект процесса машинного обучения, почти полностью выполняется вручную.
Инжиниринг признаков, также известный как построение признаков, представляет собой процесс создания новых признаков из существующих данных для обучения моделей машинного обучения. Этот шаг может быть более важным, чем фактическая используемая модель, потому что алгоритм машинного обучения может учиться только на данных, которые нам предоставлены, поэтому создание функции, соответствующей задаче, имеет решающее значение, см. отличную статью «Несколько полезных вещей», о которых нужно знать. Машинное обучение".
Как правило, проектирование признаков — это утомительный ручной процесс, основанный на знании предметной области, интуиции и манипулировании данными. Этот процесс может быть чрезвычайно утомительным, а полученные функции будут ограничены человеческим субъективизмом и временем. Автоматизация разработки признаков призвана помочь специалистам по данным, автоматически создавая признаки-кандидаты из набора данных и выбирая из них оптимальные признаки для обучения.
В этой статье мы рассмотрим пример автоматизации разработки функций с использованием библиотеки Feature Tools Python. Мы будем использовать пример набора данных, чтобы проиллюстрировать основные концепции (следите за примером, используя реальные данные позже). Полный код для этой статьи можно найти на Github.
Основные концепции разработки признаков
Разработка функций означает создание дополнительных функций из существующих данных, обычно распределенных по нескольким связанным таблицам. Разработка признаков включает в себя извлечение соответствующей информации из данных и сохранение ее в одной таблице, которая затем используется для обучения модели машинного обучения.
Построение функций — это трудоемкий процесс, так как создание каждой новой функции обычно занимает несколько шагов, особенно при использовании информации из нескольких таблиц. Мы можем разделить операции построения признаков на две категории: «преобразование» и «агрегирование». Вот несколько примеров, чтобы увидеть эти концепции в действии.
«Преобразование» работает с одной таблицей (в Python таблица — это кадр данных Pandas), создавая новые функции из одного или нескольких столбцов. Например, если у вас есть следующая таблица клиентов:
Мы можем построить новые функции, ища месяц в соединенном столбце или натуральный логарифм столбца дохода. Это операции преобразования, поскольку они используют информацию только из одной таблицы.
Агрегации, с другой стороны, реализуются по таблицам и используют связь «один ко многим» для группировки наблюдений и последующего вычисления статистики. Например, если бы у нас была другая таблица с информацией о кредитах клиентов, где у каждого клиента может быть несколько кредитов, мы могли бы рассчитать такие статистические данные, как средний, максимальный и минимальный кредиты для каждого клиента.
Этот процесс включает в себя группировку таблицы ссуд по клиентам и вычисление сводной статистики, а затем интеграцию результатов в данные о клиентах. Вот как мы это делаем на Python, используя библиотеку Pandas.
import pandas as pd
# Group loans by client id and calculate mean, max, min of loans
stats = loans.groupby('client_id')['loan_amount'].agg(['mean', 'max', 'min'])
stats.columns = ['mean_loan_amount', 'max_loan_amount', 'min_loan_amount']
# Merge with the clients dataframe
stats = clients.merge(stats, left_on = 'client_id', right_index=True, how = 'left')
stats.head(10)
Эти операции сами по себе не сложны, но при наличии сотен переменных, разбросанных по десяткам таблиц, процесс невозможно выполнить вручную. В идеале нам нужно решение, которое автоматизирует преобразования и агрегации по разным таблицам и объединяет результаты в одну таблицу. Хотя Pandas — отличный ресурс, все еще есть много манипуляций с данными, которые нам нужно выполнить вручную! Для получения дополнительной информации о разработке искусственных признаков ознакомьтесь с Руководством по науке о данных Python.
Инструмент функций
К счастью, Feature Tools — это именно то решение, которое мы искали. Эта библиотека Python с открытым исходным кодом может автоматически создавать функции из набора связанных таблиц. Инструмент функций основан на методе под названием «Глубокий синтез функций» (см. «Глубокий синтез функций: на пути к автоматизации усилий по науке о данных»), который звучит более грандиозно, чем сам по себе (название происходит от объединения нескольких функций, а не из-за использования методов глубокого обучения!).
Глубокий синтез признаков накладывает несколько операций преобразования и агрегирования, известных как примитивы признаков в тезаурусе инструмента признаков, для создания новых признаков из данных, распределенных по нескольким таблицам. Как и большинство методов машинного обучения, это сложный метод, основанный на простых концепциях. Изучая по одному строительному блоку за раз, мы можем получить хорошее представление об этом мощном методе.
Во-первых, давайте посмотрим на образцы данных. Мы видели некоторые из наборов данных выше, и полный набор таблиц выглядит так:
клиенты: Основная информация о клиентах кредитного союза. Каждому клиенту соответствует только одна строка во фрейме данных.
кредиты: кредиты, предлагаемые пользователям. Каждый кредит соответствует только одной строке во фрейме данных, но у клиента может быть несколько кредитов.
платежи: платежи для погашения кредита. Для каждого платежа есть только одна строка, но для одного кредита может быть несколько платежей.
Если у нас есть задача машинного обучения, например прогнозирование того, будет ли клиент погашать кредит в будущем, мы хотим объединить всю информацию о клиенте в одну таблицу. Эти таблицы связаны (через переменные client_id и кредит_id), и мы можем вручную реализовать этот процесс с помощью ряда преобразований и агрегаций. Однако вскоре мы сможем автоматизировать этот процесс с помощью функциональных инструментов.
Сущности и наборы сущностей
Первые два понятия инструмента объектов — это «сущности» и «наборы сущностей». Сущность — это таблица (или DataFrame в Pandas). Набор сущностей — это набор таблиц и связей между ними. Думайте о наборе сущностей как об еще одной структуре данных Python со своими собственными методами и свойствами.
Мы можем создать пустой набор сущностей в инструменте объектов, выполнив следующие действия:
import featuretools as ft
# Create new entityset
es = ft.EntitySet(id = 'clients')
Теперь нам нужно интегрировать две сущности. Каждый объект должен иметь индекс, который представляет собой столбец, содержащий все уникальные элементы. То есть каждое значение в индексе может появиться в таблице только один раз. Индекс во фрейме данных клиентов — client_id, потому что для каждого клиента во фрейме данных есть только одна строка. Мы добавляем сущность с индексом в набор сущностей, используя следующий синтаксис:
# Create an entity from the client dataframe
# This dataframe already has an index and a time index
es = es.entity_from_dataframe(entity_id = 'clients', dataframe = clients,
index = 'client_id', time_index = 'joined')
Фрейм данных займов имеет еще один уникальный индекс, credit_id, и синтаксис для его добавления в набор сущностей такой же, как и у клиентов. Однако фрейм данных платежей не имеет уникального индекса. Когда мы добавляем фрейм данных о платежах в набор сущностей, нам нужно передать параметр make_index = True и указать имя индекса. Кроме того, хотя инструмент функций может автоматически определять тип данных каждого столбца в объекте, мы можем переопределить его, передав словарь типов данных столбца в параметр variable_types.
# Create an entity from the payments dataframe
# This does not yet have a unique index
es = es.entity_from_dataframe(entity_id = 'payments',
dataframe = payments,
variable_types = {'missed': ft.variable_types.Categorical},
make_index = True,
index = 'payment_id',
time_index = 'payment_date')
Для этого фрейма данных, хотя Missed является целым числом, это не числовая переменная, поскольку она может принимать только 2 дискретных значения, поэтому в инструменте Feature обрабатывайте ее как категориальную переменную. После добавления этого фрейма данных в набор сущностей мы исследуем весь набор сущностей:
Тип данных столбца был правильно определен в соответствии с указанной нами схемой коррекции. Далее нам нужно указать, как связаны таблицы в наборе сущностей.
ассоциация таблиц
Лучший способ представить «отношения» между двумя таблицами — это аналогия с отношениями между родительской и дочерней таблицами. Это ассоциация «один ко многим»: у каждого отца может быть несколько сыновей. Для таблиц каждый родитель соответствует строке в родительской таблице, но в дочерней таблице может быть несколько строк, которые соответствуют нескольким дочерним элементам в одной и той же родительской таблице.
Например, в нашем наборе данных фрейм данных клиентов является родительской таблицей фрейма данных кредитов. Каждый клиент соответствует только одной строке в таблице клиентов, но может соответствовать нескольким строкам в таблице кредитов. Точно так же таблица займов является родительской таблицей таблицы платежей, поскольку у каждого займа может быть несколько платежей. Отец связан с сыном через общую переменную. Когда мы выполняем операцию агрегирования, мы группируем дочернюю таблицу в соответствии с родительской переменной и вычисляем статистику для сыновей каждого отца.
Чтобы формализовать правила ассоциации в инструменте объектов, нам нужно только указать переменные, которые соединяют две таблицы. Таблица клиентов и таблица кредитов связаны переменной client_id, а таблица кредитов и таблица платежей связаны переменной кредит_ид. Синтаксис для создания ассоциации и добавления ее в набор сущностей следующий:
# Relationship between clients and previous loans
r_client_previous = ft.Relationship(es['clients']['client_id'],
es['loans']['client_id'])
# Add the relationship to the entity set
es = es.add_relationship(r_client_previous)
# Relationship between previous loans and previous payments
r_payments = ft.Relationship(es['loans']['loan_id'],
es['payments']['loan_id'])
# Add the relationship to the entity set
es = es.add_relationship(r_payments)
es
Набор сущностей теперь содержит три сущности (таблицы) и правила ассоциации, которые объединяют таблицы. После добавления сущностей и формализации правил ассоциации набор сущностей завершен и готов для создания из него новых функций.
примитивы функций
Прежде чем мы углубимся в глубокий синтез признаков, нам нужно понять концепцию примитивов признаков. Мы на самом деле уже знали, что это такое, мы просто называли их по-разному! Это просто операции, которые мы используем для создания новых функций:
Агрегация: операция, выполняемая в соответствии с ассоциацией между родителем и дочерним элементом (один ко многим), то есть группировка по отцу и вычисление статистики сына. Примером может служить группировка таблицы займов по client_id и поиск максимальной суммы займа на одного клиента.
Преобразование: операция, выполняемая над одним или несколькими столбцами таблицы. Примером может служить разница между двумя столбцами в таблице или получение абсолютного значения столбца.
Используйте эти примитивы по отдельности или в стопках в Инструменте объектов для создания новых объектов. Ниже приведен список некоторых примитивов функций в инструменте Feature, которые также можно настроить.
Эти примитивы можно использовать по отдельности или в комбинации для создания новых функций. Чтобы создать новые функции с использованием определенных примитивов, мы используем функцию ft.dfs (обозначает глубокий синтез функций). Мы передаем entityset и target_entity, то есть таблицу, в которую мы хотим добавить функции, выбранные параметры trans_primitives (преобразование) и agg_primitives (агрегирование).
public class MyActivity extends AppCompatActivity {
@Override //override the function
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
OkhttpManager.getInstance().setTrustrCertificates(getAssets().open("mycer.cer");
OkHttpClient mOkhttpClient= OkhttpManager.getInstance().build();
} catch (IOException e) {
e.printStackTrace();
}
}
Возвращается фрейм данных, содержащий новые характеристики каждого клиента (поскольку мы определяем клиентов как target_entity). Допустим, у нас есть месяц, в который присоединяется каждый клиент, это примитив функции для операции преобразования:
У нас также есть примитивы для многих агрегатных операций, таких как средний общий платеж на одного клиента:
Хотя мы указали только несколько примитивов объектов, инструмент объектов может создавать новые объекты, комбинируя и складывая эти примитивы.
Полный фрейм данных содержит 793 столбца новых функций!
Глубокий синтез признаков
Теперь у нас есть все необходимое для понимания глубокого синтеза признаков (dfs). На самом деле мы уже выполнили dfs в предыдущем вызове функции! Глубокая функция — это всего лишь одна функция, созданная путем объединения нескольких примитивов, а dfs — это просто название процесса, с помощью которого создаются эти функции. Глубина глубокого объекта — это количество примитивов, необходимых для построения этого объекта.
Например, столбец MEAN(payments.payment_amount) является функцией глубины 1, поскольку он построен с использованием одной операции агрегирования. ПОСЛЕДНИЙ(кредиты(СРЕДНЕЕ(СРЕДНИЕ(платежи.сумма_платежей)) — это функция глубины 2, построенная из двух наложенных операций агрегирования: столбец ПОСЛЕДНИЙ (ближайший) поверх столбца СРЕДНИЙ. Он представляет самую последнюю среднюю выплату кредита для каждого клиента.
Мы можем складывать функции любой глубины, но на практике я никогда не использую больше двух функций. Кроме того, эти особенности трудно объяснить, но я призываю всех, кто заинтересован в «углублении».
Нам не нужно вручную указывать примитивы объектов, но мы можем позволить инструменту объектов автоматически выбирать объекты для нас. Для этого мы используем тот же вызов функции ft.dfs, но не передаем никаких примитивов функций.
# Perform deep feature synthesis without specifying primitives
features, feature_names = ft.dfs(entityset=es, target_entity='clients',
max_depth = 2)
features.head()
Инструмент функций создает множество функций, которые мы можем использовать. Хотя этот процесс автоматически создает новые функции, он не заменит специалистов по данным, потому что нам все еще нужно выяснить, что делать с этими функциями. Например, если наша цель состоит в том, чтобы предсказать, погасит ли клиент кредит, мы можем искать функции, которые наиболее важны для конкретного результата. Кроме того, если у нас есть знание предметной области, мы можем использовать это знание для выбора определенных примитивов признаков или признаков-кандидатов для затравочного глубокого синтеза признаков.
Следующий шаг
Автоматизация разработки признаков решает одну проблему, но приносит другую: слишком много функций. Хотя трудно сказать, какие функции важны перед подгонкой модели, вполне вероятно, что не все из них имеют отношение к задаче модели, которую мы хотим обучить. Кроме того, наличие слишком большого количества функций (см. «Нерелевантные функции и проблема выбора подмножества») может привести к снижению производительности модели, поскольку менее полезные функции подавляют более важные.
Проблема слишком большого количества функций известна как проклятие размерности. По мере увеличения количества признаков (рост размерности данных) модели становится все труднее изучать сопоставление между признаками и целями. На самом деле количество данных, необходимых для хорошей работы модели, экспоненциально связано с количеством функций.
Проклятие размерности противоположно уменьшению размерности признаков (также называемому выбором признаков, процессу удаления нерелевантных признаков). Это может принимать разные формы: анализ основных компонентов (PCA), SelectKBest, использование важности функций в модели или использование глубоких нейронных сетей для автоматического кодирования. Однако уменьшение размерности признаков — это отдельная тема для другой статьи. На данный момент мы знаем, что можем использовать инструмент признаков для построения большого количества признаков из многих таблиц с минимальными усилиями!
в заключении
Как и во многих других областях машинного обучения, автоматизация разработки функций с помощью инструментов функций — это сложная концепция, основанная на простых идеях. Используя концепции наборов сущностей, сущностей и ассоциаций, инструменты функций могут выполнять операции глубокого синтеза функций для создания новых функций. Глубокий синтез функций может последовательно складывать примитивы функций: «агрегаты», которые функционируют в ассоциациях «один ко многим» между несколькими таблицами, и «преобразования», которые применяются к одному или нескольким столбцам в одной таблице для создания новых из нескольких таблиц. особенность функция.
В следующем посте я опишу, как использовать эту технику в реальной проблеме, а именно в соревновании риска дефолта по жилищному кредиту на Kaggle (woohoo.kareformed.com/from/home-fire…). Следите за этим постом, а пока прочитайте эту заметку, чтобы начать конкурс (к data science.com/machine-ahhh…)! Надеюсь, вы, ребята, сможете использовать автоматизацию разработки признаков в качестве вспомогательного средства в своей работе по науке о данных. Наши модели так же хороши, как и данные, которые мы предоставляем, а автоматизация разработки признаков может сделать процесс создания признаков более эффективным.
Дополнительные сведения о функциональных инструментах, в том числе о расширенном использовании, см. в онлайн-документации (docs.featuretools.com/). Чтобы понять, как фич-инструменты используются на практике, прочитайте работу Feature Labs, разработчика библиотеки с открытым исходным кодом (www.featurelabs.com/).