---
# System prepended metadata

title: ML System desgin case study "Twitter-style social media feed"
tags: [ML AA]

---

---
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. 
Четко следим, чтобы модель не заглядывала в фичах в будущее: валидация строго на более поздних данных, при подсчете статистик считаем то, что было на момент показа. 