Spotify提供Duo订阅服务,并附带名为Duo Mix的独特播放列表。这个播放列表应该是结合用户的音乐品味生成的。

我们都很想知道这个播放列表到底是怎么回事。我们开始听,但不知怎么的感觉有点不对劲,歌手是“正确的”,但歌曲不是,播放列表几乎没有我们俩都听过的歌。

于是我们不再听每周播放列表中的更新。然而我喜欢这个想法,认为一定有一种方法可以创建我们都希望的播放列表。

所以我决定自己创建一个播放列表,但不是手动创建,因为我想每周更新。我首先想到使用机器学习或其他方法。

我的目标是:

  • 添加一些我们一直都喜欢的,以及最近都喜欢的歌曲
  • 根据这些热门歌曲搜索并加入新歌
  • 限制一个歌手的歌曲数量
  • 创建一个基于共同喜欢的音乐的整体聆听体验,而不仅仅是提供一个人的个人品味

我最终找到了一个有效的解决方案,而且还没有使用机器学习,它实际上只是一些数据操作,通过相似性度量对Spotify的推荐进行一些改进,再加上一点随机性。

这个解决方案是有效的,到目前为止,我们对播放列表很满意,并将继续改进它,也许是使用机器学习。如果有关于我们喜欢和不喜欢的歌曲的数据,一个训练有素的模型就可以改善。

准备创建播放列表

获得数据

我首先使用已经创建的Spotify应用程序,并通过应用程序验证我们的账户。如果你不确定如何做这些事情,请查看这篇文章,它将引导你完成这个过程: https://towardsdatascience.com/using-python-to-refine-your-spotify-recommendations-6dc08bcf408e

首先,我为我们两人查询了以下数据:

  • 热门艺术家
  • top并且包括长期、中期和短期的曲目
  • 以及一些保存的用户曲目(最后的50条)

我使用了下面的函数,它实际上只是组合了一组查询并生成三个数据帧。

defget_dfs(sp):##查询#用户热门曲目top_tracks_short=sp.current_user_top_tracks(limit=50,offset=0,time_range='short_term')top_tracks_med=sp.current_user_top_tracks(limit=50,offset=0,time_range='medium_term')top_tracks_long=sp.current_user_top_tracks(limit=50,offset=0,time_range='long_term')#组合top_trackstop_tracks_short_df=append_audio_features(create_df_top_songs(top_tracks_short),sp)top_tracks_med_df=append_audio_features(create_df_top_songs(top_tracks_med),sp)top_tracks_long_df=append_audio_features(create_df_top_songs(top_tracks_long),sp)#从长期热门歌曲中选取样本,以引入更多随机性,避免使用相同的艺术家top_tracks_long_df=top_tracks_long_df.sample(n=15)top_tracks_df=pd.concat([top_tracks_short_df,top_tracks_med_df,top_tracks_long_df]).drop_duplicates().reset_index(drop=True)#热门艺术家top_artists_long=sp.current_user_top_artists(limit=50,time_range="long_term")top_artists_med=sp.current_user_top_artists(limit=50,time_range="medium_term")top_artists_short=sp.current_user_top_artists(limit=50,time_range="short_term")artists_short_df=top_artists_from_API(top_artists_short)artists_med_df=top_artists_from_API(top_artists_med)artists_long_df=top_artists_from_API(top_artists_long)artists_df=pd.concat([artists_short_df,artists_med_df,artists_long_df])artists_df["genres"]=artists_df["genres"].apply(lambdax:",".join(x))artists_df.drop_duplicates().reset_index(drop=True)#用户保存的曲目user_saved_tracks=sp.current_user_saved_tracks(limit=50)saved_tracks_df=create_df_saved_songs(user_saved_tracks)returntop_tracks_df,artists_df,saved_tracks_df

请注意,我在这里调用的函数将Spotify API查询结果转换为一个可用的数据帧。我不会在这里一一介绍它们的细节。

另一篇关于Spotify的文章中提到了一些。你可以在Github上找到完整的代码(参见spotifuncs.py):

https://github.com/MerlinSchaefer/spotify_app

第一个重要的数据是用户的所有热门歌曲,我将它们组合成一个完整的热门歌曲列表,涵盖了从短期到长期喜爱的所有内容。

请注意,我只从长期热门歌曲中抽样了15首歌曲,并且这样做时没有设置一个随机种子,以避免每次运行代码时都得到相同的结果。在这个过程中总是使用长期喜欢的完整列表会导致播放列表重复太多。

第二个重要的部分是热门艺术家的数据,就像所有时间帧的曲目检索一样。艺术家对于后面的过滤过程很重要。

最后,我还在检索用户保存的最新50首歌曲。50是上限,这很不好,因为限制了数据的使用。

最后几周播放列表

为了避免连续两周遇到同样的歌曲(短期和中期热门歌曲很可能不会有太大变化),上周的播放列表从“playlist .csv”读取。

第一次运行代码时,这个文件只是一个空的.csv文件。但是在创建播放列表过程的最后,新创建的播放列表被保存在.csv文件中,因此它包含上周的播放列表。我在这个过程的不同阶段使用.csv文件中的数据为新的播放列表过滤歌曲。

建立播放列表

创建播放列表需要几个步骤来“组装所有组成它的构件”。这些是:

  1. 上周没有出现在播放列表中的常见的热门歌曲;
  2. 每个用户的热门歌曲与其他用户的热门歌曲最相似的样本;
  3. 每个用户最喜欢的歌手(他们最喜欢的歌手之一)的歌曲样本;
  4. 用户保存的歌曲样本;
  5. 推荐曲目(通过Spotify API和额外的过滤),我们为每一个曲目执行步骤1 -4过滤后再添加到播放列表。