feat(social): add listening activity, shared rooms and modern chat
ci / api / api (push) Canceled after 0s
ci / module boundaries / boundaries (push) Canceled after 0s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Canceled after 11m29s
ci / db / db (push) Canceled after 11m22s
ci / mobile / mobile (Metro-бандл Android) (push) Canceled after 6m43s
ci / recommender / recommender (push) Canceled after 6m47s
ci / ts / ts (packages + web) (push) Canceled after 1s
ci / api / api (push) Canceled after 0s
ci / module boundaries / boundaries (push) Canceled after 0s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Canceled after 11m29s
ci / db / db (push) Canceled after 11m22s
ci / mobile / mobile (Metro-бандл Android) (push) Canceled after 6m43s
ci / recommender / recommender (push) Canceled after 6m47s
ci / ts / ts (packages + web) (push) Canceled after 1s
This commit is contained in:
1 parent
0a05bfe2cd
commit
11a16cd023
59 files changed
+5022
-542
No files matched your search
@@ -313,6 +313,7 @@ def build_batch(
|
||||
rng: np.random.Generator | None = None,
|
||||
ranker: Ranker | None = None,
|
||||
ctx: Context | None = None,
|
||||
friend_ids: list[str] | None = None,
|
||||
) -> list[Pick]:
|
||||
"""Кандидаты → фильтры → оценка → соответствие контексту → MMR с правилами разнообразия."""
|
||||
rng = rng or np.random.default_rng()
|
||||
@@ -363,6 +364,8 @@ def build_batch(
|
||||
if seeds:
|
||||
q = index.emb[seeds].mean(axis=0)
|
||||
add(_top((index.emb @ q).astype(np.float64), allowed & index.has_emb, 100), "seed")
|
||||
friends = [index.pos[t] for t in (friend_ids or []) if t in index.pos and allowed[index.pos[t]]][:10]
|
||||
add(friends, "friends")
|
||||
query = np.maximum(sim_session, sim_taste) if svec is not None or len(centroids) else None
|
||||
if query is not None:
|
||||
# «Новое» помечаем раньше audio_sim: неслышанный трек рядом со вкусом считается исследованием.
|
||||
@@ -446,6 +449,8 @@ def build_batch(
|
||||
pred = ranker.predict(x)
|
||||
score = np.argsort(np.argsort(pred)) / max(len(pred) - 1, 1)
|
||||
|
||||
# Social influence is small, context-sensitive, and survives the learned ranker.
|
||||
score = score + 0.06 * np.isin(cand, friends) * f
|
||||
# 5. MMR + правила: 1 трек исполнителя на пачку, не больше 2 на последние 10; доля «нового».
|
||||
picks: list[Pick] = []
|
||||
chosen: list[int] = []
|
||||
@@ -457,6 +462,8 @@ def build_batch(
|
||||
best_j, best_v = -1, -np.inf
|
||||
for j in order:
|
||||
i = int(cand[j])
|
||||
if sources[i] == "friends" and any(p.source == "friends" for p in picks):
|
||||
continue
|
||||
a = index.artist[i]
|
||||
if any(index.artist[c] == a for c in chosen) or recent_artists.count(a) >= 2:
|
||||
continue
|
||||
@@ -471,7 +478,9 @@ def build_batch(
|
||||
continue
|
||||
if chosen:
|
||||
chosen_artists = {index.artist[c] for c in chosen}
|
||||
rest = [j for j in order if index.artist[int(cand[j])] in chosen_artists]
|
||||
social_chosen = any(p.source == "friends" for p in picks)
|
||||
rest = [j for j in order if index.artist[int(cand[j])] in chosen_artists
|
||||
and not (sources[int(cand[j])] == "friends" and social_chosen)]
|
||||
if not rest:
|
||||
break
|
||||
best_j = max(rest, key=lambda j: score[j])
|
||||
|
||||
Reference in new issue
Block a user