Odtworzenie uczenia na 189 tys. zdarzen (wagi zdarzenie po zdarzeniu, bez zagladania w przyszlosc, test na 30% najnowszych): stara punktacja porzadkowala klipy w obrebie urzadzenia z AUC 0,576 (lajk albo >= 10 s vs ucieczka < 2 s). Tagi RedGifs sa liczne i ogolne, wiec ich suma dominowala, a mowila malo; nisze prawie nic, popularnosc z RedGifs slabo, tworca i przyjecie klipu u nas najwiecej. Nowa: log(waga tagu x rzadkosc tagu) + 0,25 log(nisze) + 2,5 log(tworca) + 0,8 ln(1+lajki RedGifs) + 120 (odsetek lajkow u nas - 3%) - 15 (odsetek ucieczek - 50%) + 0,3 za swiezosc. Na tescie 0,652, regresja na tych samych cechach 0,654. Liczniki clips.feed_views/skips/likes (migracja 0052, wypelnione z historii), bumpowane w POST /clips/events. 25% urzadzen (hash id) zostaje na starej punktacji do porownania na zywym ruchu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
"""Liczniki klipu z feedu Edge: wyswietlenia, ucieczki (< 2 s) i lajki w samym Goonie.
|
|
|
|
Odtworzenie uczenia feedu na 189 tys. zdarzen (2026-10-02) pokazalo, ze najmocniejszym
|
|
sygnalem tego, czy klip sie spodoba, jest to, jak przyjeli go inni u nas: odsetek lajkow
|
|
(AUC w obrebie urzadzenia 0,600) bije wagi tagow (0,571), a popularnosc z RedGifs prawie
|
|
nic nie mowi (0,532). Punktacja (app/clips_feed.py) potrzebuje tych liczb w chwili
|
|
ukladania strony, stad kolumny przy klipie zamiast agregatu po clip_feed_events.
|
|
|
|
ADD COLUMN ze stalym DEFAULT nie przepisuje tabeli (Postgres 11+). Wypelnienie z
|
|
dotychczasowych zdarzen jednym UPDATE (~70 tys. klipow).
|
|
|
|
Revision ID: 0052_clips_feed_counters
|
|
Revises: 0051_movies_tpdb_checked_at
|
|
Create Date: 2026-10-02
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from alembic import op
|
|
|
|
revision = "0052_clips_feed_counters"
|
|
down_revision: str | None = "0051_movies_tpdb_checked_at"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute("SET LOCAL lock_timeout = '5s'")
|
|
op.execute("""
|
|
ALTER TABLE clips
|
|
ADD COLUMN IF NOT EXISTS feed_views integer NOT NULL DEFAULT 0,
|
|
ADD COLUMN IF NOT EXISTS feed_skips integer NOT NULL DEFAULT 0,
|
|
ADD COLUMN IF NOT EXISTS feed_likes integer NOT NULL DEFAULT 0
|
|
""")
|
|
op.execute("""
|
|
UPDATE clips c SET feed_views = a.v, feed_skips = a.s, feed_likes = greatest(a.l, 0)
|
|
FROM (
|
|
SELECT clip_id,
|
|
count(*) FILTER (WHERE kind IN ('complete', 'skip', 'impression', 'autoswipe')) AS v,
|
|
count(*) FILTER (WHERE kind = 'skip') AS s,
|
|
count(*) FILTER (WHERE kind = 'like') - count(*) FILTER (WHERE kind = 'unlike') AS l
|
|
FROM clip_feed_events WHERE clip_id IS NOT NULL
|
|
GROUP BY clip_id
|
|
) a
|
|
WHERE a.clip_id = c.id
|
|
""")
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("SET LOCAL lock_timeout = '5s'")
|
|
op.execute("""
|
|
ALTER TABLE clips
|
|
DROP COLUMN IF EXISTS feed_views,
|
|
DROP COLUMN IF EXISTS feed_skips,
|
|
DROP COLUMN IF EXISTS feed_likes
|
|
""")
|