用Python创建音乐推荐系统,下一个“网易云音乐”创建者就是你!


推荐系统无处不在,而且在整个网络上都是非常标准的。亚马逊、Netflix和许多这样的公司都在使用推荐系统。我们将要构建的这个版本与Spotify或Youtube音乐的使用非常相似,但要简单得多。

接下来需要用到的工具是 Tableau Python3 。先介绍一下数据集,稍后我将在数据可视化部分简要介绍Tableau。

数据集

百万首歌曲数据集是一个免费收集的音频功能和元数据为一百万个当前流行音乐曲目库。

以下是数据集的链接:

https://static.turi.com/datasets/millionsong/10000.txt

https://static.turi.com/datasets/millionsong/song_data.csv

这是我们需要合并的两个数据集。我们将使用Python3连接数据集并将其导入Tableau中进行数据可视化。

<code>#导入所有必需的库
import numpy as np
import pandas as pd


#导入两个数据集
songmetadata = pd.read_csv(r'Path where the file is located')

#其中一个文件是文本文件,因此我们使用pd.read_fwf导入它
#fwf代表固定宽度文件
othersongdata = pd.read_fwf(r'Path where the file is located')

#为 othersongdata 命名列
othersongdata.columns = ['user_id','song_id','listen_count’]

#合并数据集并删除重复项
song_df = pd.merge(othersongdata, songmetadata.drop_duplicates(['song_id']), on="song_id", how="left")

#在.csv中写入文件以在Tableau中可视化
song_df.to_csv(r'Path where you want to store the exported CSV file\\File Name.csv', index = False)/<code>

在合并数据集之后,我们得到的是一个一百万首歌曲的数据集,数据集有超过一百万个观测数据,由七个变量组成。

<code>Song_id = Object
#数据集中每首歌的唯一ID,数据集中总共有1000首歌
User_id = Object #
Unique ID for every user
每个用户的唯一ID
Listen_count = int
#Number of times a song was listened by an user
Artist_name = Str
#Name of Artist
Title = Str
#Title of each song
Year = int
#Categorical variable with lot of zero values
Release = Str
#Album to which the songs belong to/<code>

数据可视化

可视化能给你所有你不知道的问题的答案--本·施奈德曼

可视化数据、理解数据和发现见解总是一个很好的实践。我使用Tableau是因为它很快,并且提供了大量可视化数据集的选项。Tableau大大改进了我们的工作流程,此外,它是免费的!

什么是TreeMaps?

在这个项目中广泛使用TreeMaps来显示数据,这些数据可视化后的非常易于观看,而且是可定制化的。

维基百科已经用一种我无法理解的格式解释它:

Treemaps将分层(树结构)数据显示为一组嵌套矩形。树的每个分支都有一个矩形,然后用代表分支的较小矩形平铺。叶节点的矩形区域与数据的指定维度成比例。通常叶节点被着色以显示数据的单独维度。--维基百科

Tableau

在写这篇文章的时候,我想,什么是最好的方式来解释一个人,“如何在Tableau中创建TreeMaps?”. 我不想通过截图的途径。我能做什么?所以我制作了一个容易理解的视频。

要将数据转换为表格,需要将.csv转换为excel工作簿。您可以使用python中的以下命令轻松完成此操作:

<code>song_df.to_excel("millionsong.xlsx")/<code>

有时转换需要大量的时间,所以我在这里提供了一个可以随时下载的excel工作簿。

无论如何,这是一个全面的Tableau指南,它只是一个概述,让您熟悉Tableau是如何工作的,以及TreeMaps是如何制作的。

第一个TreeMap表示数据集中年份变量相对于侦听计数的比例。图表显示数据集中有许多零。由于我们在创建音乐推荐系统时不会使用Year变量,因此我们不会删除这些观察结果。

第二个TreeMap表示与数据集中的总侦听计数相关的艺术家。Coldplay以36406首点击率成为数据集中最受关注的艺术家,其次是Kings Of Leon,点击率为32552。

业务问题

太多的选择会让用户不知所措。如果提供的选项太多,用户可能不会购买任何东西。像Spotify这样的流媒体服务有大量的目录。识别用户可能喜欢的跟踪并推荐他们可能喜欢的产品对他们的业务至关重要。

我们将创建两个播放列表,一个是流行的播放列表,第二个是识别与用户已经喜欢的歌曲相似的歌曲,从而为他们提供个性化的推荐。

推荐系统

基于内容的推荐系统

CBRS根据项目的特征和其他项目元素之间的相似性推荐项目。假设用户已经看过喜剧类型的电影,CBRS将推荐同样属于喜剧类型的电影。

协同过滤推荐系统

用户偏好和态度被认为是创建cfr的基础。CFRS推荐的项目与用户已经选择的相似。我们将使用皮尔逊相关来计算相似轨迹之间的关系。

为什么我们使用协同而不是关联?

关联只描述了两个变量之间的关系,而协同不仅描述了两个变量之间的关系,还描述了两个变量之间的强度。因此,当我们创建一个协同过滤推荐系统时,我们使用相关性。

开始编写代码

首先,我们创建流行的播放列表。

<code>import pandas as pd
songmetadata = pd.read_csv(r'E:\\Analytics\\song_data.csv')
othersongdata = pd.read_fwf(r'E:\\Analytics\\10000.txt’)
songmetadata = pd.DataFrame(songmetadata)
othersongdata.columns = ['user_id','song_id','listen_count’]
song_df = pd.merge(othersongdata, songmetadata.drop_duplicates(['song_id']), on="song_id“, how ="left“)
song_grouped = song_df.groupby(['title']).agg({"listen_count":"count"})
grouped_sum = song_grouped['listen_count'].sum()

#计算每首歌曲在收听计数中所占的百分比
song_grouped['percentage'] = song_grouped['listen_count'].div(grouped_sum)*100

#根据侦听计数对数据集排序
song_grouped = song_grouped.sort_values(['listen_count'],ascending = True)
song_df = song_df['listen_count'].astype(float)
popular = song_grouped.sort_values(by = 'listen_count')

#筛选数据集中的前十首歌曲
popularsongs = popular[9517:9567]
popularsongs = pd.DataFrame(popularsongs.reset_index())
popularsongs.sort_values('listen_count', ascending = False)
popularsongs/<code>

现在我们将制作CFR并创建个性化播放列表,推荐系统的结果如下:

<code>import numpy as np
import pandas as pd
songmetadata = pd.read_csv(r'E:\\Analytics\\song_data.csv')
othersongdata = pd.read_fwf(r'E:\\Analytics\\10000.txt')
othersongdata.columns = ['user_id','song_id','listen_count’]
song_df = pd.merge(othersongdata, songmetadata.drop_duplicates(['song_id']), on="song_id", how="left")
song_grouped = pd.DataFrame(song_df.groupby('song_id')['listen_count'].count())
song_grouped = pd.DataFrame(song_df.groupby('song_id')['listen_count'].count())
song_df.astype({'listen_count': 'int32'},{'song_id':'str'}).dtypes
song_df[song_df['song_id'] == 'SOFVZRE12A8C139783']
songs_crosstab = pd.pivot_table(song_df, values = 'listen_count', index = 'user_id', columns = 'song_id’)
songs_crosstab.head()
predictor_song_ratings = songs_crosstab['SOFVZRE12A8C139783']


predictor_song_ratings[predictor_song_ratings>= 1]
similar_songs = songs_crosstab.corrwith(predictor_song_ratings)
corr_listened_song = pd.DataFrame(similar_songs, columns = ['pearsonR'])
corr_listened_song.dropna(inplace = True)
predictor_corr_summary =corr_listened_song.join(song_grouped['listen_count'])
predictor_corr_summary = predictor_corr_summary.sort_values('pearsonR', ascending = False)
final_recommended_songs = predictor_corr_summary[predictor_corr_summary.pearsonR < 0.9999]
final_recommended_songs.sort_values('pearsonR', ascending = False)
final_recommended_songs = final_recommended_songs.reset_index()
song_df_one = song_df.drop(['listen_count'], axis=1)
similar_songs = pd.merge(final_recommended_songs, song_df_one.drop_duplicates(["song_id"]), on="song_id", how="left")
similar_songs = similar_songs.sort_values('pearsonR', ascending = False)
similar_songs.head(50)/<code>

以上。有从事算法推荐岗位的同学不妨练习起来!在很多音乐推荐或者电商推荐里,使用的算法会有一定的偏差,音乐推荐算法主要考量的数据是你听得次数最多的、收藏等,赶紧行动起来!

--END--

翻译:未艾信息(www.weainfo.net)

查看更多最新资讯,欢迎大家点击阅读原文登录我们的AI社区。

以及关注我们的公众号:为AI呐喊(weainahan)