Это четвертая часть серии статей Самоорганизующиеся карты с fast.ai.

Весь код опубликован в этом репозитории и этой библиотеке PyPi.

Обзор

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

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

Мы собираемся реализовать следующие основные функции:

  • Нормализация
  • Кодирование категориальных признаков
  • Экспорт кодовой книги SOM в фрейм данных Pandas

Нормализация

Мы будем использовать отдельный класс Normalizer для выполнения нормализации для каждой функции. Давайте определим базовый класс:

Сравнивая различные нормализаторы, я обнаружил, что нормализация по среднему значению и стандартному отклонению очень помогает с конвергенцией SOM, поэтому мы расширим наш Normalizer класс до VarianceNormalizer:

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

Давайте добавим нормализатор к нашему UnsupervisedDataBunch:

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

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

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

Как и в случае с нормализаторами, мы начнем с определения базового класса CatEncoder:

И подклассифицировать его в OneHotCatEncoder:

Все, что мы здесь делаем, - это используем torch.nn.functional.one_hot для быстрого кодирования наших входных переменных, сохраняя количество категорий для каждой функции в обучающем наборе в течение fit, а затем используем эту информацию для выполнения кодирования с помощью make_continuous и декодирования с помощью make_categorical.

Импорт фреймов данных Pandas

Одна особенность, которую мы могли бы пожелать для нашего UnsupervisedDataBunch, - это возможность создания из Pandas DataFrame. Как упоминалось в обзоре выше, мы будем использовать Fast.ai TabularDataBunch для загрузки и предварительной обработки данных за нас, а затем импортируем данные в нашу собственную базу данных.

TabularDataBunch обычно создается следующим образом:

Приведенный выше код делает следующее:

  • Загрузите фрейм данных в TabularList
  • Разделите список на наборы для обучения и проверки.
  • Заполните пропущенные значения
  • Превратите все категориальные признаки в порядковые категории

Теперь мы можем написать функцию преобразования для преобразования TabularDataBunch в UnsupervisedDataBunch. Здесь все становится хакерским: нам нужно извлекать категориальные и непрерывные функции отдельно, обрабатывать категориальные функции с помощью OneHotCatEncoder, а затем объединять все в один тензор.

Поскольку TabularDataBunch может иметь целевую переменную, мы собираемся добавить необязательные аргументы train_y и valid_y в наш UnsupervisedDataBunch:

Теперь мы можем преобразовать любой TabularDataBunch, просто используя функцию расширения:

Следующим шагом будет тестирование всего, что мы сделали до сих пор, на реальном наборе данных.

Тренинг по набору данных о ценах на жилье

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

Начнем с CSV-файла, содержащего обучающий набор, и перейдем к следующему:

Довольно аккуратно, правда? Всего за 40 строк кода мы получили обученную самоорганизующуюся карту 😊

Вот график потерь:

Создание DataFrame из кодовой книги SOM

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

Для этого мы могли бы написать codebook_to_df функцию внутри нашего SomLearner:

Теперь нам нужна модель для прогнозирования. Давайте воспользуемся этим представлением Kaggle регрессии цен на жилье с учащимся Fast.ai Tabular в качестве начала:

Запуск регрессии в кодовой книге SOM

Теперь, когда у нас есть обученный регрессор, давайте сгенерируем DataFrame кодовой книги SOM и используем его в качестве тестового набора:

Теперь мы можем использовать plt.imshow() для прогнозов, чтобы получить визуализацию распределения цен на жилье по SOM 😊

Это круто, правда? В следующей статье мы дополним наш инструментарий SOM, добавив целый ряд утилит визуализации и интерпретации, основываясь на нашем API на классе Fast.ai ClassificationInterpretaion.

Примечание. код библиотеки для UnsupervisedDataBunch был переписан с использованием Fast.ai TabularDataBunch с дополнительными преобразованиями. В этой статье DataBunch создается с нуля, и ее оставили нетронутой для облегчения понимания.