Vowpal Wabbit, как представить категориальные функции

У меня есть следующие данные со всеми категориальными переменными:

    class  education    income    social_standing
    1       basic       low       good
    0        low        high      V_good
    1        high       low       not_good
    0        v_high     high      good

Здесь образование имеет четыре уровня (базовый, низкий, высокий и v_high). доход имеет два уровня низкого и высокого уровня; и social_standing имеет три уровня (хороший, v_good и not_good).

В том, что касается моего понимания преобразования указанных данных в формат VW, это будет примерно так:

    1 |person education_basic income_low social_standing_good
    0 |person education_low income_high social_standing_v_good
    1 |person education_high income_low social_standing_not_good
    0 |person education_v_high income_high social_standing_good

Здесь "человек" - это пространство имен, а все остальные - значения признаков, префиксные соответствующими именами функций. Я прав? Каким-то образом это представление значений признаков довольно озадачивает меня. Есть ли другой способ представления функций? Будем благодарны за помощь.

Ответ 1

Да, вы правы.

Это представление, безусловно, будет работать с vowpal wabbit, но при некоторых условиях может не быть оптимальным (это зависит).

Чтобы представить нестандартные, категориальные переменные (с дискретными значениями), стандартный трюк wowpal wabbit заключается в использовании логических/логических значений для каждой возможной комбинации (имя, значение) (например, person_is_good, color_blue, color_red). Причина этого в том, что vw неявно принимает значение 1, если значение отсутствует. Нет никакой практической разницы между color_red, color=red, color_is_red или даже (color,red) и color_red:1 за исключением мест хеширования в памяти. Единственными символами, которые вы не можете использовать в имени переменной, являются специальные разделители (: и |) и пробелы.

Примечание по терминологии: этот трюк преобразования каждой пары (функция + значение) в отдельную функцию иногда называют "одним горячим кодированием".

Но в этом случае переменные значения могут быть не "строго категоричными". Они могут быть:

  • Строго упорядоченный, например (low < basic < high < v_high)
  • Предположительно, имеет монотонное отношение с меткой, которую вы пытаетесь предсказать

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

В вашем конкретном случае вы можете получить лучший результат, преобразовывая значения в числовые, например. (1, 2, 3, 4) для образования. вы можете использовать что-то вроде:

1 |person education:2 income:1 social_standing:2
0 |person education:1 income:2 social_standing:3
1 |person education:3 income:1 social_standing:1
0 |person education:4 income:2 social_standing:2

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

Здесь короткий чит-лист для кодирования переменных в wowpal wabbit:

Variable type       How to encode                readable example
-------------       -------------                ----------------
boolean             only encode the true case    is_alive
categorical         append value to name         color=green
ordinal+monotonic   :approx_value                education:2
numeric             :actual_value                height:1.85

Заключительные примечания:

  • В vw все переменные являются числовыми. Кодирующие трюки - это просто практические способы сделать categorical или boolean. Булевы переменные - просто числовые 0 или 1; Категориальные переменные могут быть закодированы как boolean: name + value: 1.
  • Любая переменная, значение которой не является монотонной с меткой, может быть менее полезно при кодировании по цифре.
  • Любая переменная, не линейно связанная с меткой, может извлечь выгоду из нелинейного преобразования перед обучением.
  • Любая переменная с нулевым значением не будет иметь никакого отношения к модели (исключение: если используется опция --initial_weight <value>), поэтому ее можно удалить из учебного набора
  • При анализе функции только : считается специальным разделителем (между именем переменной и его числовым значением), все остальное считается частью имени, а вся строка имени хешируется в месте в памяти. Отсутствующая часть :<value> подразумевает :1

Изменить: как насчет пространств имен?

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

|E low |I low

Является, по существу, эквивалентным (нет примерного пространства имен):

|  E^low:1 I^low:1

Основное использование пространств имен заключается в том, чтобы легко переопределить всех членов пространства имен на что-то еще, игнорировать полное пространство имен функций, перекрестные функции пространства имен с другим и т.д. (см. -q, --cubic, --redefine, --ignore, --keep).