feat(taste): fold enriched folksonomy tags into the profile (#1490 Step 3)
The taste recompute's tag facet now unions the cached track_tags (MusicBrainz/Last.fm folksonomy tags) alongside raw ID3 genre, so a coarse "Rock" gains "post-punk / shoegaze / melancholic". - taste_profile.sql: ListPlayEngagementInputsForUser + ListLikedTrackTasteInputsForUser now return track_id to key the enriched-tag lookup. - accumulate(): for each play, fold its track's enriched tags weighted by engagement × tag.weight × EnrichedTagScale; for each liked track, by the tag-like bonus × tag.weight × scale. A track with no cached tags contributes genre only (graceful). - New Config.EnrichedTagScale (default 0.5) — enriched tags augment the ID3 signal without swamping it; 0 = genre-only. Flows through recsettings.TasteConfig() (starts from DefaultConfig). Promoting it into the admin tuning lab is a small follow-up. Unit-tested the pure foldEnrichedTags helper (overlap accumulation + scale=0 disable). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,19 +87,21 @@ func (q *Queries) ListLikedArtistIDsForUser(ctx context.Context, userID pgtype.U
|
||||
}
|
||||
|
||||
const listLikedTrackTasteInputsForUser = `-- name: ListLikedTrackTasteInputsForUser :many
|
||||
SELECT t.artist_id, t.genre
|
||||
SELECT t.id AS track_id, t.artist_id, t.genre
|
||||
FROM general_likes gl
|
||||
JOIN tracks t ON t.id = gl.track_id
|
||||
WHERE gl.user_id = $1
|
||||
`
|
||||
|
||||
type ListLikedTrackTasteInputsForUserRow struct {
|
||||
TrackID pgtype.UUID
|
||||
ArtistID pgtype.UUID
|
||||
Genre *string
|
||||
}
|
||||
|
||||
// (artist_id, genre) for each track the user has explicitly liked. Feeds the
|
||||
// track-like bonus into the liked track's artist and tags.
|
||||
// (track_id, artist_id, genre) for each track the user has explicitly
|
||||
// liked. Feeds the track-like bonus into the liked track's artist and
|
||||
// tags; track_id keys the enriched track_tags lookup (#1490).
|
||||
func (q *Queries) ListLikedTrackTasteInputsForUser(ctx context.Context, userID pgtype.UUID) ([]ListLikedTrackTasteInputsForUserRow, error) {
|
||||
rows, err := q.db.Query(ctx, listLikedTrackTasteInputsForUser, userID)
|
||||
if err != nil {
|
||||
@@ -109,7 +111,7 @@ func (q *Queries) ListLikedTrackTasteInputsForUser(ctx context.Context, userID p
|
||||
var items []ListLikedTrackTasteInputsForUserRow
|
||||
for rows.Next() {
|
||||
var i ListLikedTrackTasteInputsForUserRow
|
||||
if err := rows.Scan(&i.ArtistID, &i.Genre); err != nil {
|
||||
if err := rows.Scan(&i.TrackID, &i.ArtistID, &i.Genre); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
@@ -123,6 +125,7 @@ func (q *Queries) ListLikedTrackTasteInputsForUser(ctx context.Context, userID p
|
||||
const listPlayEngagementInputsForUser = `-- name: ListPlayEngagementInputsForUser :many
|
||||
|
||||
SELECT
|
||||
t.id AS track_id,
|
||||
t.artist_id,
|
||||
t.genre,
|
||||
LEAST(GREATEST(
|
||||
@@ -146,6 +149,7 @@ type ListPlayEngagementInputsForUserParams struct {
|
||||
}
|
||||
|
||||
type ListPlayEngagementInputsForUserRow struct {
|
||||
TrackID pgtype.UUID
|
||||
ArtistID pgtype.UUID
|
||||
Genre *string
|
||||
Completion float64
|
||||
@@ -169,6 +173,7 @@ func (q *Queries) ListPlayEngagementInputsForUser(ctx context.Context, arg ListP
|
||||
for rows.Next() {
|
||||
var i ListPlayEngagementInputsForUserRow
|
||||
if err := rows.Scan(
|
||||
&i.TrackID,
|
||||
&i.ArtistID,
|
||||
&i.Genre,
|
||||
&i.Completion,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
-- track duration, clamped to [0,1]); age_days drives the time-decay. Genre
|
||||
-- is split into tags in Go. Quarantined tracks are excluded.
|
||||
SELECT
|
||||
t.id AS track_id,
|
||||
t.artist_id,
|
||||
t.genre,
|
||||
LEAST(GREATEST(
|
||||
@@ -25,9 +26,10 @@ WHERE pe.user_id = $1
|
||||
);
|
||||
|
||||
-- name: ListLikedTrackTasteInputsForUser :many
|
||||
-- (artist_id, genre) for each track the user has explicitly liked. Feeds the
|
||||
-- track-like bonus into the liked track's artist and tags.
|
||||
SELECT t.artist_id, t.genre
|
||||
-- (track_id, artist_id, genre) for each track the user has explicitly
|
||||
-- liked. Feeds the track-like bonus into the liked track's artist and
|
||||
-- tags; track_id keys the enriched track_tags lookup (#1490).
|
||||
SELECT t.id AS track_id, t.artist_id, t.genre
|
||||
FROM general_likes gl
|
||||
JOIN tracks t ON t.id = gl.track_id
|
||||
WHERE gl.user_id = $1;
|
||||
|
||||
Reference in New Issue
Block a user