Введение

В настоящее время медийная онлайн-реклама — это многомиллиардный бизнес с годовым доходом в 31,7 миллиарда долларов США в 2016 финансовом году, что на 29% больше, чем в 2015 финансовом году. нужных людей, в нужном контексте, в нужное время. Точное прогнозирование рейтинга кликов (CTR) имеет решающее значение для решения этой проблемы, и в последние несколько лет ему уделялось большое внимание исследователей.

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

Характеристики категориальных данных из нескольких полей демонстрируют некоторые уникальные проблемы:

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

2- Функции из одной области часто по-разному взаимодействуют с функциями из других областей.

3- Необходимо позаботиться о потенциально высокой сложности модели.

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

Набор данных

Набор данных, над которым мы будем работать, предоставлен вам благодаря Yektanet (иранской цифровой рекламной платформе). помеченная как «обучающая» часть набора данных состоит из более чем 4 миллионов данных.

Этот набор данных состоит из 14 функций + 1 цель, т. е. «Нажатие». Каждый раз, когда пользователь с уникальным идентификатором пользователя посещает веб-страницу с идентификатором документа, происходит просмотр страницы. Для каждого просмотра страницы создается уникальный отображаемый идентификатор. При каждом просмотре страницы пользователю одновременно показываются некоторые рекламные объявления. Временная метка указывает, когда произошло событие. Как видно из названия, "Час дня" и "День недели" показывают, когда произошло событие. Каждый рекламный контент отображается с помощью "Идентификатора объявления", и каждый из этих материалов принадлежит рекламной кампании, которая отображается с помощью "Идентификатора кампании", каждая кампания принадлежит рекламодателю, представленному 'ID рекламодателя'. Каждый пользователь использует определенное "устройство" для посещения веб-страницы. Мы можем легко определить, что столбец "OS" указывает на операционную систему, используемую пользователем. Столбец "Браузер" показывает, какой браузер пользователь использовал для посещения веб-страниц. Каждая реклама отображается в определенной части веб-страницы, которая называется виджетом. Идентификатор виджета указывает, какая часть веб-страницы выделена для рекламы. У каждой веб-страницы есть "Издатель" и "Источник".

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

Очистка данных

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

затем вам нужно перебрать все функции и найти значения NaN или Null:

count_missing = df_train.isnull().sum()
missing_value_df = pd.DataFrame({ ‘Count Missing’ : count_missing})
missing_value_df

приведенный выше фрагмент покажет нам, что с нашим набором данных не так много проблем с очисткой:

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

cor = df_train.corr()
plt.figure(figsize=(15,15))
sns.heatmap(cor, annot=True, cmap=plt.cm.Reds)
plt.show()

вывод приведенного выше фрагмента будет примерно таким:

Как видите, некоторые из наших функций сильно коррелированы, поэтому мы можем отбросить по одной из каждой пары.

Например, мы видим, что («timestamp», «display»), («source», «publisher»), («os», «device») здесь являются витыми парами, и мы удалим по одной из каждой функции. но, как я описал выше, и мы можем видеть в описании набора данных, «отметка времени» и «displayId» уникальны в наборе данных, и мы можем интерпретировать эту характеристику как индексы и отбросить оба.

drop_columns = ['timestamp', 'publisher','os', 'displayId']
df_train = df_train.drop(columns=drop_columns, axis=1)

То, что мы сделали до сих пор, — это просто обычные и очевидные критерии очистки в каждом наборе данных, но с такими данными нам нужно будет проделать несколько фокусов, чтобы увеличить взаимодействие функций и удалить бесполезные данные, такие как «userId», которые мы видим только несколько раз. во всем наборе данных или 'docId's или любых других функциях с аналогичным поведением.

Отбросьте бесполезные столбцы

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

Например, вывод этих двух функций для «userId» будет таким:

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

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

Набор данных дисбаланса

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

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

форма отрицательного класса перед субдискретизацией: (2926235, 16)

форма отрицательного класса после понижения дискретизации: (842181, 16)

Горячее кодирование

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

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

Логистическая регрессия

После всех проделанных работ приступим к реализации наших методов классификации.

Вы можете увидеть реализацию логистической регрессии в приведенном ниже фрагменте:

SVM

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

RandomForest

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

Перекрестная проверка:

Оценка в поезде:

оценка на тесте:

XGBoost

XGBoost намного быстрее, чем предыдущие методы, а также полученные результаты приемлемы. (но недостаточно хорошо)

Оценка в поезде:

Оценка на тесте:

Вывод

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

Вы можете увидеть все объясненные коды и другие методы, такие как FM, FWFM, в этой ссылке