Przez losowy las Spotify

Czy machine learning może pomóc w poszukiwaniu ulubionej muzyki?

Dzisiaj zajmiemy się poszukiwaniem nowej muzyki. Już kiedyś o tym było w oparciu o LastFM, dzisiaj będzie w oparciu o Spotify. Taki szybki wpis.

Na początek potrzebujemy kilku elementów:

  • własnej aplikacji współpracującej z API Spotify – zbudować ją można zaczynając z dashboardu Spotify, potrzebujemy numerku client_id i client_secret
  • te numerki wpisujemy do zmiennych o tych samych nazwach i zapisujemy sobie lokalnie (żeby nie przechowywać ich w kodzie) w pliku spotify_cred.rda. W bardzo prosty sposób: save(client_id, client_secret, file = "spotify_cred.rda")
  • następnie budujemy kilka funkcji, których będziemy używać. Kod jest długi, nie warto go tutaj zamieszczać – znajdziecie go na GitHubie (swoją drogą jest tam nieco więcej funkcji niż potrzeba, ale nie wszystkie skończone i działające)

Uzbrojeni w taki zestaw zaczynamy od pozyskania tokenu:

Kolejny krok to już praca ręczna – musimy przygotować sobie dwie listy, które posłużą do nauki modelu. Jedna z nich to lista zawierająca piosenki, które lubimy; druga – których nie lubimy. Ja skorzystałem z jakichś gotowych list. Dobrze byłoby gdyby listy były długie (dużo danych) i mniej więcej równej długości.

Trzecią listą jest lista testowa – to dla piosenek z tej listy będziemy określać czy nam się spodobają czy nie. Może to być na przykład coś z zestawień rocznych Spotify albo jakaś inna lista.

Mając takie listy zapisujemy sobie ich parametry:

Skąd wziąć te parametry? Z jej adresu URL:

gdzie:

  • czerwone to nazwa użytkownika
  • niebieskie to ID listy

Teraz możemy rozpocząć analizę – na początek pobierzemy utwory z playlisty lubię:

a także z playlisty nie lubię:

Łączymy obie listy (ulubionych mamy 260 utworów, nielubianych 305) z jednoczesnym oznaczeniem z której pochodzi konkretny utwór:

Mamy pełną listę 545 utworów (unikalnych; stąd suma 545 mniejsza niż suma dwóch list 260 + 305 = 565). Model oparty będzie na cechach utworów (ich opis znajdziecie w jednym z poprzednich wpisów), pobierzmy je więc ze Spotify:

To mogłoby wystarczyć, ale połączmy cechy z tytułami utworów (i ich wykonawcami oraz albumami z jakich pochodzą):

Mamy komplet, możemy sobie pooglądać jak różnią się cechy piosenek lubianych i nie:

Widzimy, że największe różnice występują dla cech: danceability (lubię te, które są mniej taneczne), energy (wolę bardziej energetyczne), loudness (wolę cichsze), tempo i valence (lubiane są bardziej pozytywne – mniejsza wartość = większa pozytywność). Właściwie te pięć cech powinno wystarczyć dla naszego modelu.

Użyjemy jednak wszystkich, a model będzie typu lasu losowego dla klasyfikacji. Zbudowanie go w R jest banalne:

Widzimy, że błąd klasyfikacji to około 18% (na danych uczących). Dość dużo. Zobaczmy jak zmienia się błąd w zależności od liczby drzew w lesie:

  • czarne to błąd łączny
  • zielone – błąd dla utworów klasyfikowanych jako lubiane
  • czerwone – błąd dla utworów klasyfikowanych jako nielubiane

Sprawdźmy które cechy mają największe znaczenie:

W większości pokrywa się to z tym, co wywnioskowaliśmy z wykresów rozkładu cech powyżej.

Przeprowadźmy teraz klasyfikację na nieznanym zbiorze – czyli bierzemy playlistę testową:

pobieramy cechy utworów z tej listy:

i przewidujemy czy utwory będą się podobać czy nie:

Dla czytelności obrazu łączymy przewidywania z tytułami piosenek:

Wszystkie 115 utworów nasz model podzielił:

nie lubię lubię
83 34

Na koniec przygotujmy wykresy tak jak na początku – rozkład cech utworów lubianych, nie lubianych i przewidzianych do lubienia oraz nielubienia. Łączymy więc wszystkie dane znane (listy lubię i nie lubię) oraz dane testowe:

I rysujemy sobie wykresik:

Wyraźne podobieństwo przewidywań i rzeczywistości widać dla cech energy, loudness. Jeśli uśrednimy wartości dla poszczególnych kategorii:

można zauważyć granice pomiędzy lubię i nie lubię:

  • acousticness w okolicach 0.13 (mniejsze lubię)
  • danceability – 0.58 (mniejsze lubię)
  • energy 0.7 (większe lubię)
  • loudness -8 (większe, czyli bliższe zera – lubię)
  • valence na poziomie około 0.5 lubię, inne – nie

To znaczne uproszczenie, prowadzące właściwie do modelu drzewa (zamiast lasu drzew).

Kolejnym krokiem może być zbudowanie nowej listy (da się to zrobić przez API), dodanie do niej utworów, które powinny się podobać i… przesłuchanie jej. Ciekawe jak się sprawdzi? Wszystko zależy od tego jak bardzo różnorodnej muzyki słuchacie i jak bardzo różnorodne są playlisty uczące.

Dodaj komentarz