Çalma listesi önerilerini 500 parçada etiketle süzmek

这篇内容暂时只有 Türkçe 版本,以下是原文。

Geçen ay kendi arşivimden bir öneri listesi çıkarmaya çalışırken tıkandım: 500 kadar parça, her birinde tür etiketi, tempo ve enerji değeri var ama öneri üretmek için tek tek dinlemek istemiyordum. Amacım belirli bir ruh haline uyan 40 parçalık bir liste; bunu hazır bir modelle değil, elimdeki etiketlerle yapmak istedim. Ortam yerel, Python 3.11, veri ise kendi tuttuğum bir CSV dosyası.

İlk denememde her parçayı etiket vektörü olarak alıp kosinüs benzerliği hesapladım. Ama sonuçlar aynı albümden parçaları üst üste getiriyordu; tür etiketi aynı olduğu için değil, benzerliği sadece etiketlere bıraktığım için. Şu yönteme geçtim: önce etiketleri ikili (binary) hale getirdim, sonra her etiketin listede kaç kez geçtiğine göre ters frekans ağırlığı verdim. Sonra da tempo ve enerji değerlerini ayrı bir skor olarak ekledim, böylece etiket benzerliği tek başına karar vermiyor.

import csv, math
from collections import Counter

rows = list(csv.DictReader(open("parcalar.csv")))
all_tags = Counter(t for r in rows for t in r["etiketler"].split(";"))
N = len(rows)

def agirlik(t):
    return math.log((N + 1) / (all_tags[t] + 1)) + 1

def skor(a, b):
    ta, tb = set(a["etiketler"].split(";")), set(b["etiketler"].split(";"))
    ortak = ta & tb
    etiket_skoru = sum(agirlik(t) for t in ortak) / (len(ta | tb) or 1)
    tempo_fark = abs(float(a["tempo"]) - float(b["tempo"])) / 200
    enerji_fark = abs(float(a["enerji"]) - float(b["enerji"]))
    return 0.6 * etiket_skoru + 0.25 * (1 - tempo_fark) + 0.15 * (1 - enerji_fark)

Bunu 500 parça üzerinde çalıştırdığımda ilk 40 sonuç artık aynı albümden değil, farklı sanatçılardan geliyordu. Neden böyle yaptım: etiketler seyrek olduğunda düz kosinüs benzerliği popüler etiketlere yöneliyor; ters frekans ağırlığı bu eğilimi kırıyor. Tempo ve enerjiyi ayrı skor olarak eklemek, etiketlerin yakalayamadığı duygusal farkı kısmen kapatıyor. Bedeli şu: ağırlıklar elle seçildi, yani 0.6/0.25/0.15 oranı benim dinleyerek verdiğim bir karar; başka bir arşivde bu oran yanlış sonuç verebilir.

Nerede bozuluyor: etiketi olmayan parçalar (CSV’de boş alan) tüm skoru sıfırlıyor, o yüzden önce eksik etiketleri ayıklamak gerekiyor. Ayrıca tempo değeri 0 olan kayıtlar (ölçülmemiş) benzerliği yapay olarak yükseltiyor; ben bunları filtreledim. Bir de tür etiketi çok genişse, örneğin sadece “rock” yazıyorsa, ağırlıklandırma yine de yanlış eşleşme üretiyor; o durumda alt tür etiketi eklemek gerekti.

Sizin arşivinizde etiketler ne kadar tutarlı? Özellikle tempo değeri olmayan parçaları öneri listesine hiç almıyor musunuz, yoksa ayrı bir eşikle mi değerlendiriyorsunuz?

0
赞同度 100% · 0 条评论 · 2 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。