Machine Learning: Как да групираме определени песни и от тях да направим нов плейлист в Spotify? (Клъстеризация)

Автор: Десислава Христова

Случвало ли ви се е да искате да слушате определени песни в Spotify, но без да се налага да търсите готов плейлист или ръчно да си създавате такъв?

По-лесно би било ако песните автоматично се групират по определени характеристики и след това от тях да се генерират плейлисти. Това е и причината да реша да напиша тази статия.

Чрез практически пример ще ви покажа как можете да групирате песни, които слушате в Spotify, и след това да създадете от тях плейлист. За неговото решение, ще е необходим езикът за програмиране Python и някои негови библиотеки за анализ на данни и машинно обучение.

Преглед на данните

Извадката, с която ще работим, съдържа 1846 произволно избрани песни, които съм слушала в Spotify за периода 28 юни 2015 - 26 януари 2021 година. Данните са предварително изчистени и съдържат 15 числови променливи и 10 категорийни.

Можете да изтеглите файла с първоначалната обработка от тук.

5 случайно избрани реда от данните изглеждат по следния начин:

 artisttitlealbumgenreyearaddedlast_listenedlistensbpmnrgydncedBlivevalduracousspchpopadd_dayadd_monthadd_yearll_dayll_monthll_yearll_timecluster
1251Fifth HarmonySqueeze7/27 (Deluxe)dance pop20162016-09-042016-12-25 22:08:00291005864-8831213424434920162512201622:08:001
636LauvFor Now~how i'm feeling~electropop20202020-03-082020-12-29 23:12:006842353-121111189784588320202912202023:12:001
352DallasKSometimesSometimescomplextro20192020-05-082020-05-09 09:08:0011227873-73657183575085202095202009:08:000
981Sabrina CarpenterSmoke and FireSmoke and Firedance pop20162017-10-282017-10-30 07:58:00511708746-47532251954281020173010201707:58:002
638LauvSweatpants~how i'm feeling~electropop20202020-03-082020-12-29 21:22:0041604972-8157319658548320202912202021:22:000

Кои методи за машинно обучение ще използваме?

Ще приложим първо метода на главните компоненти (Principal Component Analysis - PCA), с който можем да редуцираме дименсиите и да визуализираме данните в 2D пространство, запазвайки дисперсията в извадката. След това ще клъстеризираме данните с метода k-средни (k-means clustering), за да открием групи въз основа на определени критерии за подобие на обектите.

PCA и K-means се отнасят към задачите за машинно обучение без контролна извадка и тъй като те изискват входните данни да са числа, е нужно да създадем нов DataFrame само с числови променливи.

Категорийните променливи бихме могли да ги кодираме и използваме също, но нека тях да ги оставим извън данните, за да може като формираме клъстерите, да видим какви песни са попаднали вътре в тях и по какво точно си приличат (жанр, артист или нещо друго).

5 случайно избрани реда:

 yearlistensbpmnrgydncedBlivevalduracousspchpopadd_dayadd_monthadd_yearll_dayll_monthll_year
837201881006053-7133219156126816720191772019
1392201621033953-91242676745324820162152020
7852019361606420-61034335284361112201931122019
501201831423662-728253067842416420201942020
92320159855259-91234260738716620182912020

Някои от колоните обаче са свързани с дати и не са ни полезни за групиране на песните. Тях ще ги премахнем. Нужни са ни само броя слушания на песните, различните аудио характеристики и популярността според скалата на Spotify (от 0 до 100, като 100 означава, че е много популярна песента, а 0 непопулярна).

Така остават 11 променливи, които ще използваме при прилагане на методите за машинно обучение.

5 случайно избрани реда:

 listensbpmnrgydncedBlivevalduracousspchpop
139811029246-626322020819
110862938463-4216619035619
479201097570-6127520741230
105651017079-586017516944
132211385759-7133222729519

Най-вероятно забелязвате, че стойностите в някои колони са доста по-високи от тези в други колони. Такава е например колоната с продължителност на песните (dur). Това е проблем за методите, които ще използваме, тъй като PCA се влияе много от дисперсията на променливите, а при K-means се изчисляват разстояния между обектите в пространството от характеристики. Поради тази причина е възможно да се определят тези променливи за по-важни. Нужно е данните да бъдат от еднакъв порядък, иначе получените резултати могат да бъдат с голяма грешка.

Мащабиране на променливите

Ще стандартизираме данните с помощта на StandardScaler().

Формулата, която се прилага, е следната:

Формула: StandardScaler

Формата на разпределението след трансформацията не се променя, стандартното отклонение става равно на 1, а средната стойност на всички променливи става 0.

5 случайно избрани реда:

 listensbpmnrgydncedBlivevalduracousspchpop
85-0.3714910.3060330.460492-0.8131920.0699754-0.735825-1.661481.61726-0.872762-0.6628810.210776
566-0.393265-0.289707-1.25001-2.28932-1.3653-0.658831-1.927991.465881.72132-0.502965-0.062655
1262-0.4585850.656469-0.1935230.66294-0.6476610.496083-0.3289270.532372-0.485586-0.3430490.101403
305-0.436811-0.149533-0.9984641.25339-1.72412-0.504842-0.595437-0.6282080.2113321.09620.101403
7941.784072.05821-0.193523-1.62506-0.288843-0.4278480.115257-1.687871.798765.893680.757636

Прилагане на PCA

Ще използваме метода на главните компоненти, предоставен от библиотеката Scikit-learn. Идеята, която стои зад него, е да се намали броят на използваните характеристики, но в същото време да се запази възможно най-много информация за данните. Това става като се проектират точките от пространството с характеристики върху такова с по-малка размерност така, че разстоянията да са минимални.

Новосъздадените променливи (компоненти) са комбинация от първоначалните характеристики и са такива, че връзката между тях (мултиколинеарността) е минимална, а по-голямата част от дисперсията е в първите компоненти. В нашия случай те са толкова на брой, колкото променливи има първоначално в извадката - 11. За да преценим оптималния брой компоненти, който ни е необходим, ще създадем 2 визуализации. Една стълбовидна диаграма, на която е представена дисперсията, обяснена от всеки от компонентите, и една линейна диаграма, показващата общата дисперсия при конкретен брой компоненти.

pca number of components

От графиката става ясно, че по-голямата част от дисперсията в данните е обяснена от 1-вия компонент.

pca number of components line chart

Нека поставим за критерий компонентите да съдържат над 80% от данните. Тогава оптималния брой ще бъде 7, тъй като първите 7 компонента съдържат в себе си информация за 84.36% от данните.

След това можем да преминем към прилагане на PCA.

5 случайно избрани реда от данните след PCA изглеждат по следния начин:

 0123456
3710.95619-1.204141.886340.08745640.341647-1.037410.418123
5573.99529-0.461566-0.6906720.462283-0.5515670.3726961.17407
2510.05804810.7174260.553869-1.13996-0.258895-0.492269-0.165832
71.46270.892714-0.815698-1.234310.1450450.456694-0.738249
42-0.676131.002590.9597480.297643-0.520085-0.540276-1.92545

Клъстеризация на данните с метода K-means

K-means е един често използван метод за групиране на данни в клъстери. При него се изчисляват разстояния между всеки обект до центъра на клъстера и се организират данните така, че да има голяма прилика между обектите в клъстера и малка прилика между обектите от съседни клъстери. Този метод изисква предварително да се зададе броя клъстери.

Основни стъпки на алгоритъма:

  1. инициализация на центровете на клъстерите
  2. определяне на точките с минимално разстояние до центъра на клъстера
  3. преизчисляване на центровете на клъстера
  4. точки 2-3 се изпълняват докато центровете не спрат да се изместват значително

Съществуват множество метрики за измерване на разстояние между обектите, но най-често използваните са разстоянията на:

  • Евклид:

        \[$dist_{euc} = \sqrt{\sum^N_{j=1}(x_{aj} - x_{bj})^2}$\]

  • Манхатън:

        \[$dist = \sum^N_{j=1}|x_{aj} - x_{bj}|$\]

Какъв е оптималният брой клъстери?

За да отговорим на този въпрос ще създадем една линейна диаграма, която показва изменението на отдалечеността на точките вътре в клъстерите (inertia) в зависимост от броя клъстери.

optimal number of clusters

Оптималният брой клъстери според визуализацията е 3 или 4, защото след това наклонът на кривата става по-плавен и при по-големите бройки клъстери разликата в стойностите за отдалечеността на точките вътре в клъстерите е по-малка. Ние ще групираме данните в 3 клъстера обаче, тъй като по време на тест на алгоритъма с единия и след това с другия брой, при 4 клъстера не се получиха толкова добри резултати.

След като сме определили на колко групи да се разделят данните, можем да продължим нататък с прилагане на метода за клъстеризация. Ще използваме KMeans(), предоставен от библиотеката Scikit-learn.

След прилагане на KMeans(), всяка от песните в извадката е разпределена в един от 3 клъстера в зависимост от нейните характеристики.

Резултати и създаване на плейлист

За да представим получените резултати от групирането на песните, ще създадем 2 визуализации.

scatter matrix

Първата включва множество диаграми на разсейването, показващи връзката между отделните компоненти. На нея можем да видим с различни цветове клъстерите и да изберем тези 2 компонента, при които те са разделени най-ясно. В този случай това са 1 и 3.

cluster scatter

На тази графика се вижда по-ясно как са разделени песните. Размера на точките е на базата на популярността на конкретната песен. Колкото по-големи са, толкова песента е по-популярна.

Създадените клъстери са следните:

  • Клъстер 0 (Син клъстер) е със 716 песни, предимно такива, които са енергични, бързи и весели, най-вече от жанра k-pop.
  • Клъстер 1 (Розов клъстер) включва 417 песни, които са най-вече от жанра инди и са бавни и тъжни.
  • Клъстер 2 (Жълт клъстер) има 713 песни, предимно такива, на които може да се танцува, предназначени за клубове. Най-много песни в този клъстер са от жанр dance pop и electropop.

От тук нататък можем от всеки клъстер да извадим определен брой песни и да ги запазим във файл с разширение .csv, след което да използваме онлайн платформа като Soundiiz, за да импортираме плейлист в Spotify.

10 случайно избрани песни от Клъстер 0:

 titleartistalbum
1222Don't Wanna Dance AloneFifth HarmonyBetter Together
1630VVITHNU'ESTQ IS.
472Drove You AwayFly By MidnightHappy About Everything Else…
1115RUMORKARDK.A.R.D Project Vol.3 "RUMOR"
1098Your SongRita OraYour Song
1248The LifeFifth Harmony7/27 (Deluxe)
1749The Art Of BreakingThousand Foot KrutchDeja Vu: The TFK Anthology
1176Oh NaNa (Hidden. HUR YOUNG JI)KARDK.A.R.D Project Vol.1 "Oh NaNa"
1650Broken HeartAfter SchoolPLAYGIRLZ
1582Will You Be AlrightBeastHard To Love, How To Love

За да е успешно импортирането на плейлиста в Soundiiz, е необходимо csv файлът ни да съдържа само колоните заглавие (title), изпълнител (artist) и албум (album), а разделителят да е точка и запетая (semicolon).

Като извод можем да кажем, че групирането на песните се е получило доста добре, макар да има и такива, които се различават от останалите в съответния клъстер, но в повечето случаи наистина си приличат. Резултатите от клъстеризацията могат да бъдат подобрени като се правят множество експерименти с различни стойности на параметрите на KMeans().

Цялостния пример можете да изтеглите от тук.

Искате да научите повече за Python?

Включете се в курса по програмиране с Python.

© Copyright 2019 DeviseExpert Всички права запазени
envelopephone-handsetmap-marker linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram