Выпускной проект курсов 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 запрос не должен превышать 0.5 секунд.
- Сервис не должен занимать более 2 Гб памяти системы.
- Сервис должен иметь минимум две модели - обученную методом классического ML и с помощью DL.
- Набор пользователей и постов фиксирован.
- Временные рамки подаваемых сервису запросов ограничены предельными значениями в логах действий пользователей.
При EDA препятствием стал размер датасета логов пользователей - 77 миллионов строк. С целью уменьшить потребляемую память из базы данных было выгружено около 6 миллионов записей. При этом данные выгружались равномерно по последним двум месяцам наблюдений. Далее этот массив разбили на обучающую и тестовую выборку - 3.5 млн, 1 млн и 1.5 млн соответственно.
Так как сервис должен иметь возможность давать рекомендации двумя различными моделями, необходимо сделать и обосновать выбор.
- Рекомендационную модель на методе классического ML решено обучать с помощью CatboostClassifier. Данный выбор обоснован табличной сущностью данных и необходимостью ранжировать полученные моделью предсказания. Так как целевым показателем для нас является получение like хотя бы у одного поста в выдаче (согласно метрике hitrate@5), ранжировать предсказания будем по вероятностям, полученными в классификаторе.
- Вторая модель представляет собой тот же CatboostClassifier с обучением на полученных с помощью DL эмбеддингами текстов постов. Эмбеддинги текстов получены с помощью эмбеддингов слов, в свою очередь полученные обучением Word2Vec и дальнейшими преобразованиями.
Сервис реализован с помощью FastAPI в виде endpoint "ручки":
- По POST запросу принимается запрос от пользователя на выдачу ленты.
- Полученный в запросе JSON обрабатывается, все необходимые признаки приводятся к требуемой для модели форме.
- Модель делает предсказания для каждого поста и выбираются с наибольшей вероятностью получающие лайк.
- Сервис возвращает отклик со списком рекомендованных постов.
- Среднее значение hitrate@5 в экспериментальной группе: 0.372
- Среднее значение hitrate@5 в контрольной группе: 0.347
Методику и расчет указанных значений см. в этом ноутбуке.
Реализован веб-сервис, по POST запросу id пользователя возвращающий ленту постов. При этом смоделирован A\B-тест, при котором сравниваются две различных модели рекомендаций. Полученные в результате моделирования данные были проанализированы и показана статистически значимая разница полученных метрик. Для удобства проверки работы сервиса, был подготовлен Docker образ, запускаемый с помощью docker-compose. Кодстайл сервиса проверен flake8 и pyflakes.
Ввиду различных допущений и ограничений, а так же учебного характера проекта, укажем возможные пути улучшения сервиса:
- Возможен более глубокий feature engineering, например кластеризация постов и пользователей.
- Обученные модели довольно просты. Не исследованы классические RecSys подходы (коллаборативная фильтрация и т.д.).
- Кроме того, возможна более тонкая настройка гиперпараметров использовавшегося CatboostClassifier.
- В DL модели эмбеддинги текстов получены довольно прямолинейно - современные предобученные модели могут предложить получение эмбеддингов имеющегося корпуса текстов с учётом контекста (BERT и т.д.)
- Проведённый А\В-тест имеет большое число допущений и упрощений, кроме того технические ограничения не позволили провести статистический анализ на большей выборке.
- Возможно улучшение сервиса по сбору и мониторингу метрик - времени отклика под нагрузкой, разделение пользователей по группам, список постов в ленте и т.д.
| 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 | Статистический анализ проведённого А\В-теста |
git clone https://github.com/Litvinov-Ivan/posts-feed-recsys.git
cd ./posts-feed-recsys
docker-compose up -d
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
можно протестировать запрос на выдачу ленты.
Примеры запросов есть здесь.