Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

[HW2] Рачкин Владимир Сергеевич #7

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# HW2

## Abstract

Взять бейзлайновый DSSM (recommendations_dssm) и накрутить на него какую-нибудь интересную эвристику.

Если слушателю понравился трек из топ-100, значит он точно не хейтер мейнстримной музыки и если в рекомендациях от DSSM есть, что-то из топа, то порекомендуем.

## Детали

В файле `custom.py` реализовал класс `CustomRecommender`. Мы просто берём случайны трек из рекомендаций от DSSM

Просто идём по рекомендациям от DSSM. Если слушатель прослушал `80%` трека из топ-100, порекомендуем ему трек от DSSM который есть в топ-100.

В файле `server.py` добавили наш рекомендер к остальным


## Результаты A/B эксперимента

![](table.png)

## Как повторить эксперимент

### Повтор

В репозиторий уже загружены результаты в файле [cache/botify-recommender-1/data.json](./cache/botify-recommender-1/data.json). Можно сразу перейти к просмотру

```shell
# Запускаем Botify (Нужно немного подождать пока запуститься
cd botify
docker-compose up -d --build --force-recreate --scale recommender=1
```

```shell
# Запускаем симуляцию
cd ../sim
python -m sim.run --episodes 2000 --config config/env.yml single --recommender remote --seed 31337
cd ..
```

```shell
# Чистим кэш
rm -rf cache
```

```shell
# Сохраняем результаты
python ./script/dataclient.py --recommender 1 log2local ./cache/
```

```shell
# Останавливаем Botify
docker-compose stop
```

### Просмотр

Для просмотра результатов смотрим [Week 1 Seminar](./jupyter/Week1Seminar.ipynb).

T4 - бейзлайн (DSSM). T7 - наша эвристичка.
3 changes: 2 additions & 1 deletion botify/botify/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Split(Enum):
FOUR_WAY = 4
FIVE_WAY = 5
SEVEN_WAY = 7
EIGHT_WAY = 8
NINE_WAY = 9


Expand Down Expand Up @@ -70,7 +71,7 @@ class Experiments:
CONTEXTUAL = Experiment("CONTEXTUAL", Split.HALF_HALF)
GCF = Experiment("GCF", Split.HALF_HALF)
DIVERSITY = Experiment("DIVERSITY", Split.HALF_HALF)
ALL = Experiment("ALL", Split.SEVEN_WAY)
ALL = Experiment("ALL", Split.EIGHT_WAY)

def __init__(self):
self.experiments = [Experiments.ALL]
36 changes: 36 additions & 0 deletions botify/botify/recommenders/custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from .recommender import Recommender

import numpy
import random


class CustomRecommender(Recommender):
def __init__(self, recommendations_redis, catalog, top_tracks, fallback):
self.recommendations_redis = recommendations_redis
self.fallback = fallback
self.catalog = catalog
self.top_tracks = top_tracks

def recommend_next(self, user: int, prev_track: int, prev_track_time: float) -> int:
recommendations = self.recommendations_redis.get(user)

if recommendations is not None:
list_recommendations = list(self.catalog.from_bytes(recommendations))

if prev_track in self.top_tracks:
liked_top = prev_track_time >= 0.8
rec_top = []
for track in self.top_tracks:
if track in list_recommendations:
rec_top.append(track)
if len(rec_top) > 5 and liked_top:
return int(numpy.random.choice(rec_top, 1)[0])

if prev_track in list_recommendations:
next_id = (list_recommendations.index(prev_track) + 1) % len(list_recommendations)
return list_recommendations[next_id]

random.shuffle(list_recommendations)
return list_recommendations[0]

return self.fallback.recommend_next(user, prev_track, prev_track_time)
6 changes: 6 additions & 0 deletions botify/botify/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from botify.recommenders.contextual import Contextual
from botify.recommenders.toppop import TopPop
from botify.recommenders.sticky_artist import StickyArtist

from botify.recommenders.custom import CustomRecommender

from botify.track import Catalog

root = logging.getLogger()
Expand Down Expand Up @@ -104,6 +107,9 @@ def post(self, user: int):
recommender = Contextual(recommendations_contextual.connection, catalog, Random(tracks_redis.connection))
elif treatment == Treatment.T6:
recommender = Contextual(recommendations_div.connection, catalog, Random(tracks_redis.connection))
elif treatment == Treatment.T7:
# Custom recommender DSSM with toptracks feature
recommender = CustomRecommender(recommendations_dssm.connection, catalog, catalog.top_tracks[:1000], Random(tracks_redis.connection))
else:
recommender = Random(tracks_redis.connection)

Expand Down
Loading