让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

上个周被网易云音乐的听歌报告刷屏,文摘菌这才发现,朋友圈不乏年度听歌成千上万的音乐重度患者。这群人可能中的不是音乐的毒,而是这套个性化音乐推荐算法真的太懂你。

这也又引起了一波对推荐算法的讨论。本文作者发现了一个有7亿多条歌曲的数据集,利用Word2vec,用这个训练集来训练机器学习模型,优化我们的音乐推荐结果。

中东和北非地区最大的音乐流媒体平台Anghami每个月产生7亿多条歌曲数据流。这也意味着所有这些流媒体产生的大量数据对我们来讲是一个宝贵的训练集,我们可以用这个训练集来训练机器学习模型使其更好地理解用户品味,并优化我们的音乐推荐结果。

在本文中,我们将介绍一个从大量流数据中提取歌曲嵌入信息的神经网络方法,以及如何用这一模型生成相关推荐。

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

每个点代表一首歌曲。点间距离越近,歌曲越相似

什么是推荐系统?

推荐系统分为两大类:

基于内容的推荐系统:着眼于需要推荐物品的属性。对音乐来说,属性包括歌曲流派、每分钟节拍数等等。

协同过滤系统:依据用户历史数据来推荐其他相似用户曾经接触过的物品。这类系统不关注内容本身的属性,而是基于有很多共同喜爱的歌曲和艺术家的人们通常喜欢相同风格的音乐这一原则进行推荐的。

当有足够多数据支撑时,协同过滤系统在推荐相关物品方面效果非常好。协同过滤的基本思想是,如果用户1喜欢艺术家A和B,用户2喜欢艺术家A、B、C,那么用户1可能也会喜欢艺术家C。

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

观察所有用户对全球歌曲的偏好,对用户-商品评分矩阵应用经典协同过滤方法(如矩阵分解),就可以得到关于不同歌曲组别是如何相关联的信息。因此如果一组用户拥有很多共同喜欢的歌曲,我们可以推断这些用户音乐品味很相似,并且他们听得每首歌曲之间也很相似。

这种涉及多用户的全球共现现象(global co-occurrence)告诉我们歌曲间是如何联系起来的。然而它没有告诉我们的是,歌曲是如何在时间上局部共存的。它们也许会告诉我们喜欢歌曲A的用户可能也会喜欢歌曲B,但是,这些用户之前有没有在同一个歌单或电台听过这些歌呢?因此查看用户在什么环境播放这些歌比仅仅只查看用户听过哪些歌的推荐效果会更好。换句话说,他们在同一时间段前后还听了什么歌?

因此我们希望有一个模型不仅能捕捉相似用户通常对哪些歌感兴趣,还能捕捉在相似环境下哪些歌频繁地一起出现。这时需要Word2vec大显身手了。

什么是Word2vec?

Word2vec是一种神经网络模型,起初被用来学习对自然语言处理课题非常有用的词嵌入(word embeddings)。最近几年,这项技术被更广泛地用到其他机器学习问题上,如产品推荐。神经网络分析输入的文本语料库,对词汇表中的每个单词生成代表这个单词的向量。这些向量数字就是我们所需要的,因为这些向量编码了词义与上下文的关系这一重要信息,接下来我们将会看到进一步的解释。

Word2vec定义了两个主要模型:CBOW模型(Continuous Bag-of-Words model)和Skip-gram模型(Skip-gram model)。因为本次使用了Skip-gram模型,在接下来的讨论中我们只涉及这一模型。

Word2vec Skip-gram模型是带一层隐含层的浅层神经网络,输入一个单词,尝试预测它的上下文单词并输出。以下面这句为例:

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

在上句中,“back-alleys”是我们当前的输入单词;

“little”,“dark”,“behind”和“the”是我们想得到的预测结果输出单词。

神经网络如下:

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

W1和W2表示权重矩阵,代表从输入得到输出时依次转换的权重。训练神经网络包括学习这些权重矩阵的值,直到输出最接近我们提供的训练数据的值。

输入一个单词,通过神经网络做前向传播,得到输出单词是我们所期望的单词的概率,期望单词是根据我们的训练集确定的。因为我们知道期待得到的输出单词是什么,所以我们可以计算预测的错误率,然后通过神经网络用反向传播反馈错误率,用随机梯度下降算法调整权重。通过这一步微调W1和W2的值,因此它们能更准确地预测出输出单词。这步完成后,让我们把上下文视窗移动到下一个单词,重复以上步骤。

对训练集的所有句子重复上述过程。全部完成后,权重矩阵会收敛到一个值,这个值能提供最准确的预测。

有意思的地方来了,如果两个不同的单词经常出现在相似的语境里,我们可以认为把两个单词中的任一个作为输入,神经网络将会输出非常相近的预测值。我们之前提到过权重矩阵的值会决定输出的预测值,所以说如果两个单词出现在相似的上下文中,我们可以认为这两个单词的权重矩阵值非常相似。

特别要说一下,权重矩阵W1的矩阵对应我们词汇表里的所有单词,每一行都对应某一个单词的权重。因此,因为相似的单词会输出相似的预测,他们在W1里对应的权重也应该相似。权重矩阵里这种权重和单词的对应关系就叫做embeddingss(嵌入),我们将用它来代表那个单词。

如何应用到歌曲推荐呢?我们可以把用户的歌曲列表当作一个句子,句子中的每个单词就是用户听过的一首歌。通过这些句子训练Word2vec模型基本上就意味着对用户过去听过的每首歌,我们使用用户在这首歌前后听过的歌曲来训练模型,这些歌曲某种程度上是属于同一个范畴的。

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

上图就是使用歌曲来代替单词的神经网络示意图。

这跟上面介绍的文本分析是类似的处理方式,只不过是我们给每首歌一个独特的标识而不是文本的单词。

在训练阶段最后我们将得到一个模型,其中每首歌都用一个高维度空间的权重向量来表示。有意思的是,相似歌曲的权重要比无关的歌曲更加接近。

有哪些歌曲向量的使用案例?

我们可以使用Word2vec把寻找相似场景的歌曲这个难题转变为数学问题,来捕捉这些局部的共同特点。我们把这些权重作为坐标呈现在高维空间里,每一首歌都是这个空间里的一个点。

这个空间被定义成很多个维度,虽然人类肉眼不能看到,但是我们可以使用如t-SNE(t-分布邻域嵌入算法)等降维的方法把高维向量降到2维,然后绘制如下图:

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

上图中的每一个点都代表一首歌,点之间距离越近就意味着歌曲越相似。这些向量可以有很多种用法,比如说作为其他机器学习算法的输入特征,当然它们自己也可以用来寻找相似的歌曲。

我们之前提到过,两首歌出现在相似情境的次数越多他们的坐标就会越接近。

所以对于特定的某一首歌,我们可以通过这首歌和其他所有歌曲向量之间的余弦相似性取余弦值最大的k首歌,即找到了k首最相似歌曲(向量之间的夹角最小就最相似)。

举个例子,黎巴嫩古典歌手Fayrouz的两首歌Shayef El Baher Shou Kbir和Bhebbak Ma Baaref Laych的余弦相似度高达0.98,而Shayef El Baher Shou Kbir这首歌和黎巴嫩现代流行歌手Elissa的Saharna Ya Leil就只有-0.09的相似度。这个我们比较好理解,因为正在听古典歌曲的用户不太可能在当前歌曲列表里放上流行歌曲。

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

使用歌曲向量的另一个有趣的方法是将用户的听音乐习惯映射到这个空间,并在此基础上生成推荐歌曲。

因为我们现在处理的是向量,我们可以用简单的四则运算来叠加向量。假如一个用户听过的三首歌分别是:Keaton Henson的In the Morning,London Grammar的Wasting My Young Years和Daughter的Youth。

我们可以获取这三首歌的向量并取平均值,找到与这三首歌等距的点。

我们所做的只是把某个用户听过的一些歌曲转化成向量坐标,在同样的向量空间中,这个坐标代表这个用户。

现在我们有了一个定义用户的向量,我们可以用之前的方法找到向量空间里坐标离用户比较近的相似歌曲。接下来的卡通片帮我们更生动的理解生成推荐的不同步骤。

让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现

我们发现歌曲如The Head and the Heart的Down in the Valley,Fleet Foxes的Mykonos和Ben Howard的Small Things和我们的输入歌曲一样都属于独立民谣风格。记住我们的所做的一切并没有基于音乐的声学研究哦,而是简单的探索在这些指定的歌曲周围,其他人到底听过哪些歌曲。

下一首可能就是你喜欢的

Word2vec使我们能用包含歌曲播放情境的坐标向量来为每首歌精确地建模。这种方法让我们很容易鉴别相似的歌曲,并使用向量运算找到定义每个用户的向量。

目前在工业界,Word2vec向量正和其他模型一起作为音乐推荐的特征,并且主要用于基于客户听音乐习惯的推荐。

所以下次你发现被推荐了一首好歌,想一想在你之前那些成千上万听过这首歌的人们,也许他们下一首听的歌就是你喜欢的某一首。


原文发布时间为:2018-01-07

本文作者:文摘菌

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“大数据文摘”微信公众号

上一篇:LeetCode: 106_Construct Binary Tree from Inorder and Postorder Traversal | 根据中序和后序遍历构建二叉树 | Medium


下一篇:LeetCode:110_Balanced Binary Tree | 平衡二叉树 | Easy