Улучшение классификации со многими категориальными переменными

37

Я работаю над набором данных с 200 000+ выборок и примерно 50 объектами на выборку: 10 непрерывных переменных, а остальные ~ 40 являются категориальными переменными (страны, языки, научные области и т. Д.). Для этих категориальных переменных у вас есть, например, 150 разных стран, 50 языков, 50 научных областей и т. Д.

Пока что мой подход:

  1. Для каждой категориальной переменной с множеством возможных значений возьмите только ту, которая имеет более 10000 выборок, которые принимают это значение. Это уменьшает до 5-10 категорий вместо 150.

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

  3. Заполните эти данные случайным классификатором леса (проверьте параметры и т. Д.).

В настоящее время с таким подходом мне удается получить только 65% точности, и я чувствую, что можно сделать больше. Особенно меня не устраивает мой 1), так как я чувствую, что не должен произвольно удалять «наименее релевантные значения» в соответствии с количеством выборок, которые они имеют, потому что эти менее представленные значения могут быть более дискриминационными. С другой стороны, моя оперативная память не может позволить себе добавлять в данные 500 столбцов * 200000 строк, сохраняя все возможные значения.

Будете ли вы предлагать справиться с такими категориальными переменными?

Бертран Р
источник
2
Если вы все еще заинтересованы, вы можете проверить мой ответ по уменьшению размерности и мой ответ по иерархической классификации .
Александр Блех
1
Когда вы говорите «создать фиктивную переменную для каждой категориальной» , звучит так, будто вы используете Python, а не R? R randomforest может работать с категориями, а также с сокращением памяти. Попробуйте R.
smci
См. Также stats.stackexchange.com/questions/146907/…
kjetil b halvorsen

Ответы:

20

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

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

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

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

Существует почти полная реализация асе здесь и у меня есть effichent больше памяти / быстрое внедрение вч , что ручки категориальные переменные изначально здесь ... -evaloob опция опция поддерживает 4 Я работаю на добавление поддержки для ACE и пару других ВЧ методы выбора объектов на основе, но это еще не сделано.

Райан Бресслер
источник
4
Все эти предложения интересны, я согласен, что случайный лес должен обрабатывать изначально категориальные переменные, но scikit-learn не ... Я думаю, что это один из главных недостатков scikit. Я попробую ваш код на своих данных, чтобы увидеть, что произойдет, и посмотрю о других ваших предложениях!
Бертран Р.
1
Попробуйте реализацию R Запуск это один лайнер. Чтение данных чрезвычайно просто, и существует новая паралельная реализация, которая работает быстро и эффективно использует память: r-bloggers.com/… С другой стороны. Ваши классы не сбалансированы? в реализации r вы можете вырастить каждое дерево из сбалансированного примера начальной загрузки sampsize = c (x, x). Это дало мне лучшие бинарные классификации. Вы можете поэкспериментировать с размерами и легко настроить классификацию, используя выходные данные матрицы путаницы OOB.
JEquihua
2
Реализация R в RandomForest допускает факторы с максимум 32 уровнями. scikit-learn менее ограничен, если вы сначала создаете фиктивные переменные (см. pandas.get_dummiesфункцию). Реализация случайного леса в H2O показала себя очень хорошо (см. 0xdata.com/docs/master/model/rf ).
Алекс Вулфорд
1
есть более новая и более быстрая реализация случайного леса, пакет называется ranger. Отличный материал на самом деле. На несколько порядков быстрее и не имеет ограничения в 32 уровня.
Марбель
6

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

cjauvin
источник
1
Это хорошо для категориальных функций с n <= 3, так как вы можете генерировать все те же разбиения, что и при рассмотрении функции изначально как категориальной. Для больших n можно получить наборы разбиений, которые эквивалентны категориальному разделению, но алгоритм может найти или не найти их так же эффективно ... однако, если вы разделите элемент на n числовых элементов, вы также снизите эффективность, с которой алгоритм может найти расщепления. Кто-то должен добавить поддержку категориальных переменных в реализацию scikit-learn, иначе это здорово.
Райан Бресслер
Я согласен с вами, когда вы говорите, что вводить ординальность в категориальных данных звучит подозрительно ... Я бы предпочел не делать этого, но я могу хотя бы попробовать и посмотреть, что получится!
Бертран Р.
4
Я долго обсуждал этот вопрос в списке рассылки sklearn (некоторые его части можно прочитать здесь: mail-archive.com/scikit-learn-general@lists.sourceforge.net/… ). По мнению одного из разработчиков, при достаточно глубоких деревьях порядковые кодированные категориальные функции могут работать достаточно хорошо (в дополнение к большей вычислительной эффективности). В любом случае, если вы попробуете это, мне будет очень интересно услышать о ваших результатах / заключении, так как я постоянно сталкиваюсь с этой проблемой.
cjauvin
1
Поэтому я попытался сохранить одну числовую переменную для категориальных, и она на самом деле работает на удивление хорошо, и намного лучше, чем добавление большого количества двоичных записей ... Я также попытался отсортировать значения в соответствии с их средним значением по отношению к цели , И это тоже отлично работает
Bertrand R
Я не удивлен этим на самом деле ... это соответствует тому, что я наблюдал в нескольких различных настройках, хотя, судя по количеству голосов, это довольно противоречивая идея.
cjauvin
5

Я думаю, что вы должны рассмотреть / более переменную технику сокращения . Это избавляет от не очень влиятельных предсказателей.

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

Мои предложения следующие:

  • для качественных переменных замените отсутствующие значения категорией «отсутствующие». Это может привести к смещению, если данные не пропущены случайно, но, по крайней мере, все ваши наблюдения останутся нетронутыми, а отсутствие может выявить другое поведение.
  • исключите предикторы с нулевой дисперсией или предикторы с почти нулевой дисперсией (будьте осторожны, чтобы не исключить фиктивные переменные с высокими несбалансированными категориями, которые могут эффективно разделить ваш Y. Сделайте несколько графиков для переменных, которые вы считаете важными). В R вы можете использовать 'nzv'функцию из'caret' пакета. Это сильно уменьшит измерение данных.
  • устранить коррелированные предикторы . Используйте матрицу корреляции Кендалла, потому что она более подходит для построения при наличии категориальных переменных. Недостатком является то, что вы должны преобразовать все свои номинальные переменные в категориальные.
  • Есть методы выбора функций которые еще больше уменьшат их количество (кластеризация - вы выбираете одного представителя каждого кластера, регрессию LASSO и т. д.). У меня еще не было возможности протестировать их, потому что другие шаги снизили мои переменные до 100.

Также я бы предложил использовать алгоритм AdaBoost вместо RF. Лично, исследования, которые я провел, дали мне очень похожие коэффициенты Джини для обоих этих методов. Хорошая сторона AdaBoost в том, что в R он обрабатывает недостающие наблюдения. Таким образом, вы можете пропустить 1-й шаг этого списка

Надеюсь, это немного помогло. Удачи

Lorelai
источник
4

Вы можете рассмотреть модели со смешанными эффектами. Они популярны в социальных науках благодаря своей работе с категориальными данными с высокой степенью кардинальности, и я использовал их для создания великолепных прогностических моделей, превосходящих популярные подходы машинного обучения, такие как деревья с градиентным усилением, случайные леса и упорядоченная логистическая регрессия с упругой сеткой. Наиболее известной реализацией является пакет R's lme4; функция, которую вы использовали бы для классификации, - glmer, которая реализует логистическую регрессию со смешанными эффектами. У вас могут быть проблемы с масштабированием вашего набора данных, но я сделал 80 тыс. Строк с 15 объектами без особых сложностей.

Павел
источник
2
  1. Когда вы говорите «создать фиктивную переменную для каждой категориальной» , звучит так, будто вы используете Python, а не R? R randomforest может работать с категориями, а также с сокращением памяти. Попробуйте R.

  2. Далее вам не нужно вручную сокращать / объединять категориальные уровни, что звучит как большая боль. И даже если вы это сделали, вы не гарантированы, что самые густонаселенные категории являются наиболее предсказуемыми. Управляйте сложностью случайного леса с помощью параметра размера узла : начните с большого размера узла и постепенно уменьшайте его (это поиск гиперпараметра).

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

SMCI
источник
0

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

Мне особенно нравится их реализация Gradient Boosted Machine (GBM), потому что вы можете посмотреть на значение переменной после построения модели. У GBM также есть хорошая особенность: они устойчивы к переоснащению.

Если вы хотите изучить другие модели, у них есть: GLM, Random Forest, Наивный Байес, Deep Learning и т. Д.

См .: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/gbm.html.

Он также прост в установке (Windows, Linux, Mac) и прост в работе с API, использующими R, Python, Java и Scala.

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

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

Это также с открытым исходным кодом и бесплатно (есть поддержка Enterprise).

Клем Ван
источник