Введение
Spotify, одна из самых известных платформ для потоковой передачи музыки, является моим самым часто используемым приложением в повседневной жизни. Будучи меломаном, я создал более десяти плейлистов в таких жанрах, как поп-музыка, хип-хоп, рок и джаз. Тем не менее, я всегда оказывался со своим плейлистом на мандаринском языке, когда мне больше всего нужна была музыка. Однажды я случайно наткнулся на документы Spotify Web API и был очарован функциями звука, которые отслеживает Spotify. На следующем изображении показан ответ аудиофункций при вызове Get /audio-features.
Подробнее о каждом параметре см. Справочник по API.
Мое внимание привлек еще один параметр — популярность.
Для меня популярность сравнительна. Однако Spotify измеряет популярность каждого трека в цифрах. То, как Spotify отслеживает каждый аспект музыки, от популярности исполнителя до громкости трека в виде данных, дало мне новый взгляд на музыку. Это заставило меня задуматься, а можно ли создавать золотые треки исключительно по характеристикам других популярных треков? Чтобы узнать ответ на этот вопрос. Я решил глубже погрузиться в то, как музыка и данные взаимодействуют. Но сначала нам нужно выяснить, что делает трек популярным. В этой статье я сосредоточусь только на том, как звуковые характеристики влияют на популярность песни.
Прежде чем начать этот эксперимент, я просмотрела Интернет, чтобы узнать, выполнял ли кто-нибудь еще подобное упражнение. Есть и другие эксперименты по предсказанию популярности песни по звуковым характеристикам, например, эта статья. Набор данных, использованный в этой статье, был взят из Kaggle. Тем не менее, я хотел бы сосредоточиться на песнях на китайском языке, а у Kaggle нет набора данных о популярности песен на китайском языке. Поэтому я извлек набор данных Spotify вручную из веб-API Spotify.
Извлечение/исследование данных
В качестве набора данных я собрал 3000 атрибутов песен в жанре «мандо-поп» с 2019 по 2022 год. Сначала я получаю токен Bearer из консоли Spotify Web API для целей аутентификации.
auth_token = "BQAbNoApNP48x6r_2G5qfAUFXzgEUIqpUxhYZx7WpETfpg77wXdzpxgkXYdQaIx9MqmnfKzGq3o0Om3O4F2JwBRORPJK-GwxbswcKg66Wf-7x5blrDWKy8CUmC-_eDZ4BjQTFZDV2Z9W1rsNbj1zlmK179d8SyuyXzkyAMFP96n3J2Nc" headers = { 'Authorization': 'Bearer {token}'.format(token=auth_token) }
Затем я создал список из 3000 идентификаторов песен, по 1000 в год, с помощью веб-API Spotify. Затем я извлекаю атрибуты песен из этого списка с помощью Spotify Web API.
Давайте углубимся в данные, которые я только что извлек.
Для данных информация о песне, которые я извлек:
- Идентификатор песни (идентификатор дорожки в Spotify) Название дорожки (название дорожки)
- ID основного исполнителя (ID основного исполнителя Spotify)
- Имя исполнителя (имя главного исполнителя)
- Название альбома (Альбом, в котором появляется трек)
Для данных атрибутов песни, которые я извлек:
- Популярность трека (популярность трека. Значение будет от 0 до 100, где 100 — самый популярный)
- танцевальность (значение 0,0 соответствует наименее танцевальной способности, а 1,0 — наиболее танцевальной)
- энергия (Энергия представляет собой меру от 0,0 до 1,0 и представляет перцептивную меру интенсивности и активности)
- ключ (тональность, в которой находится дорожка. Целые числа сопоставляются с высотой звука с использованием стандартной нотации класса высоты тона. Например, 0 = C, 1 = C♯/D♭, 2 = D и т. д. Если тональность не обнаружена, значение равно - 1)
- громкость (общая громкость дорожки в децибелах (дБ). Обычно значения находятся в диапазоне от -60 до 0 дБ)
- режим (режим указывает модальность (основной или второстепенный) дорожки. мажор представлен 1, а минор - 0)
- Речевость (Речь определяет присутствие произнесенных слов в дорожке. 1.0 — наиболее речеподобный, 0.0 — наиболее неречевой)
- акустика (1,0 означает высокую степень уверенности в том, что трек является акустическим, а 0,0 означает высокую уверенность в том, что трек не является акустическим)
- инструментальность (предсказывает, не содержит ли трек вокала. 1.0 означает, что трек не содержит вокала)
- Живость (Обнаруживает присутствие аудитории в записи. Более высокие значения живости представляют собой повышенную вероятность того, что трек был исполнен вживую)
- валентность (показатель от 0,0 до 1,0, описывающий музыкальную позитивность, передаваемую треком. Треки с высокой валентностью звучат более позитивно (например, счастливый, веселый, эйфорический), а треки с низкой валентностью звучат более негативно (например, грустный, подавленный, злой))
- темп (общий предполагаемый темп трека в ударах в минуту (BPM))
- duration_ms (длительность трека в миллисекундах)
- time_signature (Предполагаемый тактовый размер. Размер варьируется от 3 до 7, что указывает размер от «3/4» до «7/4»)
Как я упоминал ранее, мы сосредоточены только на том, как атрибуты песни (сгенерированные алгоритмом Spotify) взаимодействуют с ее популярностью. Поэтому информация о песне для этого проекта будет удалена.
df = df.drop(columns=['track_id','track_name','artist_id','artist_name','album'])
Хотя все остальные столбцы являются числовыми значениями, некоторые из них являются непрерывными переменными, такими как энергия, которая представляет собой меру от 0,0 до 1,0 и представляет перцептивную меру интенсивности и активности. Некоторые из них представляют собой дискретные переменные, такие как клавиши, с целыми числами, сопоставленными с высотой тона с использованием стандартной нотации класса высоты тона. Есть одна категориальная переменная — mode. Для этого проекта я решил использовать регрессионные модели. Другими словами, непрерывные и дискретные переменные не нуждаются в дополнительной предварительной обработке. Для mode,который содержит только 0 и 1, его не нужно фиктивировать.
Я использовал StandardScaler, чтобы удалить среднее значение и масштабировать каждую переменную до единичной дисперсии для track_popularity, key и mode из-за их значительной дисперсии.
need_scale_df = df.drop(columns=['track_popularity', 'key', 'mode']) scale = StandardScaler() df_scaled = pd.DataFrame(scale.fit_transform(need_scale_df), columns=need_scale_df.keys())
Давайте проведем небольшое исследование данных! Сначала я нарисовал и описал распределение нашего значения Y — track_popularity.
sns.displot(data=final_data['track_popularity'], kind='kde', palette='cool', height=5, aspect=1.4).set(title='Track Popularity Distribution')
Распределение пика track_popularity составляет около 20 и смещено вправо. Другими словами, набор данных несбалансирован.
final_data['track_popularity'].describe()
Затем я построил тепловую карту корреляций между переменными.
plt.figure(figsize=(20, 10)) sns.heatmap(final_data.corr(),annot = True)
На этой тепловой карте мы не видим каких-либо четких указаний на сильную корреляцию между track_popularity и другими переменными. Давайте лучше посмотрим на значение корреляции каждой переменной с помощью track_popularity.
abs(final_data.corr()['track_popularity']).sort_values()
Я решил отбросить переменные со значением абсолютной корреляции ниже 0,05, чтобы убрать шум и повысить точность моделей.
Теперь, когда исследование данных и разработка признаков завершены, я продолжу обучение моделированию в Части 2.
Вот блокнот Python для этого проекта.