Spark 实践——音乐推荐和 Audioscrobbler 数据集
本文基于《Spark 高级数据分析》第3章 用音乐推荐和Audioscrobbler数据
完整代码见 https://github.com/libaoquan95/aasPractice/tree/master/c3/recommend
1.获取数据集
本 章 示 例 使 用 Audioscrobbler 公 开 发 布 的 一 个 数 据 集。 Audioscrobbler 是 last.fm 的 第一个音乐推荐系统。 last.fm 创建于 2002 年,是最早的互联网流媒体广播站点之一。
Audioscrobbler 数据集有些特别, 因为它只记录了播放数据,主要的数据集在文件 user_artist_data.txt 中,它包含 141 000 个用户和 160 万个艺术家,记录了约 2420 万条用户播放艺术家歌曲的信息,其中包括播放次
数信息。数据集在 artist_data.txt 文件中给出了每个艺术家的 ID 和对应的名字。请注意,记录播放信息时,客户端应用提交的是艺术家的名字。名字如果有拼写错误,或使用了非标准的名称, 事后才能被发现。 比如,“The Smiths”“Smiths, The”和“the smiths”看似代表不同艺术家的 ID,但它们其实明显是指同一个艺术家。因此,为了将拼写错误的艺术家 ID 或ID 变体对应到该艺术家的规范 ID,数据集提供了 artist_alias.txt 文件。
下载地址:
- http://www-etud.iro.umontreal.ca/~bergstrj/audioscrobbler_data.html (原书地址,已失效)
- https://github.com/libaoquan95/aasPractice/tree/master/c3/profiledata_06-May-2005(数据集大于git上传限制,分卷压缩)
2.数据处理
加载数据集
val dataDirBase = "profiledata_06-May-2005/"
val rawUserArtistData = sc.read.textFile(dataDirBase + "user_artist_data.txt")
val rawArtistData = sc.read.textFile(dataDirBase + "artist_data.txt")
val rawArtistAlias = sc.read.textFile(dataDirBase + "artist_alias.txt")
rawUserArtistData.show()
rawArtistData.show()
rawArtistAlias.show()



格式化数据集,转换成 DataFrame
val artistByID = 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").cache()
val artistAlias = rawArtistAlias.flatMap { line =>
var Array(artist, alias) = line.split('\t')
if (artist.isEmpty()) {
None
} else {
Some((artist.toInt, alias.toInt))
}
}.collect().toMap
val bArtistAlias = sc.sparkContext.broadcast(artistAlias)
val userArtistDF = rawUserArtistData.map { line =>
val Array(userId, artistID, count) = line.split(' ').map(_.toInt)
val finalArtistID = bArtistAlias.value.getOrElse(artistID, artistID)
(userId, artistID, count)
}.toDF("user", "artist", "count").cache()



查看 artist 别名与实名
val (badID, goodID) = artistAlias.head
artistByID.filter($"id" isin (badID, goodID)).show()

3.利用 Spark MLlib 进行推荐
Spark MLlib 使用 ALS (交替最小二乘) 来实现协同过滤算法,该模型只需传入三元组 (用户ID, 物品ID, 评分) 就可以进行计算,需要注意,用户ID 和 物品ID必须是整型数据。
val Array(trainData, cvData) = userArtistDF.randomSplit(Array(0.9, 0.1))
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)

推荐模型已经搭建完成,不过 Spark MLlib 每次只能对单个用户进行推荐,无法进行单次的全局推荐。
val userId = 2093760
val topN = 10
val toRecommend = model.itemFactors.
select($"id".as("artist")).
withColumn("user", lit(userId))
val topRecommendations = model.transform(toRecommend).
select("artist", "prediction").
orderBy($"prediction".desc).
limit(topN)
// 查看推荐结果
val recommendedArtistIDs = topRecommendations.select("artist").as[Int].collect()
artistByID.join(sc.createDataset(recommendedArtistIDs).
toDF("id"), "id").
select("name").show()

Spark 实践——音乐推荐和 Audioscrobbler 数据集的更多相关文章
- 音乐推荐与Audioscrobbler数据集
1. Audioscrobbler数据集 数据下载地址: http://www.iro.umontreal.ca/~lisa/datasets/profiledata_06-May-2005.tar. ...
- 3-Spark高级数据分析-第三章 音乐推荐和Audioscrobbler数据集
偏好是无法度量的. 相比其他的机器学习算法,推荐引擎的输出更直观,更容易理解. 接下来三章主要讲述Spark中主要的机器学习算法.其中一章围绕推荐引擎展开,主要介绍音乐推荐.在随后的章节中我们先介绍S ...
- ALS音乐推荐(上)
本篇文章的开头笔者提出一个疑问,何为数据科学,数据科学是做什么的?大家带着这个疑问去读接下来的这篇音乐推荐的公众号. 从经验上讲,推荐引擎属于大规模机器学习,在日常购物中大家或许深有体会,比如:你在淘 ...
- 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 ...
- 个推 Spark实践教你绕过开发那些“坑”
Spark作为一个开源数据处理框架,它在数据计算过程中把中间数据直接缓存到内存里,能大大提高处理速度,特别是复杂的迭代计算.Spark主要包括SparkSQL,SparkStreaming,Spark ...
- Spark 实践——基于 Spark MLlib 和 YFCC 100M 数据集的景点推荐系统
1.前言 上接 YFCC 100M数据集分析笔记 和 使用百度地图api可视化聚类结果, 在对 YFCC 100M 聚类出的景点信息的基础上,使用 Spark MLlib 提供的 ALS 算法构建推荐 ...
- 推荐系统实践 0x05 推荐数据集MovieLens及评测
推荐数据集MovieLens及评测 数据集简介 MoiveLens是GroupLens Research收集并发布的关于电影评分的数据集,规模也比较大,为了让我们的实验快速有效的进行,我们选取了发布于 ...
- MongoDB,HDFS, Spark to 电影推荐
http://www.infoq.com/cn/news/2014/12/mongdb-spark-movie-recommend MovieWeb是一个电影相关的网站,它提供的功能包括搜索电影信息. ...
- Spark实践 -- 性能优化基础
性能调优相关的原理讲解.经验总结: 掌握一整套Spark企业级性能调优解决方案:而不只是简单的一些性能调优技巧. 针对写好的spark作业,实施一整套数据倾斜解决方案:实际经验中积累的数据倾斜现象的表 ...
随机推荐
- CSS鼠标经过另类做法
HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- redis在.net架构中的应用(2)--并发和原子操作不可兼得
在上一篇文章中,我主要向大家介绍了利用servicestack连接redis以及一些redis的基本数据类型,传送门 本文中,我将通过一个具体应用场景为大家介绍redis中的并发和原子操作 其中用到的 ...
- BZOJ1458:士兵占领(有上下界最小流)
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
- BZOJ3251:树上三角形(乱搞)
Description 给定一大小为n的有点权树,每次询问一对点(u,v),问是否能在u到v的简单路径上取三个点权,以这三个权值为边长构成一个三角形.同时还支持单点修改. Input 第一行两个整数n ...
- 页面中php传值后循环列表js获取点击的id
页面中php传值后循环列表js获取点击的id值进行js操作 <script type="text/javascript" src="__PUBLIC__/js/jq ...
- 【转】SVN branches trunk 合并 讲解
转自:http://blog.csdn.net/e3002/article/details/21469437 使用svn几年了,一直对分支和合并敬而远之,一来是因为分支的管理不该我操心,二来即使涉及到 ...
- WorldWind源码剖析系列:设置类SettingsBase
PluginSDK中的星球设置类WorldSettings 和WorldWind.程序设置类WorldWindSettings均继承自父类SettingsBase.类图如下所示.其中父类Setting ...
- java剪辑音频
用来剪辑特定长度的音频,并将它们混剪在一起,大体思路是这样的: 1. 使用 FileInputStream 输入两个音频 2. 使用 FileInputStream的skip(long n) 方法跳过 ...
- Hadoop日记Day9---HDFS的java访问接口
一.搭建Hadoop 开发环境 我们在工作中写完的各种代码是在服务器中运行的,HDFS 的操作代码也不例外.在开发阶段,我们使用windows 下的eclipse 作为开发环境,访问运行在虚拟机中的H ...
- Elasticsearch date 类型详解
引言 一直对 elasticsearch 中的 date 类型认识比较模糊,而且在使用中又比较常见,这次决定多花些时间,彻底弄懂它,希望能对用到的同学提供帮助. 注意:本文测试使用是 elastics ...