Изучите основные методы и инструменты для эффективной разработки функций в Python

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

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

Что вы узнаете из этой статьи:

  • Что такое разработка функций?
  • Как работать с отсутствующими значениями.
  • Как обращаться с категориальными признаками.
  • Как работать с числовыми / непрерывными функциями.
  • Создание полиномиальных признаков.
  • Нормализация признаков.
  • Работа с функциями даты / времени
  • Работа с широтой и долготой

Найдите Блокнот Jupyter для этого поста здесь.

Что такое разработка функций?

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

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

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

… Некоторые проекты машинного обучения успешны, а некоторые - нет. В чем разница? Несомненно, наиболее важным фактором являются используемые функции. - Педро Домингос, Несколько полезных фактов о машинном обучении.

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

Подготовка наших наборов данных

Теперь, когда мы понимаем, что такое разработка функций, перейдем непосредственно к практическому аспекту этой статьи. В этой статье мы будем использовать два набора данных. Первый - это набор данных прогнозирования по умолчанию, размещенный на Zindi by Data Science Nigeria, а второй - также размещенный на Zindi - это набор данных Sendy Logistics от Sendy.

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

Во-первых, давайте импортируем некоторые библиотеки и наборы данных:

  • Мы импортируем Pandas, NumPy, Seaborn и Matplotlib для базового манипулирования данными и визуализации.
  • Мы заглушаем ненужные предупреждения с помощью модуля filterwarnings и, наконец, импортируем наборы данных.

Мы видим, что в наборе данных о ссуде есть три таблицы. Эти таблицы связаны друг с другом первичным ключом (customerid).

Давайте взглянем на наш набор данных и почувствуем, какие записи присутствуют.

loan_demographics.sample(3).T

loan_perf.sample(3).T

loan_prev.sample(3).T

sendy_data.sample(3).T

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

Помня об этом, давайте займемся разработкой функций.

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

Присоединяйтесь к более чем 14000 ваших коллег по машинному обучению и исследователей данных. Подпишитесь на главную рассылку новостей по глубокому обучению.

Как работать с отсутствующими значениями

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

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

  • Режим заполнения. Заполните отсутствующие значения самым популярным / частым / модальным классом.
  • Временное заполнение (прямое или обратное заполнение). Заполните отсутствующие значения предыдущим значением (сверху вниз) или последующим значением (снизу вверх).
  • Кодирование и заполнение. В этом методе вы можете кодировать значения, используя различные стратегии, а затем заполнять их средним значением, режимом или медианой.

В наборе демографических данных ссуды у нас есть три категориальных признака (bank_branch_clients, employment_status_clients, level_of_education_clients) с пропущенными значениями. Давайте попробуем заполнить режим с помощью функции employment_status_clients:

#check for missing values
loan_demographics.isna().sum()

loan_demographics['employment_status_clients'].value_counts()

Из вывода value_counts выше мы можем видеть классы, присутствующие в функции employment_status_clients, и их соответствующие частоты. Мы видим, что класс Permanent более популярен. Мы можем использовать это значение для заполнения всех отсутствующих значений в функции employment_status_clients, как показано ниже.

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

  • Заполнение средним значением, режимом или медианой.
  • Временное пломбирование (обратное или прямое).
  • Используйте модели машинного обучения. Обучите модель машинного обучения, чтобы узнать наиболее подходящие значения заполнения.

Чтобы продемонстрировать процесс заполнения числовых значений, мы будем использовать набор данных Sendy logistics , поскольку он имеет две числовые характеристики (Temperature и Precipitation в миллиметрах), которые содержат пропущенные значения.

  • Сначала мы вычисляем значение выбранного метода заполнения, затем используем функцию Pandas fillna для автоматического поиска и замены отсутствующих значений на вычисленное значение.

Примечание. Вы должны использовать только один метод (среднее значение, режим или медианное заполнение) в любой момент времени. Кроме того, вычисляемый режим в Pandas всегда возвращает модальное значение и его индекс. Это означает, что мы можем получить более одного возвращаемого модального значения. Мы выбираем первый, индексируя его [0].

Используйте моделирование для заполнения отсутствующих значений

Чтобы продемонстрировать заливку с помощью моделирования, мы воспользуемся функцией Precipitation in millimeters) в наборе данных Sendy. Но сначала нам нужно выбрать функции, которые с ним коррелируют. То есть функции, которые могут помочь предсказать Precipitation in millimeters.

В этом нам поможет график тепловой карты Seaborn. Мы продемонстрируем это ниже.

#Plot heatmap of feature correlation
plt.figure(figsize = (15,10))
sns.heatmap(sendy_data.corr())

Из приведенного выше графика тепловой карты мы видим, что большинство функций на самом деле не коррелируют с Precipitation in millimeters. Мы можем использовать последние три функции (Destination Lat, Destination Long и Time from Pickup to Arrival), поскольку они показывают небольшую корреляцию. Продемонстрируем это ниже:

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

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

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

  • Во-первых, мы явно требуем и активируем функцию IterativeImputer. Это необходимо сделать, прежде чем вы сможете его использовать.
  • Затем мы импортируем модель RandomForest и создаем объект импорта, передавая модель RandomForest.
  • Затем мы указываем список коррелированных функций в виде списка Python.
  • Наконец, мы подбираем преобразование и конвертируем результат в фреймворк Pandas.

Как обрабатывать категориальные особенности

Категориальные характеристики - это функции, которые могут принимать значения из ограниченного набора. Например, относительная привлекательность места / предмета (горячее, горячее, самое горячее) или рейтинг приложения (1,2,3,4,5). Что касается нашего набора данных, такие функции, как level_of_education_clients в наборе данных loan_demographics, являются категориальной функцией, содержащей такие классы, как Secondary, Graduate, Post-Graduate и Primary.

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

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

Типы категориальных признаков

  1. Порядковые категориальные признаки. Порядковые категориальные признаки имеют естественную упорядоченную категорию. То есть один класс выше другого. Например, звездные рейтинги (1,2,3,4,5), где класс 5 является более высоким рейтингом, чем 4/3/2/1.
  2. Не порядковые категориальные элементы. Этот тип элементов не имеет определенного порядка. То есть ни один класс не выше другого. Одним из примеров может быть тип еды (рис, макароны, макароны, спагетти). Рис каким-то странным образом не превосходит макароны / макароны / спагетти, верно?

Какую схему кодирования использовать и когда ее использовать

Ручное кодирование порядкового элемента. Если классы в категориальном элементе являются порядковыми, а уникальные значения невелики, вы можете вручную назначить метки, которые имеют некоторую форму упорядочения. Давайте продемонстрируем это ниже, используя функцию level_of_education_clients в наборе данных loan demographic . Эта функция имеет некоторую форму ординальности, поскольку класс Post-Graduate выше, чем классы _34 _ / _ 35 _ / _ 36_.

loan_demographics['level_of_education_clients'].unique()

  • Сначала мы создаем словарь, отображающий классы на свои метки. Здесь высшему классу (Post-Graduate) присваивается наивысший номер.
  • Затем мы используем функцию Pandas map, чтобы найти и заменить каждый класс соответствующей меткой.

Чтобы выполнить автоматическое кодирование, мы будем использовать эффективную библиотеку под названием категориальные_энкодеры. Эта библиотека предлагает многочисленные схемы кодирования из коробки и имеет непосредственную поддержку фреймов данных Pandas.

Чтобы установить библиотеку, вы можете использовать pip следующим образом:

pip install category_encoders
          or
conda install -c conda-forge category_encoders

Кодировка метки. Если у вас есть большое количество классов в категориальной функции, вы можете использовать кодировку метки. Кодирование метки присваивает уникальную метку (целое число) определенному классу. Мы демонстрируем это с помощью двух функций (bank_name_clients и bank_branch_clients) с большим количеством уникальных классов, 18 и 45 соответственно. .

Функция OrdinalEncoder из библиотеки категориальных_энкодеров может использоваться для маркировки кодирования, как показано ниже:

  • Сначала мы сохраняем категориальные столбцы, которые хотим закодировать, в список.
  • Затем мы создаем объект кодировщика.
  • Наконец, мы подгоняем-трансформируем набор данных.

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

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

  • Во-первых, мы указываем функции, которые хотим хэшировать.
  • Затем мы создаем объект хеш-кодировщика и указываем длину хеш-вектора, который будет использоваться.
  • Наконец, мы подгоняем-трансформируем набор данных.

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

Чтобы продемонстрировать целевую кодировку, мы будем использовать набор данных об эффективности ссуды (loan_perf). Целью, представляющей интерес в этом наборе данных, является функция good_bad_flag, и задача состоит в том, чтобы предсказать, вернет ли клиент ссуду или нет. Признак good_bad_flag представлен как категориальный признак, поэтому сначала мы преобразуем его в числовую форму, как показано ниже:

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

  • Сначала мы создаем целевой объект кодировщика и передаем столбцы, которые хотим кодировать.
  • Затем мы подгоняем-трансформируем набор данных, передавая как функции, так и интересующую цель.

Существует множество других схем кодирования (двоичные кодировщики, кодировщики подсчета, кодировщики с исключением одного, кодировщики CatBoost и т. Д.), Которые вы можете опробовать в своих случаях использования. Хорошее место, чтобы узнать о них - это официальная документация библиотеки category_encoder.

Как работать с числовыми / непрерывными функциями

Числовые / непрерывные объекты - это наиболее распространенный тип объектов в наборах данных. Они могут представлять значения из заданного диапазона. Например, цена продукта, температура в месте или координаты на карте.

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

Преобразование журнала. Преобразование журнала помогает центрировать (или, с точки зрения статистики, обычно распределять) данные. Эта стратегия может помочь большинству моделей машинного обучения работать лучше.

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

Преобразования журналов в основном выполняются на наклонных элементах. Элементы могут быть смещены вправо или влево. Асимметрию легко проверить с помощью визуализации. Чтобы продемонстрировать преобразование журнала, мы будем использовать функцию Distance (KM) в наборе данных Sendy, поскольку эта функция наклонена вправо.

sns.distplot(sendy_data['Distance (KM)'])
plt.title("Histogram of Distance (KM)")
plt.show()

Мы регистрируем преобразование, логарифмируя все экземпляры. Мы используем эффективную реализацию NumPy, которая добавляет 1 к каждому значению перед логарифмом. Это помогает нам избежать нулевого значения в логе.

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

  1. Процент истек: Процент истек - это функция, которую мы создали на основе разницы между totaldue и loanamount.
loan_prev['interest_elapsed'] = loan_prev['totaldue'] - loan_prev['loanamount']

2. Количество ссуд. Мы можем подсчитать общее количество ссуд, полученных клиентом, путем агрегирования номеров ссуд.

3. Скорость: из физики мы знаем, что скорость - это расстояние в единицу времени - поэтому , мы можем создать новую функцию (Speed) в наборе данных Sendy из функций Distance (KM) и Time from Pickup to Arrival.

Полиномиальные (перекрестные) функции

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

Мы можем создавать полиномиальные / перекрестные объекты вручную, просто складывая, умножая или разделяя объекты друг с другом. В этой статье мы собираемся использовать модуль Polynomial Feature, присутствующий в библиотеке sklearn.

Мы создадим полиномиальные функции из функций loannumber, totaldue и termdays в предыдущем наборе данных взаймы, как показано ниже.

  • Сначала мы импортируем функцию PolynomialFeatures из sklearn
  • Далее мы создаем из него объект. Здесь мы можем указать степень взаимодействия (по умолчанию 2).
  • Затем мы указываем функции, которые хотим пересечь (по умолчанию все).
  • Далее выполняем переход методом fit-transform.
  • PolynomialFeatures возвращает объект массива NumPy, поэтому мы конвертируем его в фрейм данных Pandas, а затем объединяем с исходным набором данных (loanprev).

Нормализация функций

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

Некоторые функции нормализации, доступные в sklearn, включают:

  1. StandardScaler: Стандартизируйте функции путем вычитания среднего и масштабирования до единичной дисперсии.
  2. RobustScaler: масштабируйте функции, используя статистику, устойчивую к выбросам.
  3. MinMaxScaler: нормализовать функции, масштабируя каждую функцию до указанного диапазона (диапазон зависит от вас!).

Примечание. Ни в коем случае нельзя подгонять масштабатор к набору для тестирования / проверки. Это может вызвать утечки. Кроме того, скейлеры в sklearn не устойчивы к пропущенным значениям, что означает, что вы всегда должны заполнять отсутствующие значения перед попыткой использования скейлеров.

Работа с функциями даты

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

Истекшее время. Истекшее время - это разница во времени между двумя датами. Мы продемонстрируем это ниже, вычислив время в секундах, прошедшее между функциями approveddate и creationdate в наборе данных об исполнении ссуды.

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

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

Период дня: мы можем извлечь период дня (утро, день, вечер) из функции даты, вручную сопоставив часы дня с периодом. Мы продемонстрируем это ниже.

Примечание. Многие функции времени, в том числе используемые здесь, уже реализованы в модуле timeseries библиотеки datasist. Вы можете легко вызывать и использовать эти функции всего в одной строке кода. Узнайте больше о библиотеке datasist здесь.

Работа с широтой и долготой

Географические объекты - это класс объектов, представленных в ряде наборов данных. Эти объекты содержат записи о географическом положении места / точки в космосе. Такие функции, как Longitudes, Latitudes и Address, являются географическими функциями, которые необходимо разработать.

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

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

Приведенные ниже техники взяты из этого удивительного ядра на Kaggle от Beluga.

  1. Манхэттенское расстояние: Манхэттенское расстояние - это сумма расстояний по горизонтали и вертикали между двумя точками. Давайте продемонстрируем это ниже, используя набор данных Sendy:

  • Сначала мы пишем функцию для вычисления манхэттенского расстояния. Это реализовано в базе NumPy.
  • Затем мы использовали созданную функцию для вычисления манхэттенского расстояния между Pickup и Destination.

2. Хаверсинусное расстояние: Хаверсинус - это расстояние по дуге большого круга между двумя точками на сфере с учетом их долготы и широты. Это очень важно в навигации.

  • Сначала мы пишем функцию для вычисления расстояния Харверсина. Это также реализовано в базе NumPy.
  • Затем мы используем функцию для вычисления расстояния Харверсина между Pickup и Destination.

3. Пеленг. Пеленг - это направление по компасу, используемое для движения от начальной точки, оно должно находиться в диапазоне от 0 до 360.

  • Сначала мы создаем функцию bearing в NumPy.
  • Затем мы используем функцию для вычисления азимута между Pickup и Destination.

4. Центральная точка: мы можем вычислить среднюю точку между двумя точками, исходя из их широты и долготы. Это можно сделать, сложив точки и разделив результат на 2.

  • Сначала мы вычисляем центральную широту, добавляя Pickup Latitude к Destination Latitude, а затем разделив результат на 2. Мы делаем то же самое для Pickup Longitude и Destination Longitude.

Примечание. Географические функции, такие как Манхэттен, Харверсайн и расстояние пеленга, уже реализованы в библиотеке DataSist. Вы можете легко вызвать и использовать их всего в одной строке кода. Узнайте больше о библиотеке datasist здесь.

И здесь занавес задергиваем…

Разработка функций имеет важное значение и часто является разницей между хорошей моделью машинного обучения и лучшей моделью машинного обучения.

В этом посте мы узнали о некоторых методах и инструментах для разработки функций. Мы начали с определения проектирования функций, а затем рассмотрели способы обработки пропущенных значений.

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

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

Это был действительно длинный пост, но я надеюсь, что вы многому научились и будете использовать некоторые (или многие!) Техники, описанные здесь, в своем следующем проекте.

Если у вас есть какие-либо вопросы, предложения или отзывы, не стесняйтесь использовать раздел комментариев ниже. Скоро увидимся, удачного анализа!

Ссылка на полную версию Блокнота с пояснениями и кодами на GitHub

Свяжитесь со мной в Твиттере.

Свяжитесь со мной в LinkedIn.

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

Независимо от редакции, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее создавать лучшие модели машинного обучения.