После введения Agile Data Science в нашей вводной статье здесь мы построили,

а) быстрая базовая модель на неделе 1, чтобы выяснить, достаточно ли предсказательной силы данных, чтобы тратить больше времени на улучшение

б) другая модель на неделе 2 с более чистыми функциями, чтобы посмотреть, улучшит ли она производительность.

На этой неделе мы выполним проектирование сложных функций с последующим сокращением функций, чтобы увидеть, могут ли комбинации существующих функций создать модель с большей прогностической силой.

Основываясь на очищенных выходных данных предыдущей недели, мы будем использовать библиотеку инструментов функций, чтобы расширить пространство функций с помощью встроенных преобразований. Затем, когда синтетические функции будут созданы, мы уменьшим пространство функций, удалив коллинеарные столбцы. Дополнительные способы сокращения пространства признаков будут предприняты с помощью важности признаков на основе случайного леса и рекурсивного исключения признаков. Наконец, мы запустим классификатор Random Forest с предыдущей недели, чтобы оценить производительность модели и увидеть, окупилась ли вся тяжелая работа.

Давайте начнем !

После загрузки данных визуализируйте фрейм данных, чтобы увидеть, все ли загружено правильно. Обратите внимание, что я использую очищенную версию данных за неделю 2 в качестве входных данных для записной книжки этой недели, в которой все еще есть непрерывные переменные, но все категориальные переменные были закодированы.

В рамках подготовки к разработке функций, которая значительно увеличит размер данных, я собираюсь сначала уменьшить размер данных, прежде чем преобразовывать их. По умолчанию pandas использует int64 и float64 для хранения переменных. Это дорого с точки зрения памяти. Итак, следующий блок кода (из Kaggle) реализует уменьшение размера данных за счет изменения типа сохраняемой переменной

Вышеупомянутая функция уменьшила объем памяти моего фрейма данных на 84%!

Хорошо, теперь наш набор данных готов к серьезному проектированию функций.

Автоматизированная разработка функций

Первый вопрос, который нужно задать, заключается в том, что такое фич-инжиниринг и должен ли он меня волновать? Разработка функций — это способ создания синтетических функций из существующих данных либо с использованием знаний в области бизнеса, либо с помощью некоторых умных преобразований (как это обычно происходит на соревнованиях Kaggle, когда знания в области бизнеса ограничены). Вы должны быть осторожны, потому что, если все сделано правильно, дополнительные функции включают больше знаний в набор данных и делают границы классов легко разделимыми в гиперпространстве.

В реальной жизни вы бы сидели рядом с бизнес-экспертом и советовались с ним о том, какие преобразования имеют смысл (например, логическая переменная, чтобы указать, попадают ли ежемесячные платежи клиента в определенный диапазон и т. д.). Этот процесс является одной из самых утомительных частей. (после очистки данных) и включает в себя множество догадок о том, какие синтетические функции имеют смысл.

Есть ли способ уменьшить количество догадок и частично уменьшить это утомление? Оказывается есть! Вы можете сделать это с помощью автоматизированной разработки функций, которая в основном пробует все возможные комбинации (которые вы можете указать заранее) для создания данных. Конечно, это не заменит встречи с бизнес-экспертами, но если у вас мало времени (это основная идея этой серии статей), попробуйте автоматическую разработку функций!

Инструменты функций

В этом уроке я собираюсь представить вам Featuretools, который представляет собой пакет, который вы импортируете в блокнот Jupyter для выполнения автоматизированного проектирования функций, описанного выше. Аналитика У Vidhya есть фантастическое руководство, знакомящее с инструментом. Вкратце, Feature Tools состоит из 3 частей:

а) Сущности — это представления кадра данных pandas. Вы можете иметь один фрейм данных (как в нашем примере) или указать несколько фреймов данных, которые будут объединены, и в этом случае он называется EntitySet.

б) Примитивы — это преобразования, которые применяются к данным. Это может быть так же просто, как логическое ИЛИ между двумя столбцами или что-то более сложное.

c) Глубокий синтез признаков (DFS). Это базовое ядро ​​того, как создаются синтетические признаки путем применения ранее указанных примитивов к объектам.

Теперь, когда мы знакомы с терминологией, давайте приступим к кодированию!

После установки функциональных инструментов pip вы можете импортировать их в свой блокнот Jupyter. Если вы получили сообщение об ошибке, ознакомьтесь с ответами stackoverflow и Github.

Теперь мы можем либо позволить feature_tools вывести типы переменных, либо нам нужно просмотреть каждый из столбцов функций в нашем фрейме данных и определить типы столбцов. Я собираюсь проиллюстрировать ручной подход.

Как вы решаете, какие переменные_типы? Все, что имеет 2 уникальных значения, будет логическим; 3 или более дискретных значения, но менее 10 будут категориальными. Что-то еще, скорее всего, числовое (например, должность).

Существуют и другие типы данных в более сложных условиях, но этот набор данных достаточно прост, чтобы его можно было охватить типами переменных Boolean, Categorical и Numeric. .

Я создал словарь для хранения типа переменной в соответствующих столбцах. Теперь мы собираемся сообщить ранее созданному EntitySet о функциях, которые мы собираемся использовать, и данных. Одно предостережение: убедитесь, что вы передаете только X, а не весь фрейм данных. Мы не хотим, чтобы целевой столбец был включен в Feature Engineering!

Следует отметить одну небольшую вещь: я создал столбец под названием «что-то». Это просто фиктивный столбец, который начинается от 0 до длины X. Но это синтаксически критично, чтобы заставить его работать. В ситуациях, когда объединяются более сложные наборы данных, индекс имеет решающее значение, но не здесь.

Если вы запустите EntitySet, определенный выше, вы увидите приведенный ниже вывод.

Обратите внимание, что есть 21 столбец из-за недавно созданного индексного столбца «что-то». Он говорит «Нет отношений», потому что нет других наборов данных, с которыми он был связан индексом.

Теперь, какие преобразования доступны? Мы можем увидеть, что доступно из коробки, используя вызов метода list_primitives().

Само количество и тип преобразований могут быть ошеломляющими. Чтобы проиллюстрировать мощь инструментов функций, я просто собираюсь использовать 2 примитива преобразования — логическое ИЛИ и И —и сгенерировать огромное количество синтетические черты.

Для тех из вас, кто не знаком с компьютерными науками, логические операции возвращают логический вывод (0 или 1) в зависимости от предопределенных правил. В нашем случае ИЛИ между 2 или более столбцами даст результат 1, если присутствует хотя бы 1 ненулевой столбец. Точно так же операция И между двумя или более столбцами даст на выходе 0, если хотя бы один из столбцов равен 0.

Мы передаем ранее созданный набор сущностей, es. Затем указываем, что нас интересует преобразование ‘X’ с использованием указанных примитивов. В нашем случае мы используем только trans_primitives только с 'ИЛИ' и 'И' до max_depth 2. Большее число для max_depth создаст более сложные комбинации существующих функций. Даже имея всего 2 примитива с max_depth равным 2, запуск приведенного выше кода привел к созданию почти 400 новых функций! Некоторые столбцы показаны ниже

Давайте выберем «И(ИЛИ(Иждивенцы, Безбумажное выставление счетов), ИЛИ(пол,Пожилой гражданин))», показанное выше, чтобы понять, как были созданы столбцы. Это пример синтетической функции с глубиной = 2. Внутри первой скобки есть 2 синтетические функции: первая — это логическое ИЛИ между столбцами Зависимые и Безбумажный биллинг. Результат этого теперь объединяется с логическим ИЛИ между столбцами gender и SeniorCitizen.

Откуда вы знаете, что преобразования привели к полезным столбцам? Конечно, многие из этих столбцов могут быть вообще неактуальны, и на самом деле нам нужен массовый раунд исключения функций, прежде чем мы сможем ввести их в модель машинного обучения.

Сокращение возможностей

Неверная идентификация столбца

Первый шаг — определить, какие из столбцов являются «плохими» и должны быть удалены. Заимствуя код из первой недели анализа, мы можем генерировать списки для хранения имен столбцов с нулевыми значениями, пробелами, постоянными значениями и повторяющимися столбцами.

Выполнение этого кода было относительно быстрым, несмотря на 400+ столбцов.

Вывод из приведенного выше показывает, что из 419 столбцов необходимо удалить около 102 столбцов. Если у вас есть время, вы можете более подробно проанализировать, что представляют собой эти столбцы, но из-за их большого количества я удаляю их все, используя слегка измененную версию кода из Week1.

В результате остается 317 столбцов. В следующих разделах мы рассмотрим сокращение количества функций на основе коллинеарности, важности функций и рекурсивного исключения функций.

Уменьшение признаков на основе коллинеарности

Основная идея состоит в том, чтобы найти корреляции между функциями и исключить те, которые выше определенного порога. Коллинеарные переменные — это те, которые сильно коррелируют друг с другом. Это может снизить способность модели к обучению, интерпретируемость модели и производительность обобщения на тестовом наборе. Какие критерии мы должны использовать, чтобы удалить их после выявления? Мы возьмем признаки, имеющие более 0,80 корреляции с другой переменной. Крис Албон и Уилл Кёрсен дали отличные уроки по этой теме здесь и здесь.

Приведенный выше код создает фрейм данных с именем «upper_df», который содержит верхнюю треугольную матрицу корреляции между парными отдельными функциями. Нижний треугольник этого фрейма данных заполнен NaN. Это гарантирует, что мы не будем дважды считать столбцы для исключения. Впоследствии мы можем проанализировать и идентифицировать столбцы с корреляцией более 0,80. Запуск этого кода дает нам список из 270 столбцов, которые нужно удалить.

Удивительный ! Мы устранили почти 2/3 синтетических столбцов без особых усилий. На этом этапе мы можем использовать модель машинного обучения или, если у вас есть время, попробовать некоторые контролируемые методы устранения признаков, представленные ниже:

Исключение функций на основе важности функций

Давайте используем базовый случайный лес для данных, чтобы создать список важности функций.

Пример вывода будет выглядеть следующим образом:

Как мы решаем, сколько столбцов оставить? Одна из возможностей состоит в том, чтобы увидеть, сколько столбцов требуется, чтобы получить совокупную важность, скажем, 95%, и исключить все, что ниже этого значения. Опять же, на этом этапе это может быть бизнес-решение, основанное на различных факторах, таких как стоимость обслуживания дополнительных столбцов и т. д.

Мы сохранили количество «важных» столбцов на основе тех, которые необходимы для совокупного достижения 95% важности функций.

На данном этапе у нас есть 32 функции. Если еще есть время, вы можете выполнить еще один уровень устранения признаков, называемый рекурсивным устранением признаков.

Рекурсивное удаление функций

Вместо того, чтобы кодировать этот алгоритм самостоятельно, мы воспользуемся пакетом Yellow Brick для выполнения RFE, а также отобразим результаты.

Что этот график говорит вам? По одной оси X у вас есть количество используемых функций, а ось Y дает оценку точности в процессе RFE. Заштрихованная область представляет изменчивость перекрестной проверки, одно стандартное отклонение выше и ниже средней оценки точности, нарисованной кривой.

Пунктирная линия в крайнем правом углу показывает количество функций, которые дали самую высокую среднюю точность.

В этом случае нам нужно 18 функций, чтобы получить наивысший балл. Но, как видно из приведенного выше графика, все, что выше 10 или около того, дает довольно схожие оценки. Бизнес-решение заключается в том, стоит ли повышать точность сохранения дополнительных функций или лучше использовать более простую модель.

Мы можем написать быстрый фрагмент кода, чтобы увидеть, какие функции были выбраны.

Обратите внимание, что «PhoneService», «TotalCharges», «TotalCharges_na» не были приняты. Похоже, что некоторые из синтетических функций были выбраны наряду с некоторыми из оригинальных функций. Теперь мы, наконец, готовы использовать модель машинного обучения!

Машинное обучение

Мы собираемся повторить тот же анализ, что и раньше, с базовой моделью случайного леса и построить матрицу путаницы + некоторое базовое резюме. Я просто покажу результаты, потому что код был представлен ранее.

По-прежнему существует значительное количество ложноположительных и ложноотрицательных результатов. Результаты очень похожи на предыдущую неделю анализа и не показывают улучшения, несмотря на введение дополнительных функций.

Обратите внимание, что я опробовал Feature Engineering только с двумя примитивами — ИЛИ и И. Я призываю читателей попробовать различные другие примитивы, чтобы увидеть, есть ли разница. В реальной жизни этап разработки функций будет одним из самых трудоемких и потребует обширных бизнес-вложений или понимания предметной области. Поскольку цель статьи состоит в том, чтобы проиллюстрировать методы разработки признаков, а не убедительно доказать, что разработка признаков всегда поможет повысить точность, я собираюсь перейти к другим методам в следующей статье — Настройка гиперпараметров.

Быть в курсе !

Следующую статью можно найти здесь