Как и многие люди, в наши дни я чаще всего слушаю музыку через Spotify. Одна из моих любимых функций - плейлист Discover Weekly, плейлист, который Spotify алгоритмически создает для всех своих пользователей, который он описывает как еженедельный обзор песен, которые, как мы думаем, вам понравятся. Я могу только предположить, что это сочетание машинного обучения и магии вуду. Каждую неделю в моем Discover Weekly всегда есть несколько песен, которые мне нравятся; и когда я нахожу эти песни, я сохраняю их в своей библиотеке Spotify.

В этом и заключается проблема. В отличие от некоторых людей, которые тщательно хранят свою сохраненную музыку и помещают ее в тщательно составленные плейлисты, я просто сваливаю все в общий раздел «Сохраненные» в моем Spotify. Со временем эта неорганизованная куча музыки выросла до прилично больших (330 песен на момент написания). В результате я не очень часто пересматривал эти сохраненные песни. Вы можете подумать: «Черт возьми, Сэм, зачем тебе сохранять песни, если ты не вернешься и не послушаешь их позже?» Отличный вопрос, я сам задавался этим вопросом и пришел к выводу, что пройти через них просто слишком сложно (в некотором роде несущественные проблемы первого мира).

Мои музыкальные вкусы охватывают множество жанров, и то, что я хочу послушать в любой момент, во многом зависит от моего настроения. Так что я не могу просто перетасовать все свои сохраненные песни, поскольку все они принадлежат к разным жанрам, игривое к-поп Awoo звучало бы просто странно, если бы сразу же за ним последовала жесткая Drunk Drivers в подголовнике автокресла. /Косатки"." Итак, если я собирался слушать свои сохраненные песни, мне нужно было сначала организовать их по настроению. Но не вручную, у меня нет на это терпения.

К счастью, группирование множества вещей (в данном случае песен) в похожие группы без особого участия человека - это хорошо изученный тип проблемы машинного обучения, известный как кластеризация. Так что я, луддит по машинному обучению, могу воспользоваться этим исследованием, даже не зная, что я делаю, ура!

Метод кластеризации, который я решил использовать, называется k-means clusterin g, в первую очередь потому, что это один из немногих алгоритмов кластеризации, которые я понимаю. Чтобы использовать k-средство, вам нужно взять материал, который вы кластеризуете, и каким-то образом превратить его в точки. Вы можете представить, что эти точки находятся в знакомой двумерной декартовой плоскости, но это также работает для вещей в пространствах более высоких измерений. После того, как все ваши данные были превращены в баллы, вы можете решить, сколько разных кластеров вы хотите, k. Затем K-means работает, чтобы найти k центроидов (причудливое название для большего количества точек), так что каждая из ваших точек заполнения близка к одному из этих центроидов. Эти центроиды определяют k различных кластеров, и каждая из точек принадлежит кластеру, определенному ее ближайшим центроидом.

Например, на приведенном выше изображении все цветные точки представляют собой объекты, которые объединяются в кластеры, выбранный k равен 5, а центроиды, найденные алгоритмом, даны пятью символами плюс. Точки окрашены в соответствии с кластерами, которым они были назначены, и вы можете увидеть, как цвет определяется просто ближайшим знаком плюс.

Итак, с выбранной конкретной техникой кластеризации мне нужно было найти способ превращать песни в точки. К счастью, Spotify предоставляет отличную информацию обо всех своих песнях через API через то, что он называет аудиофункциями. Это означает, что любой, обладающий достаточным пониманием программирования, может спросить Spotify, как он оценивает танцевальность, инструментальность данной песни или множество других функций (всего 13), каждая по числовой шкале. Другими словами, Spotify уже проделал за меня всю тяжелую работу! Мне просто нужно было написать правильный код, и все мои сохраненные песни будут преобразованы в точки, по которым я мог бы выполнить некоторую кластеризацию.

Вот скрипт Python2, который я использовал для извлечения моих сохраненных песен Spotify и преобразования их в 13-мерные точки на основе звуковых функций:

Как только все мои песни были превращены в точки, я применил масштабирование к каждому из различных измерений. Как упоминалось выше, k -means работает, пытаясь приблизить все ваши точки к центроиду. Эта близость измеряется евклидовым расстоянием (также известным как расстояние по прямой) между точками и центроидом. Однако не все разные показатели Spotify - это одни и те же единицы. Например, акустичность песни - это число от 0 до 1, а длительность - это длина в миллисекундах.

Предположим, у нас есть два центроида: центроид A с акустичностью 1 и длительностью 150 000 и центроид B с акустичностью 0 и длительностью 180 000; Теперь предположим, что мы хотим классифицировать песню с акустичностью 1 и длительностью 180 000, как бы она была классифицирована? Без масштабирования он был бы классифицирован в группу, определенную B, потому что это расстояние всего 1 по сравнению с расстоянием ~ 30 000 от центроида A. Но это не совсем то, что мы хотим, две песни могут звучать очень похоже, но могут быть классифицированы по разным кластерам только потому, что длина различается на гораздо большую величину, чем акустика.

Вот почему я решил применить масштабирование к каждому из измерений. Хотя продолжительность может указывать на музыкальное сходство / различие между песнями, я не хочу, чтобы она была более взвешенной, чем другие звуковые функции, предоставляемые Spotify. Масштабирование борется с этим, растягивая и сдвигая каждое из измерений, так что стандартное отклонение каждого измерения масштабируется до 1. В результате «далеко» в одном измерении будет иметь такой же вес, как «далеко» в другом измерении. В данном примере центроиды A и B могут быть масштабированы до (1, 0,5) и (0, 0,6) соответственно, и песня будет правильно отнесена к группе A.

После масштабирования данных мне нужно было точно выбрать, сколько плейлистов объединить в их кластер (значение k из k- означает). Обычно это делается с помощью метода локтя, когда вы наносите оценку модели в зависимости от количества используемых кластеров и выбираете k на изгибе результирующей кривой. Это тот момент, когда вы не получите особой выгоды от добавления еще одного кластера. Для k от 1 до 20 моя кривая локтя выглядит так:

Выбор «локтя» не является точной наукой, но я чувствовал, что 8 - это хорошее количество кластеров, чтобы выбрать здесь, поскольку кривая, кажется, немного сглаживается на уровне k = 8 или около того. Опять же, это не точная наука, поэтому ваша интерпретация «локтя» здесь может отличаться от моей.

Наконец, после преобразования песен в точки, масштабирования этих точек и выбора k я фактически запустил алгоритм кластеризации и составил несколько списков воспроизведения. Вот код для этого:

Вот и все! После некоторой игры с Python, API Spotify и некоторого машинного обучения я смог автоматически отсортировать все мои сохраненные песни в 8 плейлистов. После кластеризации осталось только посмотреть, как все закончится! Во-первых, я посмотрел, какие плейлисты думает алгоритм машинного обучения создает. Ниже приведены положения центроидов кластера вместе с моими интерпретациями на английском языке и их URL-адресами Spotify:

Sad, long, and not dance-friendly
https://open.spotify.com/user/busta_sam/playlist/6ZJJODF1pjqb38ZKqlTTZs
Cluster 0 Notable features:
 danceability, -0.95694986003
 duration_ms, 0.544439790449
 valence, -0.840971014255
Happy songs!
https://open.spotify.com/user/busta_sam/playlist/0YMxnPxCG1cZJ5wzHnYrFi
Cluster 1 Notable features:
 mode, 0.941123948114
 valence, 0.530923079802
Happy, fast, but not very dance-friendly
https://open.spotify.com/user/busta_sam/playlist/6BCTnirU2CmuwJEprtZiJd
Cluster 2 Notable features:
 danceability, -0.573985772103
 mode, 0.607176740719
 tempo, 0.778386767955
 time_signature, -3.83668296263
Spoken and acoustic
https://open.spotify.com/user/busta_sam/playlist/7rFIvmvwgiWAknACRfO8Ac
Cluster 3 Notable features:
 acousticness, 0.669727246281
 speechiness, 1.99285951664
Happily danceable (in a minor key)
https://open.spotify.com/user/busta_sam/playlist/2cxDneFEaMmHVSDOj8eapw
Cluster 4 Notable features:
 danceability, 0.576201357609
 mode, -1.06255929626
 valence, 0.637916077744
PUMP UP THE JAMS (loud and energetic)
https://open.spotify.com/user/busta_sam/playlist/0hZ9AB5AqoYkyGa0ruMsJj
Cluster 5 Notable features:
 energy, 0.597173537605
 key, 0.566320654055
 liveness, 3.01315791229
 loudness, 0.52168852663
Brooding and acoustic
https://open.spotify.com/user/busta_sam/playlist/57tJKMxhO82CXHZGmQ0v0s
Cluster 6 Notable features:
 acousticness, 1.67149563594
 energy, -1.43324770625
 loudness, -1.68301335212
 tempo, -0.600891338119
 valence, -0.559252321609
Brooding without the lyrics
https://open.spotify.com/user/busta_sam/playlist/0xiUTbk9RyG9TfbwR3pMDo
Cluster 7 Notable features:
 instrumentalness, 3.29017349386
 loudness, -0.615010549014
 valence, -0.840608500109

Итак, в конце концов, получилось ли это приключение в мир науки о данных? В каком-то смысле не совсем. Хотя я могу отчасти видеть, какие настроения кластеры пытаются имитировать, я не думаю, что плейлисты, созданные этим методом, могут соперничать с теми, которые люди создают вручную. Однако это не было полным провалом. Эти плейлисты, безусловно, лучше той огромной кучи песен, которую я использовал ранее. Кроме того, я много слушал эти плейлисты, чтобы попробовать и оценить их, и в процессе заново открывал для себя потрясающую музыку. Что, в конце концов, и было конечной целью этого проекта.