基于大数据的音乐推荐系统是为了给听众推荐符合内心喜好的个性化系统。系统提供的功能有,音乐管理:管理员可以添加删除音乐,音乐查找:用户可以在系统中自行查找想要听的歌曲,音乐推荐:系统在收集了用户的行为数据之后为用户个性化推荐音乐,用户管理:管理员可以对用户进行删除,评论管理:管理员可以对评论进行删除,音乐下载:用户可以自行下载个人喜欢分歌曲。
本系统部署在开源大数据平台hadoop3.5之上,搭配的spark2.2也为开源免费。后端使用的关系型数据库为mysql。开发软件使用的是eclipse社区版、pycharm社区版和其他一些免费开源软件。前端采用spring和ssm,技术已经较为成熟。
目 录
摘 要 I
Abstract II
1 绪论 1
1.1 研究背景 1
1.2 研究现状 1
1.2.1 国内研究现状 1
1.2.2 国外研究现状 2
1.3 发展趋势 2
2 相关技术介绍 3
2.1 大数据环境 3
2.1.1 全球开源的Linux系统-Ubuntu 3
2.1.2 开源分大数据处理平台Hadoop 3
2.1.3 shell 3
2.1.4 kettle 4
2.1.5 Scala 4
2.2 数据获取与处理 4
2.2.1 Pymysql 4
2.2.2 Urllib.request 4
2.2.3 besutifulsoup4 4
2.3网页端 5
2.3.1 tomcat9 5
2.3.2 spring 5
3 数据采集 6
3.1 数据源确定 6
3.2 爬虫数据库设计 6
3.3 数据爬取 7
4 系统分析 15
4.1 业务分析 15
4.2 系统功能分析 16
4.3 系统可行性分析 16
4.3.1 技术可行性分析 16
4.3.2 经济可行性分析 17
4.3.3 操作性可行性分析 17
4.4 数据字典 17
4.4.1 数据项条目 17
4.4.2 数据流 19
4.4.3 数据处理条目 21
5 系统设计 23
5.1 系统总体模块结构设计 23
5.2 局部模块设计 24
5.2.1 登录注册模块 24
5.2.2 热门推荐模块 25
5.2.3 新歌上架模块 26
5.2.4 个性化推荐模块 26
5.2.5 用户中心模块 27
5.2.6 音乐管理模块 27
5.2.7 用户管理模块 28
5.2.8 评论管理模块 28
5.3 系统角色功能设计 29
5.4 推荐系统数据库设计 29
5.4.1 数据库概念结构设计 29
5.4.2 数据库物理结构设计 32
5.5 大数据平台搭建设计 35
5.5.1 hadoop的安装与配置 35
5.5.2 spark的安装 38
5.6 推荐算法设计 39
6 系统实现 46
6.1 用户界面 46
6.1.1 系统主页 46
6.1.2 用户登录 46
6.1.3 用户注册 47
6.1.4 用户登陆后界面 49
6.1.5 热门推荐界面 49
6.1.6 音乐播放详情界面 50
6.1.7 个性化音乐推荐详情界面 51
6.1.8 个人音乐记录页面 51
6.2 管理员界面 53
6.2.1 管理员登录 53
6.2.3 评论管理界面 54
6.2.4 用户管理界面 55
总结与展望 56
致 谢 57
参考文献 58
2.2 数据获取与处理
2.2.1 Pymysql
Mysql是如今最为普遍的数据库里,而python作为比较流行的语言之一,自然少不了与mysql做交互,其中pymysql就是使用最多的工具库了。Python导入pymysql之后,配置完数据库就可以直接操作数据库内各种表等。
2.2.2 Urllib.request
Urllib.request 模块定义了适用于在各种复杂情况下打开 URL(主要为 HTTP)的函数和类 — 例如基本认证、摘要认证、重定向、cookies 及其它。Requests 继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。Requests的文档非常完备,中文文档也相当不错。Requests能完全满足当前网络的需求,支持Python 2.6—3.8,而且能在PyPy下完美运行。
2.2.3 besutifulsoup4
HTML 文档本身是结构化的文本,有一定的规则,通过它的结构可以简化信息提取。于是,就有了lxml、pyquery、BeautifulSoup等网页信息提取库。一般会用这些库来提取网页信息。其中,lxml 有很高的解析效率,支持 xPath 语法(一种可以在 HTML 中查找信息的规则语法);pyquery 得名于 jQuery(知名的前端 js 库),可以用类似 jQuery 的语法解析网页。
BeautifulSoup(下文简称 bs)翻译成中文就是“美丽的汤”,这个奇奇怪怪的名字取自于《爱丽丝梦游仙境》,bs 最大的特点就是简单易用,不需要像正则和 xPath 等工具必须牢记很多特定的语法。虽然效率更高更直接,但对大多数 python 使用者来说,好用会比高效更重要。
2.3网页端
2.3.1 tomcat9
Tomcat是Apache Software Foundation的Jakarta项目的核心组件,该项目是由Apache,Sun和一些公司和个人开发的轻量级Web应用程序服务器。是Servlet和JSP规范的开源实现。由于其技术非常先进,而且工作稳且性能高,它深受java爱好者的追捧,很多开源边界者都对他赞赏有加。目前呢已经成为最流行流行的Web应用程序服务器。
2.3.2 spring
Spring框架是Rod Johnson启动的开源J2EE应用程序框架,而Rod Johnson是用于bean生命周期管理的轻量级容器。 Spring解决了J2EE开发过程中开发人员遇到的较多常见问题,还提供了非常实用的功能,例如IOC,AOP,Web MVC等。 Spring甚至可以单独构建,也可以与Struts,Webwork和Tapstry等桌面应用程序结合以创建JEE,桌面和小型应用程序。
3 数据采集
3.1 数据源确定
确定了要做基于大数据的音乐推荐系统之后,首先要确定数据源。通过分析基于大数据的音乐推荐系统,即音乐推荐需要哪些数据,详细了解推荐机制,搞清楚这些数据需要被处理为什么格式。
首先定义爬取目标:
1.实现音乐的个性化推荐,帮助用户快速找到可能感兴趣的音乐。
2.实现音乐的热门推荐,帮助主流大众迅速找到流行的趋势。
3.实现音乐的新品推荐,帮助唱片公司带动市场,实现引流。
各大音乐网站多如牛毛,确定了数据爬取目标之后,接下来要确定去哪个平台去爬取泽泻数据。选择数据源要确定数据源数据是否可靠真实,要避免爬取音乐平台发布的虚伪的音乐数据,如不存在的歌唱家、专辑、音乐等。
于是,在比较多家音乐平台(QQ音乐、网易云音乐、酷狗音乐、酷音乐)后,综合分析后选择网易云音乐网页版作为爬虫目标。基于之前设定的爬取目标,选择爬取以下数据:
1.歌手信息:歌手id,歌手名字
2.歌手专辑信息:专辑id,专辑名称,专辑封面
3.音乐信息:音乐名

歌曲推荐算法

package top.wangruns.trackstacking.algorithm;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;public class CollaborativeFiltering {/*** 基于最近邻用户产生协同过滤的推荐结果* @param userIdList* 用户Id列表* @param userKNNMatrix* 用户KNN矩阵* @param user2songRatingMatrix* 用户歌曲“评分”矩阵* @param songIdList* 歌曲Id列表* @param n* 推荐的前n首歌曲* @return* 用户歌曲推荐结果矩阵.userId,[recSongId1,recSongId2...recSongIdn]*/public static Map<Integer, Integer[]> userKNNBasedCF(List<Integer> userIdList,final Map<Integer, Integer[]> userKNNMatrix, final Map<Integer, float[]> user2songRatingMatrix,final List<Integer> songIdList, final int n) {// TODO Auto-generated method stubfinal Map<Integer,Integer[]> user2songRecMatrix=new HashMap<Integer, Integer[]>();userIdList.forEach(new Consumer<Integer>() {public void accept(Integer curUserId) {// TODO Auto-generated method stubInteger[] knnIdArray=userKNNMatrix.get(curUserId);/*** 对于每一首当前用户没有听过的歌曲* 协同得分为:* 其k个最近邻用户对该歌曲的“评分”的聚合*/float[] curUserRatings=user2songRatingMatrix.get(curUserId);//为用户建立一个最小堆来存放最高的前n首歌曲MininumHeap mininumHeap=new MininumHeap(n);for(int i=0;i<curUserRatings.length;i++) {//对于没有听过的歌曲/*** 这里需要注意的是,浮点数不能用==来比较...之前竟然犯了这个低级的错误...* 故这里用 curUserRatings[i]<0.01f 来表示 curUserRatings[i]==0f*/if(curUserRatings[i]<0.01f) {for(int knnIndex=0;knnIndex<knnIdArray.length;knnIndex++) {int knnId=knnIdArray[knnIndex];float[] knnUserRatings=user2songRatingMatrix.get(knnId);curUserRatings[i]+=knnUserRatings[i];}//这里的聚合策略取均值curUserRatings[i]/=knnIdArray.length;int curSongId=songIdList.get(i);//放入堆中mininumHeap.addElement(new TreeNode(curSongId,curUserRatings[i]));}}/*** 对该用户没有听过的歌曲,协同得分完成,选取n个得分最高的项目作为推荐*/int trueNumber=n;//如果推荐的歌曲少于计划推荐的n首(处理歌曲很少的情况)if(mininumHeap.getCurHeapSize()<n) {trueNumber=mininumHeap.getCurHeapSize();}Integer[] curUserRecSongId=new Integer[trueNumber];for(int i=0;i<trueNumber;i++) {int recSongId=mininumHeap.getArray()[i].id;curUserRecSongId[i]=recSongId;}user2songRecMatrix.put(curUserId, curUserRecSongId);}});return user2songRecMatrix;}}

获取歌曲信息代码:

package top.wangruns.trackstacking.algorithm;import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;import top.wangruns.trackstacking.model.Collection;
import top.wangruns.trackstacking.model.DownloadRecord;
import top.wangruns.trackstacking.model.PlayRecord;
import top.wangruns.trackstacking.model.User;public class DataTranslate {private final static float PLAY_SCORE=1f;private final static float DOWNLOAD_SCORE=2f;private final static float COLLECTION_SCORE=5f;private final static float MAX_SCORE=10f;private final static int SONG_ID_SET_KEY=0;/*** 构建用户频率矩阵来近似用户评分,对于某些系统而言,我们是不可能获取到用户对某些项目的评分的,但是我们可以利用用户的* 行为习惯来反映用户的“评分”,比如一个用户常常收听某一首歌,那么我们可以推断该用户喜欢该歌曲的可能性很大.* 总分10分,主动播放一次1分,下载2分,收藏5分,如果超过10分,按10分计算.* @param userIdList * 用户Id列表* @param songIdList * 歌曲Id列表* @param downloadList* 用户的下载记录列表* @param playList* 用户的播放记录列表* @param collectionList* 用户的收藏记录列表* @return* 用户Id-歌曲Id 频率矩阵*/public static Map<Integer, float[]> getFrequencyMatrix(List<Integer> userIdList, final List<Integer> songIdList,List<DownloadRecord> downloadList, List<PlayRecord> playList, List<Collection> collectionList) {// TODO Auto-generated method stubfinal Map<Integer,float[]> user2songRatingMatrix=new HashMap<Integer, float[]>();final int songLen=songIdList.size();//获取用户-歌曲 下载映射final Map<Integer,Map<Integer,Set<Integer>>> userId2songIdDownloadMap=getUserId2songIdRecordMap(downloadList,false);//获取用户-歌曲 收藏映射final Map<Integer, Map<Integer, Set<Integer>>> userId2songIdCollectionMap=getUserId2songIdRecordMap(collectionList,false);//获取用户-歌曲-次数 播放映射final Map<Integer, Map<Integer, Set<Integer>>> userId2songIdPlayMap=getUserId2songIdRecordMap(playList,true);userIdList.forEach(new Consumer<Integer>() {public void accept(Integer userId) {// TODO Auto-generated method stubfloat[] curUserRatingArray=new float[songLen];int songIndex=0;//处理每一首歌曲for(Integer songId:songIdList) {/*** 处理下载,这里不考虑下载次数*/if(userId2songIdDownloadMap.get(userId)!=null && userId2songIdDownloadMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户下载过的歌曲curUserRatingArray[songIndex]+=DOWNLOAD_SCORE;}/*** 处理收藏,这里没有次数*/if(userId2songIdCollectionMap.get(userId)!=null && userId2songIdCollectionMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户收藏的歌曲curUserRatingArray[songIndex]+=COLLECTION_SCORE;}/*** 处理播放,考虑播放次数*/if(userId2songIdPlayMap.get(userId)!=null && userId2songIdPlayMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户播放过的歌曲int count=userId2songIdPlayMap.get(userId).get(songId).iterator().next();curUserRatingArray[songIndex]+=PLAY_SCORE + count;}/*** 处理最大得分,超过最大得分,记为最大得分*/if(curUserRatingArray[songIndex]>MAX_SCORE) {curUserRatingArray[songIndex]=MAX_SCORE;}//处理下一首歌songIndex++;}//处理完一个用户user2songRatingMatrix.put(userId, curUserRatingArray);}});return user2songRatingMatrix;}/*** 获取用户Id - 歌曲Id 的映射Map* @param recordList* 包含userId,songId的记录列表* @param isCount* 是否需要计数。如果true,则Integer[1]存放计数。* @return* 两层Map* 第一层Map<Integer,Map> 每个userId拥有一个自己的Map:* userId,userSetMap* * 第二层Map<Integer,Set> 用户自己的Map里面存放两个东西:* (1)为每首歌曲计数songId,CountSet;* (2)存放出现过的歌曲songSetFlay,SongIdSet:*/private static <T> Map<Integer, Map<Integer, Set<Integer>>> getUserId2songIdRecordMap(final List<T> recordList,final boolean isCount) {// TODO Auto-generated method stubfinal Map<Integer, Map<Integer, Set<Integer>>> userId2songIdRecordMap=new HashMap<Integer, Map<Integer, Set<Integer>>>();recordList.forEach(new Consumer<T>() {public void accept(T t) {// TODO Auto-generated method stubtry {//利用反射获和泛型获取不同类型表的相同属性Field userIdField=t.getClass().getDeclaredField("userId");Field songIdField=t.getClass().getDeclaredField("songId");userIdField.setAccessible(true);songIdField.setAccessible(true);int userId=userIdField.getInt(t);int songId=songIdField.getInt(t);//不需要计数if(!isCount) {//map外层的userId已经存在if(userId2songIdRecordMap.containsKey(userId)) {//获取当前用户的记录集合MapMap<Integer,Set<Integer>> curRecordSetMap=userId2songIdRecordMap.get(userId);//将当前歌曲添加到当前用户的记录集合中curRecordSetMap.get(SONG_ID_SET_KEY).add(songId);}else {Map<Integer,Set<Integer>> curRecordSetMap=new HashMap<Integer, Set<Integer>>();//创建记录歌曲Id的集合Set<Integer> curSongIdSet=new HashSet<Integer>();curSongIdSet.add(songId);curRecordSetMap.put(SONG_ID_SET_KEY, curSongIdSet);userId2songIdRecordMap.put(userId, curRecordSetMap);}}else {//map外层的userId已经存在if(userId2songIdRecordMap.containsKey(userId)) {//获取当前用户的记录集合MapMap<Integer,Set<Integer>> curRecordSetMap=userId2songIdRecordMap.get(userId);//将当前歌曲添加到当前用户的记录集合中curRecordSetMap.get(SONG_ID_SET_KEY).add(songId);//计数count(songId,curRecordSetMap);}else {Map<Integer,Set<Integer>> curRecordSetMap=new HashMap<Integer, Set<Integer>>();//创建记录歌曲Id的集合Set<Integer> curSongIdSet=new HashSet<Integer>();curSongIdSet.add(songId);curRecordSetMap.put(SONG_ID_SET_KEY, curSongIdSet);userId2songIdRecordMap.put(userId, curRecordSetMap);//计数count(songId,curRecordSetMap);}}}catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}private void count(int songId, Map<Integer, Set<Integer>> curRecordSetMap) {// TODO Auto-generated method stub/*** 计数,如果Map<songId,count>已经存在,则直接计数+1*/if(curRecordSetMap.containsKey(songId)) {//获取当前用户歌曲的计数集合(只有一个元素)Set<Integer> curCountSet=curRecordSetMap.get(songId);int cnt=curCountSet.iterator().next()+1;curCountSet.clear();curCountSet.add(cnt);}else {Set<Integer> curCountSet=new HashSet<Integer>();curCountSet.add(1);curRecordSetMap.put(songId, curCountSet);}}});return userId2songIdRecordMap;}//   private static Map<Integer, Integer>getUserId2songIdDownloadMap(List<DownloadRecord> downloadList) {//      // TODO Auto-generated method stub
//      final Map<Integer,Integer> userId2songIdDownloadMap=new HashMap<Integer, Integer>();
//      downloadList.forEach(new Consumer<DownloadRecord>() {//
//          public void accept(DownloadRecord t) {//              // TODO Auto-generated method stub
//              if(!userId2songIdDownloadMap.containsKey(t.getUserId())) {//                  userId2songIdDownloadMap.put(t.getUserId(), t.getSongId());
//              }
//          }
//
//      });
//      return userId2songIdDownloadMap;
//  }}






























基于大数据的音乐推荐系统的设计与实现相关推荐

  1. 【毕业设计_课程设计】基于大数据个性化音乐推荐算法分析

    文章目录 0 前言 1 研究目的 2 研究方法 2.1 传统推荐算法 2.2 基于LightGBM决策树模型的推荐算法 3 研究结论 4 最后 0 前言 基于大数据个性化音乐推荐算法分析 提示:适合用 ...

  2. 基于大数据的餐饮推荐系统总结

    0. 说明 由于原先自己搭的博客系统出问题了,故将其中有价值的内容迁移出来,并对文章进行更新. 发现博客园的文章不能置顶,所以又把它以随笔的形式再写一份. 原文链接: 基于大数据的餐饮推荐系统总结 可 ...

  3. 基于大数据个性化音乐推荐算法分析(附代码github地址)

    github网址:https://github.com/ciecus/music_lgb_recommend_kkbox 欢迎fork我,和我讨论呀~ 摘  要:音乐推荐算法针对当今时代信息过载的问题 ...

  4. 基于大数据的个性化推荐系统(转)

    随着互联网时代的发展和大数据时代的到来,人们逐渐从信息匮乏的时代走入了信息过载的时代.为了让用户从海量信息中高效地获取自己所需的信息,推荐系统应运而生. 推荐系统的主要任务就是联系用户和信息,它一方面 ...

  5. 基于Python的在线音乐推荐系统的设计与实现

     源码获取:https://www.bilibili.com/video/BV1Ne4y1g7dC/ 基于Python的在线音乐推荐系统是一个基于Internet,采用PYTHON技术开发的服务于音乐 ...

  6. 基于大数据的音乐数据中心平台(附:源码 课件 项目部署文档)

    项目介绍 音乐数据中心数仓综合项目主要是针对公司过去收集到的用户点播.购买音乐等数据(包括业务数据与用户行为数据),为公司业务更健康的发展提供决策服务支持(BI商业决策). 数据中心项目中包含业务系统 ...

  7. 毕业设计-基于大数据的电影推荐系统-python

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言

  8. 毕业设计-基于大数据的新闻推荐系统-python

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言

  9. 毕业设计-基于大数据动画电影推荐系统-python

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言

  10. 基于大数据的租房信息推荐系统

    介绍 基于大数据的租房推荐系统是一种用于帮助用户找到最适合他们的房子的系统.该系统主要功能是爬虫抓取贝壳租房网站信息,租房信息推荐,可视化分析等.使用 echarts, django, vue,协同过 ...

最新文章

  1. 论文:贝叶斯优化算法和应用综述(2)--概率模型和采集函数的介绍以及综述列表
  2. 带项目的一些体会以及合格的 Leader 应该具备什么特质?(转)
  3. eltree ref什么时候有_DBA:为什么你老写慢SQL
  4. 多媒体计算机辅助教学与课件制作,清华大学出版社-图书详情-《计算机辅助教学多媒体课件设计制作与应用》...
  5. 蒲公英枸杞菊花可以一起泡茶喝吗?
  6. Ubuntu 14.04安装和卸载搜狗拼音输入法
  7. 怎么重置unity界面_请问itween如何重置?
  8. 【机器学习笔记之六】Bagging 简述
  9. Visual C++学习总结——进程或线程与指定CPU绑定
  10. laravel 下载使用
  11. 用户画像数据建模方法
  12. 还不会用 Python 提取 PDF 表格?三种类型数据,轻松转换成 Excel
  13. 判断二元关系的性质:自反性、对称性、传递性
  14. Win10电脑资源管理器怎么打开?五种打开方式详解
  15. DNT精英论坛(暨.NET北京俱乐部)第3期沙龙:区块链跨链技术的设计与实践
  16. 【工控老马】OPC通讯协议解析-OPC七问
  17. android投屏!Android开发还会吃香吗?挥泪整理面经
  18. 今天找压缩算法,看到一段陈年往事
  19. 纪实之2013年秋,我在找工作
  20. Vue中使用e-icon-picker 图标选择组件

热门文章

  1. python熊猫烧香_熊猫烧香完整源代码
  2. sqlserver2010教程百度云盘_SQLServer数据库基础教程(72集),全套视频教程学习资料通过百度云网盘下载...
  3. 【数据挖掘】数据挖掘总结 ( 模式挖掘 | Apriori 算法 | 支持度 | 置信度 | 关联规则 ) ★★
  4. uml c语言函数流程图,UML流程图模板分享
  5. SQL之SQL99语法 没错就这么简单
  6. linux命令行下如何播放视频,linux播放视频命令
  7. 经典的HTML5游戏及其源码分析
  8. Java最牛教材!甲骨文java认证考试试题
  9. Excel图表之道—如何制作专业有效的商务图表(远离难看的图表,让客户满意,给自己加薪)...
  10. C语言数据结构-顺序表的插入与删除(图文详解)