Внедрение неконтролируемой сущности с использованием scikit-learn

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

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

Один из способов автоматизировать это решение - использовать алгоритм PCA или аналогичный алгоритм MCA. Идея состоит в том, чтобы использовать PCA после выполнения 1-горячего кодирования (с MCA требуется дополнительное преобразование). Выбирая векторы с наивысшими собственными значениями, мы можем представлять категории в векторном пространстве низкой размерности. PCA расположит высокочастотные категории далеко друг от друга, но расположит низкочастотные категории близко друг к другу. Продемонстрируем это на искусственном примере. Как и раньше, мы рассматриваем функцию дня недели, где 0 - понедельник, а 6 - воскресенье. Представьте, что большая часть данных поступает в выходные дни, поэтому мы создадим набор синтетических данных, чтобы продемонстрировать нашу концепцию.

array([ 23,  21,  23,  19,  20, 456, 438])

Мы видим, что в субботу и воскресенье данных намного больше, чем в будние дни. Мы подгоним PCA к этой категориальной переменной, но оставим только два компонента с наивысшими собственными значениями (т. Е. Те, которые улавливают наибольшую дисперсию)

Давайте изобразим компоненты, чтобы увидеть, как категории отображаются в двумерном векторном пространстве:

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

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

Ядро PCA

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

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

array([[1. , 0.9, 0.8, 0.7, 0.5, 0.1, 0.3],
       [0.9, 1. , 0.9, 0.8, 0.5, 0.1, 0.2],
       [0.8, 0.9, 1. , 0.9, 0.5, 0.1, 0.2],
       [0.7, 0.8, 0.9, 1. , 0.6, 0.1, 0.2],
       [0.5, 0.5, 0.5, 0.6, 1. , 0.7, 0.5],
       [0.1, 0.1, 0.1, 0.1, 0.7, 1. , 0.8],
       [0.3, 0.2, 0.2, 0.2, 0.5, 0.8, 1. ]])
array([[ 1.03305649, -0.19636025],
       [ 1.05001289, -0.38425859],
       [ 1.0480194 , -0.38846218],
       [ 1.01195609, -0.38461521],
       [ 0.29211243, -0.54331321],
       [-0.25333403, -0.22797924],
       [ 0.04688558,  0.32797451]])

Здесь мы видим, что дни недели разделены дальше друг от друга, за исключением вторника и среды, которые имеют почти одинаковое значение (и представлены на графике одной точкой).

Вывод

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

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