ALS音乐推荐(上)
本篇文章的开头笔者提出一个疑问,何为数据科学,数据科学是做什么的?大家带着这个疑问去读接下来的这篇音乐推荐的公众号。
从经验上讲,推荐引擎属于大规模机器学习,在日常购物中大家或许深有体会,比如:你在淘宝上浏览了一些商品,或者购买了一些商品,那么淘宝就会根据你的偏好给你推荐一些其他类似的商品。然而,相比较其他机器学习算法,推荐引擎的输出更加的直观,有时候的推荐效果让人吃惊。作为机器学习开篇文章,本篇文章会系统的介绍基于Audioscrobbler数据集的音乐推荐。
数据集介绍
Audioscrobbler数据集是一个公开发布的数据集,读者可以在(http://www-etud.iro.umontreal.ca/~bergstj/audioscrobbler_data.html)网站获取。数据集主要有三部分组成,user_artist_data.txt文件是主要的数据集文件记录了约2420条用户id、艺术家id以及用户收听艺术家歌曲的次数数据,包含141000个用户和160万个艺术家;artist_data.txt文件记录了艺术家id和对应的名字;artist_alias.txt记录了艺术家id和对应的别称id。
推荐算法介绍
由于所选取的数据集只记录了用户和歌曲之间的交互情况,除了艺术家名字之外没有其他信息。因此要找的学习算法不需要用户和艺术家的属性信息,这类算法通常被称为协同过滤。如果根据两个用户的年龄相同来判断他们可能具有相似的偏好,这不叫协同过滤。相反,根据两个用户播放过许多相同歌曲来判断他们可能都喜欢某首歌,这是协调过滤。
本篇所用的算法在数学上称为迭代最小二乘,把用户播放数据当成矩阵A,矩阵低i行第j列上的元素的值,代表用户i播放艺术家j的音乐。矩阵A是稀疏的,绝大多数元素是0,算法将A分解成两个小矩阵X和Y,既A=XYT,X代表用户特征矩阵,Y代表特征艺术家矩阵。两个矩阵的乘积当做用户-艺术家关系矩阵的估计。可以通过下边一组图直观的反映:
现在假如有5个听众,音乐有5首,那么A是一个5*5的矩阵,假如评分如下:
图2.1 用户订阅矩阵
假如d是三个属性,那么X的矩阵如下:
图2.2 用户-特征矩阵
Y的矩阵如下:
图2.3 特征-电影矩阵
实际的求解过程中通常先随机的固定矩阵Y,则,为提高计算效率,通常采用并行计算X的每一行,既。得到X之后,再反求出Y,不断的交替迭代,最终使得XYT与A的平方误差小于指定阈值,停止迭代,得到最终的X(代表用户特征矩阵)和Y矩阵(代表特征艺术家矩阵)。在根据最终X和Y矩阵结果,向用户进行推荐。
ALS的Spark实现
Spark MLlib的ALS算法实现有点缺陷,要求用户和产品的ID必须是数值型,并且是32位非负整数。在计算之前应该首先检验一下数据量。
1)数据预处理
过滤无效的用户艺术家ID和名字行,将格式不正确的数据行剔除掉。
def buildArtistByID(rawArtistData: Dataset[String]): DataFrame = { rawArtistData.flatMap { line => val (id, name) = line.span(_ != '\t') if (name.isEmpty) { None } else { try { Some((id.toInt, name.trim)) } catch { case _: NumberFormatException => None } } }.toDF("id", "name") }
过滤艺术家id和对应的别名id,将格式拼写错误的行剔除掉。
def buildArtistAlias(rawArtistAlias: Dataset[String]): Map[Int,Int] = { rawArtistAlias.flatMap { line => val Array(artist, alias) = line.split('\t') if (artist.isEmpty) { None } else { Some((artist.toInt, alias.toInt)) } }.collect().toMap }
将数据转换成Rating对象,Rating对象是ALS算法对“用户-产品-值”的抽象。
def buildCounts( rawUserArtistData: Dataset[String], bArtistAlias: Broadcast[Map[Int,Int]]): DataFrame = { rawUserArtistData.map { line => val Array(userID, artistID, count) = line.split(' ').map(_.toInt) val finalArtistID = bArtistAlias.value.getOrElse(artistID, artistID) (userID, finalArtistID, count) }.toDF("user", "artist", "count") }
2)模型构建
def model( rawUserArtistData: Dataset[String], rawArtistData: Dataset[String], rawArtistAlias: Dataset[String]): Unit = { val bArtistAlias = spark.sparkContext.broadcast(buildArtistAlias(rawArtistAlias)) //艺术家别名数据 val trainData = buildCounts(rawUserArtistData, bArtistAlias).cache() //将数据转换成需要的格式 val model = new ALS(). setSeed(Random.nextLong()). setImplicitPrefs(true). setRank(10). setRegParam(0.01). setAlpha(1.0). setMaxIter(5). setUserCol("user"). setItemCol("artist"). setRatingCol("count"). setPredictionCol("prediction"). fit(trainData) trainData.unpersist() model.userFactors.select("features").show(truncate = false) val userID = 2093760 val existingArtistIDs = trainData. filter($"user" === userID). select("artist").as[Int].collect() val artistByID = buildArtistByID(rawArtistData) artistByID.filter($"id" isin (existingArtistIDs:_*)).show() val topRecommendations = makeRecommendations(model, userID, 5) topRecommendations.show() val recommendedArtistIDs = topRecommendations.select("artist").as[Int].collect() artistByID.filter($"id" isin (recommendedArtistIDs:_*)).show() model.userFactors.unpersist() model.itemFactors.unpersist() }
本篇文章主要对ALS音乐推荐进行简单的介绍,下一篇会对模型的参数,以及模型的推荐效果进行评估,并且会对推荐结果进行优化。
备注:如果文中排版出现错乱,请点击https://mp.weixin.qq.com/s/aqF38rDQdT35YrLAyLm-nA
更多精彩内容,欢迎扫码关注以下微信公众号:大数据技术宅。大数据、AI从关注开始
ALS音乐推荐(上)的更多相关文章
- 3-Spark高级数据分析-第三章 音乐推荐和Audioscrobbler数据集
偏好是无法度量的. 相比其他的机器学习算法,推荐引擎的输出更直观,更容易理解. 接下来三章主要讲述Spark中主要的机器学习算法.其中一章围绕推荐引擎展开,主要介绍音乐推荐.在随后的章节中我们先介绍S ...
- Spark 实践——音乐推荐和 Audioscrobbler 数据集
本文基于<Spark 高级数据分析>第3章 用音乐推荐和Audioscrobbler数据 完整代码见 https://github.com/libaoquan95/aasPractice/ ...
- Recommending music on Spotify with deep learning 采用深度学习算法为Spotify做基于内容的音乐推荐
本文参考http://blog.csdn.net/zdy0_2004/article/details/43896015译文以及原文file:///F:/%E6%9C%BA%E5%99%A8%E5%AD ...
- 音乐推荐与Audioscrobbler数据集
1. Audioscrobbler数据集 数据下载地址: http://www.iro.umontreal.ca/~lisa/datasets/profiledata_06-May-2005.tar. ...
- Android-bindService本地服务-音乐播放-上
播放音乐的行为写在服务里,Activity去调用Service里面到方法,进行音乐播放,当Activity结束后,音乐播放器停止播放 界面: MainActivity: package liudeli ...
- 6、DRN-----深度强化学习在新闻推荐上的应用
1.摘要: 提出了一种新的深度强化学习框架的新闻推荐.由于新闻特征和用户喜好的动态特性,在线个性化新闻推荐是一个极具挑战性的问题. 虽然已经提出了一些在线推荐模型来解决新闻推荐的动态特性,但是这些方法 ...
- 这个菜鸟花几个小时写的 DEMO 被码云推荐上首页 ?
写在最前 没有接触过 AntV 的诸位看客可通过这篇不成文的文章稍作了解.最近 病毒猖獗,遂抽空做了一个相关小 DEMO.数据可视化方面的使用的是 AntV F2,前端框架使用 Vue 快速成 ...
- 用TensorFlow教你手写字识别
博主原文链接:用TensorFlow教你做手写字识别(准确率94.09%) 如需转载,请备注出处及链接,谢谢. 2012 年,Alex Krizhevsky, Geoff Hinton, and Il ...
- 历上最强的音乐播放器(jetA…
原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...
随机推荐
- (floyd)佛洛伊德算法
Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APSP)的算法.从表面上粗看,Floyd算法是一个非常简单的 ...
- 在Anacoda中管理多个版本Python
win10. 在cmd窗口中输入 conda info --envs 或者 conda env list 查看已经安装的环境,当前活动的环境前会加*号. 在cmd窗口(终端窗口)或anaconda p ...
- 多线程 Synchronized关键字和Lock
Synchronized 分为实例锁和全局锁. 实例锁为 synchronized(this) 和 非static synchronized方法. 也加对象锁. 只要一个线程访问这类的一个syn ...
- 用jQuery.delegate()将事件绑定在父元素上面
1.先看看官方的示例: <html> <head> <script type="text/javascript" src="/jquery/ ...
- git常用命令速查
创建 $ git init #在当前目录下创建一个空的本地仓库 $ rm -rf .git #删除本地仓库 $ git add . #把当前目录下的所有文件添加到暂存区 $ git commi ...
- ORA-03206,当表空间不够时,如何以添加数据文件的方式扩展表空间
准备导入一个数据库,大约为33G,开始创建的空库表空间为自增到20G,结果自然不够,然后就开始自动扩展表空间大小 使用的如下语句 --自动扩展表空间大小 ALTER DATABASE DATAFILE ...
- c语言字符类型作业
一.PTA实验作业 题目1:7-2 统计一行文本的单词个数 1. 本题PTA提交列表 2. 设计思路 1.定义整形变量i=0,count=0,flag. 2.定义数组str[999] 3.输入str[ ...
- 2017-2018-1 Java演绎法 第八周 作业
团队任务:UML设计 团队组长:袁逸灏 本次编辑:刘伟康 团队分工 第一次使用泳道图,感觉非常方便,从图中的箭头和各个活动框中可以清晰地看出分工流程: 不过既然是博客园,分工就不能只贴图,markdo ...
- Beta冲刺 第三天
Beta冲刺 第三天 1. 昨天的困难 昨天的困难主要集中在对Ajax的使用上,不熟悉这种语法,所以也就浪费了时间,导致昨天的批量删除没有完全完成. 2. 今天解决的进度 潘伟靖: 1.完善了昨天没写 ...
- python3变量和数据类型
变量和数据类型 知识点 python 关键字 变量的定义与赋值 input() 函数 字符串的格式化 实验步骤 每一种编程语言都有它们自己的语法规则,就像我们所说的外语. 1. 关键字和标识符 ...