在 Spotify 上找到我最喜欢的新歌
设置环境
分析我的播放列表曲目
将我的播放列表与该类型的样本进行比较
创建包含我可能喜欢的歌曲的新播放列表
结论和未来步骤
当我在开发时(或者只是在我上下班途中)我通常喜欢听一些摇滚音乐。
我在 Spotify 上创建了一些播放列表,但最近我还是坚持用同一个,里面都是我最喜欢的“独立摇滚”歌曲。
这个播放列表收录了大约 45 首我这些年来通过各种方式发现的歌曲。
由于我开始厌倦总是听同样的歌曲,上周末我决定使用 Spotify API 分析我的播放列表,以便发现见解并希望找到一些我可以添加的新曲子。
以下是我用大约 300 行 Python 3 代码(包括样板代码)实现的功能。
你可以在GitHub上找到包含我所用代码的 Jupyter Notebook。
设置环境
为了进行分析,我设置了一个包含以下库的 Python 3 虚拟环境:
为了访问 Spotify API,我注册了我的应用程序,然后向 spotipy 库提供了 client_id、client_secret 和重定向 url。
分析我的播放列表曲目
在第一次 API 调用获取我的播放列表 ID后,我通过另一次API 调用获取了我的播放列表的所有曲目以及一些基本信息,例如:歌曲 ID、歌曲名称、艺术家 ID、艺术家姓名、专辑名称、歌曲受欢迎程度。
通过另一个API 调用,我获得了有关播放列表中的艺术家的一些额外信息,例如流派和 artist_popularity。
最后,通过另一个API 调用,我获得了一些有关我的轨迹的深刻信息:
- duration_ms:轨道的持续时间(以毫秒为单位);
- acousticness:描述歌曲的声学效果(1 => 高置信度,表示曲目具有声学效果)。取值范围为 0 到 1;
- danceability:描述歌曲的舞蹈性(1 => 高置信度,表示该曲目适合跳舞)。取值范围是 0 到 1;
- 能量:它是强度和活跃度的感知度量(例如,死亡金属能量高,而古典音乐能量低)。其范围从 0 到 1;
- 乐器性 (instrumentalness):预测曲目是否不包含人声(1 => 高置信度,表示曲目不含人声)。取值范围为 0 到 1。
- 现场感:检测录音中是否有观众(1 => 高置信度,表示曲目为现场)。取值范围为 0 到 1;
- 响度:检测曲目的整体响度(以分贝为单位)。范围从 -60dB 到 0dB;
- valence:描述曲目所传达的音乐积极性(1 => 更积极,0 => 更消极)。取值范围为 0 到 1;
- 语音性:检测音轨中是否存在语音(1 => 语音,0 => 非语音,仅音乐)。取值范围为 0 到 1;
- key:描述歌曲的音高类别符号。范围从 0 到 11;
- mode:曲目的调式(0 => 次要,1 => 主要);
- 节奏:曲目的总体估计节奏,以每分钟节拍数(BPM)为单位;
- time_signature:曲目的估计整体时间签名(每个小节或小节有多少个节拍)。
为了简化数据分析,所有这些调用的结果都已放入 Pandas 数据框中,然后使用艺术家 ID 和曲目 ID 合并到单个数据框中。
部分值(例如歌曲/艺术家的流行度和节奏)已进行标准化。
探索性数据分析
在确保我的播放列表中的艺术家全部包含“独立摇滚”作为流派后,我看到(使用完整数据框的形状、信息和描述)我的播放列表由 46 个条目组成,包含具有以下统计数据的所有非空值:
然后我使用 Seaborn 创建了一些图表(distplot、countplot、boxplot):
所有这些图表都表明,我喜欢那些声学/乐器/语音性低、能量/响度/节奏高、艺术家知名度高且时长在200秒左右的歌曲。
效价和歌曲知名度的跨度很大,这意味着我的播放列表中既有知名的歌曲,也有不知名的歌曲,既有好评的歌曲,也有差评的歌曲。
但是我的播放列表与独立摇滚流派相比如何?
将我的播放列表与该类型的样本进行比较
我使用“genre:"Indie Rock"”作为关键词,并使用“type=tracks”调用了一些搜索 API
,以获取独立摇滚流派的样本(共 5000 首歌曲)。 此 API 还提供了一些不错的关键词,例如“tag:hipster”(仅获取热度最低 10% 的专辑)或“year:1980-2020”(仅获取特定年份范围内发行的曲目)。
然后,我对当前播放列表和独立摇滚样本重复了相同的分析,得到了以下图表:
图表显示我的播放列表与 5000 首独立摇滚歌曲不同,因为:
- 我喜欢较短的歌曲
- 我喜欢能量/响度/节奏更高的歌曲
- 我不喜欢情绪太消极的歌曲(效价 > 0.3)
- 我喜欢的歌曲大多是 (0, 1, 6, 9) 调的
创建包含我可能喜欢的歌曲的新播放列表
利用这些见解,我对 5000 首歌曲数据框应用了一些过滤器,以便只保留我可能喜欢的曲目;对于每个步骤,我都记录了删除的歌曲以仔细检查过滤器行为。
显然,我应用的第一个过滤器是删除我原始播放列表中已有的歌曲。
其他过滤器包括:
- 声学性能 < 0.1
- 能量>0.75
- 响度> -7dB
- 价态在 0.3 和 0.9 之间
- 节奏 > 120
- 输入(0, 1, 6, 9)
- 时长介于原始播放列表时长的 10% 四分位数和 90% 四分位数之间(178 秒和 280 秒)
最后我得到了一个包含 220 首曲目的数据框,并使用API 调用创建了一个新的播放列表
结论和未来步骤
听了几天的新播放列表后,我对结果非常满意,并且已经将一些曲目推广到我原来的播放列表中。
这种“推荐”方法非常简单,可能只在特定用例(即特定类型的可明确定义的子集)下有效。Spotify
的标准推荐方法显然要好得多,因为除了音频分析之外,它还结合了协同过滤模型(分析你和他人的行为)和自然语言处理 (NLP) 模型(分析歌曲文本)。
后续步骤:
- 几个月后再次运行分析,以便将我的播放列表中的新条目和 5000 个样本中的新歌曲考虑在内
- 使用 Spotify API(例如音频分析端点或其他服务)来丰富我已经获得的信息。例如,检测曲目中的乐器(吉他??)或某些特征的存在,例如失真、重复乐段等,会很好。
- 使用 API 中的预览示例,在 5000 首歌曲的子集上手动标记我喜欢/不喜欢的内容,然后运行一些 ML 算法来对我喜欢的音乐进行分类
- 使用一些 ML 算法更深入地分析我的播放列表(例如对我的曲目进行聚类)