Skip to content

Выпускной проект курсов Karpov Courses специализации Start ML.

Notifications You must be signed in to change notification settings

Litvinov-Ivan/posts-feed-recsys

Repository files navigation

posts-feed-recsys

Выпускной проект курсов Karpov Courses специализации Start ML

Описание проекта

Цель - разработка сервиса рекомендательной системы постов в условной социальной сети.

Исходные данные

Пользователи сервиса
Поле Описание
age Возраст
city Город
country Страна
exp_group Экспериментальная группа
gender Пол
id Идентификатор
os Операционная система устройства
source Источник трафика
Количество зарегистрированных пользователей: ~163 тысячи
Новостные посты
Поле Описание
id Идентификатор
text Текст
topic Тематика
Количество постов: ~7 тысяч
Логи действий пользователей с постами ленты
Поле Описание
timestamp Время
user_id id пользователя
post_id id поста
action Совершённое действие - просмотр или лайк
target Поставлен ли лайк после просмотра.
Количество записей: ~77 миллионов

Описание задачи

Необходимо создать готовый к интеграции веб-сервис, возвращающий по запросу зарегистрированного пользователя персонализированную ленту новостей.

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

Ввиду невозможности проведения реального A\B-теста, необходимо смоделировать запросы пользователей к нашему сервису на основе имеющихся исторических данных и провести статистический анализ.

Параметры запроса
Поле Описание
id id пользователя
time Время запроса
limit Количество постов в ленте
Параметры отклика (одного поста из ленты)
Поле Описание
id id поста
text Текст поста
topic Тема поста
Метрика

Оценка качества обученных алгоритмов будет замеряться по метрике hitrate@5 - есть ли хотя бы один лайк от пользователя в показанной ему ленте.

Технические требования и принятые допущения
  1. Время отклика сервиса на 1 запрос не должен превышать 0.5 секунд.
  2. Сервис не должен занимать более 2 Гб памяти системы.
  3. Сервис должен иметь минимум две модели - обученную методом классического ML и с помощью DL.
  4. Набор пользователей и постов фиксирован.
  5. Временные рамки подаваемых сервису запросов ограничены предельными значениями в логах действий пользователей.

Описание решения

Анализ данных

При EDA препятствием стал размер датасета логов пользователей - 77 миллионов строк. С целью уменьшить потребляемую память из базы данных было выгружено около 6 миллионов записей. При этом данные выгружались равномерно по последним двум месяцам наблюдений. Далее этот массив разбили на обучающую и тестовую выборку - 3.5 млн, 1 млн и 1.5 млн соответственно.

Выбор алгоритма решения

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

  1. Рекомендационную модель на методе классического ML решено обучать с помощью CatboostClassifier. Данный выбор обоснован табличной сущностью данных и необходимостью ранжировать полученные моделью предсказания. Так как целевым показателем для нас является получение like хотя бы у одного поста в выдаче (согласно метрике hitrate@5), ранжировать предсказания будем по вероятностям, полученными в классификаторе.
  2. Вторая модель представляет собой тот же CatboostClassifier с обучением на полученных с помощью DL эмбеддингами текстов постов. Эмбеддинги текстов получены с помощью эмбеддингов слов, в свою очередь полученные обучением Word2Vec и дальнейшими преобразованиями.

Реализация сервиса

Сервис реализован с помощью FastAPI в виде endpoint "ручки":

  1. По POST запросу принимается запрос от пользователя на выдачу ленты.
  2. Полученный в запросе JSON обрабатывается, все необходимые признаки приводятся к требуемой для модели форме.
  3. Модель делает предсказания для каждого поста и выбираются с наибольшей вероятностью получающие лайк.
  4. Сервис возвращает отклик со списком рекомендованных постов.

Итоговые метрики

  1. Среднее значение hitrate@5 в экспериментальной группе: 0.372
  2. Среднее значение hitrate@5 в контрольной группе: 0.347

Методику и расчет указанных значений см. в этом ноутбуке.

Выводы

Реализован веб-сервис, по POST запросу id пользователя возвращающий ленту постов. При этом смоделирован A\B-тест, при котором сравниваются две различных модели рекомендаций. Полученные в результате моделирования данные были проанализированы и показана статистически значимая разница полученных метрик. Для удобства проверки работы сервиса, был подготовлен Docker образ, запускаемый с помощью docker-compose. Кодстайл сервиса проверен flake8 и pyflakes.

Пути улучшения полученного результата

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

  1. Возможен более глубокий feature engineering, например кластеризация постов и пользователей.
  2. Обученные модели довольно просты. Не исследованы классические RecSys подходы (коллаборативная фильтрация и т.д.).
  3. Кроме того, возможна более тонкая настройка гиперпараметров использовавшегося CatboostClassifier.
  4. В DL модели эмбеддинги текстов получены довольно прямолинейно - современные предобученные модели могут предложить получение эмбеддингов имеющегося корпуса текстов с учётом контекста (BERT и т.д.)
  5. Проведённый А\В-тест имеет большое число допущений и упрощений, кроме того технические ограничения не позволили провести статистический анализ на большей выборке.
  6. Возможно улучшение сервиса по сбору и мониторингу метрик - времени отклика под нагрузкой, разделение пользователей по группам, список постов в ленте и т.д.

Структура репозитория

|   README.md
|   docker-compose.yaml
|   request-examples.txt
|
├───notebooks
│       data_downloading.ipynb
│       data_processing.ipynb
│       database_analyze.ipynb
│       model_training.ipynb
│       dl_model_training.ipynb
|       statistical_analysis.ipynb
|       
└───posts_feed_service
    │   __init__.py
    │   requirements.txt
    │   app.py
    |   Dockerfile
    │
    ├───data
    │       catboost_model
    │       catboost_model_with_text_embs
    │       post_data.csv
    │       post_data_lemmatized.csv
    │       tfidf_df.csv
    │       user_data.csv
    │       post_data_lemmatized_and_embs.csv
    │       test_data.csv
    │
    └───lib
            __init__.py
            config.yaml
            datatypes.py
            utils.py
            model.py
Название Описание
posts_feed_service Сервис
data Папка с предобученными моделями и вспомогательными датасетами
lib Папка со вспомогательными модулями
notebooks Ноутбуки
data_downloading Скачивание данных
data_processing Обработка данных
model_training Обучение модели классического ML
dl_model_training Получение эмбеддингов текстов и обучение с их помощью модели
database_analyze Анализ исходной базы данных
statistical_analysis Статистический анализ проведённого А\В-теста

Инструкция для запуска

Способ 1

git clone https://github.com/Litvinov-Ivan/posts-feed-recsys.git
cd ./posts-feed-recsys
docker-compose up -d

Способ 2

git clone https://github.com/Litvinov-Ivan/posts-feed-recsys.git
cd ./posts-feed-recsys/posts_feed_service
python.exe -m pip install --upgrade pip
pip install -r requirements.txt
python.exe -m uvicorn app:app

Сервис доступен по http://127.0.0.1:8000/docs, где во вкладке /feed можно протестировать запрос на выдачу ленты. Примеры запросов есть здесь.

About

Выпускной проект курсов Karpov Courses специализации Start ML.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published