Представительство: Разработка функций

В традиционном программировании основное внимание уделяется коду. В проектах машинного обучения акцент смещается на представление. То есть один из способов усовершенствования модели разработчиками — добавление и улучшение ее функций.

Сопоставление необработанных данных с объектами

Левая часть рисунка 1 иллюстрирует необработанные данные из источника входных данных; правая часть иллюстрирует вектор признаков , который представляет собой набор значений с плавающей запятой, включающий примеры в вашем наборе данных. Разработка признаков означает преобразование необработанных данных в вектор признаков. Будьте готовы потратить значительное время на разработку функций.

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

Необработанные данные сопоставляются с вектором признаков посредством процесса, называемого разработкой признаков.

Рисунок 1. Проектирование функций сопоставляет необработанные данные с функциями ML.

Сопоставление числовых значений

Целочисленные данные и данные с плавающей запятой не нуждаются в специальной кодировке, поскольку их можно умножать на числовой вес. Как показано на рисунке 2, преобразование необработанного целочисленного значения 6 в значение признака 6.0 тривиально:

Пример объекта, который можно скопировать непосредственно из необработанных данных

Рисунок 2. Сопоставление целочисленных значений со значениями с плавающей запятой.

Сопоставление категориальных значений

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

{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}

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

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

Используя этот подход, мы можем сопоставить названия улиц с числами:

  • карта Чарльстон-Роуд до 0
  • отобразить бульвар Норт-Шорлайн на 1
  • карта Shorebird Way to 2
  • проложить проспект Ренгсторфф до дома 3
  • сопоставьте все остальное (OOV) с 4

Однако если мы включим эти индексные числа непосредственно в нашу модель, это наложит некоторые ограничения, которые могут быть проблематичными:

  • Мы будем изучать единый вес, который применим ко всем улицам. Например, если мы узнаем вес 6 для street_name , то мы умножим его на 0 для Charleston Road, на 1 для North Shoreline Boulevard, на 2 для Shorebird Way и так далее. Рассмотрим модель, которая прогнозирует цены на жилье, используя street_name в качестве признака. Маловероятно, что существует линейная корректировка цен в зависимости от названия улицы, и, кроме того, это предполагает, что вы упорядочили улицы на основе средней цены на жилье. Нашей модели необходима гибкость обучения различным весам для каждой улицы, которые будут добавляться к цене, оцененной с использованием других функций.

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

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

  • Для значений, которые применяются к примеру, установите соответствующие элементы вектора на 1 .
  • Установите для всех остальных элементов значение 0 .

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

На рисунке 3 показано горячее кодирование конкретной улицы: Shorebird Way. Элемент двоичного вектора для Shorebird Way имеет значение 1 , тогда как элементы для всех остальных улиц имеют значения 0 .

Сопоставление строкового значения (

Рисунок 3. Сопоставление уличного адреса с помощью горячего кодирования.

Этот подход эффективно создает логическую переменную для каждого значения объекта (например, названия улицы). Здесь, если дом находится на Shorebird Way, то двоичное значение равно 1 только для Shorebird Way. Таким образом, в модели используется только вес Shorebird Way.

Аналогично, если дом находится на углу двух улиц, то двум двоичным значениям присваивается значение 1, и модель использует оба соответствующих веса.

Разреженное представление

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