---
title: ML System desgin case study "Twitter-style social media feed"
tags: ML AA
description: View the slide with "Slide Mode".
---
## Create a Twitter-style social media feed to display relevant posts to users.
Это пример решения секции ML System Design.
**Описание:** у нас есть платформа публикации пользовательского контента (постов). Допустим, что есть следующие функциональности: публикация поста (текстового, мб картинок, видео, музыки), комментарии, лайки. А также есть возможность подписываться на других авторов. По умолчанию есть лента составленная из постов всех, на кого ты подписался, отсортированная по времени.
**Цель:** Есть идея сделать рекомендательную ленту, в которой будут посты не только от “друзей”, но и от сторонних авторов, отсортированные по “релевантности”. Хотим с её помощью помогать юзерам находить интересный контент, а хорошим авторам своих читателей.
**Верхнеуровневые метрики**, которые хотим тут вырастить: суммарное время чтения постов, число сессий, число новых постов.
**Постановка ML задачи:** Будем решать как задачу отбора кандидатов (классификация) + ранжирование.
**Объемы:** Будем считать, что у нас около 10 миллионов пользователей и 100 миллионов постов. Медианное число взаимодейтсвий у поста может быть около 5, то есть немного.
**Данные:** пусть у нас есть данные вида
```
impressions = {user_id, post_id, impression_meta}
users = {user_id, user_meta}
posts = {post_id, post_meta}
```
**Отбор кандидатов**
Для отбора кандидатов объединим выходы нескольких моделей: контентной и коллаборативной.
Во-первых, оставить только авторов, которые в друзьях друзей или входят в topK1 по всей соцсети или topK2 по региону пользователя или в topK3 по интересующим пользователя категориям. Топы составляются по дневной аудитории за последние 2 месяца. Это оставит примерно 10к пользователей.
Во-вторых, можно отфильтровать все посты, которые старше чем 2 недели.
Еще можно факторизовать матрицу `{user_id, post_id, impressions_count}` и воспользоваться коллаборативной фильтрацией, чтобы оставить только посты, которые “нравятся”, пользователям, похожим на данного.
Подберём такие пороги, чтобы оставалось порядка десятка тысяч кандидатов.
**Ранкинг (классфикация)**
Используем point-wise ranking.
На кандидатах будем использовать модель с большим числом фичей, обученную под задачу классификации. Будем предсказавать лайк. Ранжировать будем по предсказанной вероятности/уверенности. Оценивать качество будем по roc auc, MAP@k.
В качестве фичей модель будет принимать на вход:
- user features
- обучаемый эмбеддинг юзера
- мета-инфа юзера (соцдем, девайс, браузер, регион)
- усредненные фичи последних k лайкнутых постов
- context features (время суток, недели, года)
- post features
- nlp фичи поста (усредненный word2vec)
- мета-инфа поста
- обучаемый эмбеддинг автора поста
- количество лайков, шеров, долгих просмотров итд, всех просмотров, кликов
- возраст поста
- user-post features
- расстояние в графе между автором и постом, число общих друзей, итд
- близость любимых авторов юзера и данного автора
- усредненный эмбеддинг лайкнувших пользователей
- есть ли друзья среди лайкнувших
Над этими фичами можно запустить однослойную или двухслойную сетку с logloss-ом на выходе.
**Как обучаться?**
Данные сэмплируем так: для каждого пользователя генерируем кандидатов по правилу выше, а потом берём лайкнутые посты (позитивный пример) и просмотренные, но не лайкнутые (негативный пример). Балансируем классы 1 к 1.
Четко следим, чтобы модель не заглядывала в фичах в будущее: валидация строго на более поздних данных, при подсчете статистик считаем то, что было на момент показа.