后台可以记录每篇博客的阅读次数,直接简单粗暴的推荐比较流行的博客即可,可能热门的博客会被很多人所喜欢。
问题:可能产生长尾效应,阅读数多的博客可能就有限的几篇,而大量的博客无人问津。
解决方案:将阅读次数与新鲜度结合,找到一个比较适合的排名方式,一篇刚发布的博客,有较大的新鲜度,可以将其排到前面。

算法的设计

(1)在抽取博客时,会抽取到文章发布的时间,我们可以将这个发布时间转化为时间戳,这个时间戳就可以作为一篇文章基础的评分,时间戳是随着时间不断增加的,新发布的博客会有比较大的时间戳,这样就保证了新来的博客的分值比较大。
(2)在时间戳的基础上,我们可以引入点击量,作为博客评分的另一个部分,我们给每一个点击量增加一个权重K,当博客被点击一次后,评分会+K(后期可以引入收藏,多一个收藏,评分还可以继续增加)。这样可以保证热度比较高的博客的分数也比较高。
(3)为了提高系统的响应时间,我考虑使用了redis的zset来进行数据的缓存,zset是一个根据score进行排序的集合,我们正好可以根据文章的评分让zset对博客的顺序自动的进行排序,我们取数据时,是需要顺序读取即可。

具体zset的操作

当每篇文章进入系统时,根据时间戳算出他的基础分数,加入zset中,当用户点击文章时,修改这篇文章的分数,将分数加K,当删除一篇文章时,将这篇文章从zset中删除
(4)当需要获取博客列表时,只需要根据range顺序的从redis中取数据即可,zset提供了方法可以取到排名从start到end的博客数据,所以很简单的就可以实现博客的分页查询。

具体实现

  1. 配置redis环境,在springboot项目中实现对redis的存取。

配置文件:

spring:redis:host: r-bp1943b4a5673ef4pd.redis.rds.aliyuncs.comport: 6379password: xxxx

有关redis存取方法的实现:
spring data for redis 提供了RedisTemplate类,实现对redis数据库的快捷存取

    /*** redis zset添加元素  如果元素存在则会用新的score替换原来的* @param key* @param value* @param score* @return*/public boolean zsetAdd(String key,String value,double score){boolean result = false;try {redisTemplate.opsForZSet().add(key, value,score);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 删除元素 zset** @param key* @param value*/public void zsetRemove(String key, String value) {redisTemplate.opsForZSet().remove(key, value);}/*** 值增加score* @param key* @param value* @param score* @return*/public Double zsetIncrScore(String key, String value, double score) {return redisTemplate.opsForZSet().incrementScore(key, value, score);}/*** 获取value对应的score* 这个需要注意的是,当value在集合中时,返回其score;如果不在,则返回null* @param key* @param value* @return*/public Double score(String key, String value) {return redisTemplate.opsForZSet().score(key, value);}/*** 查询集合中指定顺序的值  zrevrange 返回有序的集合中,score大的在前面* @param key* @param start* @param end* @return*/public Set<String> zsetRevRange(String key, int start, int end) {return redisTemplate.opsForZSet().reverseRange(key, start, end);}

2.推荐算法的设计
具体的解释都在代码里完整的注释了出来

@Service
public class FreshPopularRecommended {@Resourceprivate RedisUtils redisUtils;@Resourceprivate ArticleDao articleDao;//一次点击率可以增加的得分private static int K = 2000;private static String ZSET_KEY = "article";/*** 根据流行度和新鲜度获取博客的列表   注意返回值为articleId组成的list* @param start  开始位置* @param end  结束位置  注意与数据库的limit offset不同* @return*/public List<Integer> getArticleByFreshPopular(int start,int end){Set<String> a = redisUtils.zsetRevRange(ZSET_KEY,start,end);List<Integer> result = new ArrayList<>();for(String str : a){result.add(Integer.valueOf(str));}return result;}/***   结合博客更新时间的时间戳和博客的点击量给 给每一个博客一个分数*   key为固定的 article  value为每个文章的id  score为文章的得分* @param article  新插入的博客* @throws ParseException*/public void setScore(Article article) throws ParseException {String updateTime = article.getUpdateTime();int ratingCount  = article.getRatingCount();SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");Date date = formatter.parse(updateTime);//updateTime的时间戳  时间戳是得分的基础double timeStamp = date.getTime();//给某个article设置一个得分redisUtils.zsetAdd(ZSET_KEY,String.valueOf(article.getId()),timeStamp + ratingCount *K);}/***当一个博客被点击后  点击量会+1 得分会增加K* @param articleId*/public void addScore(int articleId){redisUtils.zsetIncrScore(ZSET_KEY,String.valueOf(articleId),K);}/*** 当一个文章 被删除时  需要在redis删除它对应的分数* @param articleId*/public void deleteArticle(int articleId){redisUtils.zsetRemove(ZSET_KEY,String.valueOf(articleId));}
}

getArticleByFreshPopular方法可以根据范围,出去博客的id,最终返回到界面上。

3.给负责后端的同学一个方便调用的接口
他是需要调用这个方法,输入参数,就可以返回对应的articleId的列表了

  /*** 根据流行度和新鲜度获取博客的列表  可以进行分页查询(注意与 数据库的limit和offset不同 需要转化一下)* @param start   开始位置   start = offset* @param end   结束位置     end = offset+limit* @return   返回值为articleId组成的list*/public  List<Integer> recommendArticleByFreshPopular(int start,int end){return freshPopularRecommended.getArticleByFreshPopular(start,end);}

总结

基于流行度和新鲜度的推荐是比较基础的显示方法,所有的用户看到的内容都是相同的,接下来可能会个性化推荐的内容

创新实训(11)——推荐系统实现之基于流行度和新鲜度的推荐相关推荐

  1. 创新实训(1)——小组成员初步讨论,进行小组分工,明确项目范围项目范围

    小组讨论 1.小组成员通过qq群语音已经qq群分享屏幕的方式进行了几天的讨论:明确了项目的范围,项目需要完成的模块以及可能会使用到的技术细节.然后通过对每个人对相关技术的掌握,分配相应的工作.通过技术 ...

  2. 创新实训个人记录 : 个人工作总结

    创新实训个人记录 : 个人工作总结 分条目.分进度总结个人工作 阅读书籍(6.8-6.18) 近似算法设计(6.19-6.27) 程序验证(6.28-7.1) 工作难点 接触近似算法领域,学习新知识 ...

  3. 创新实训团队记录:为BR-MTC问题设计一个近似算法

    创新实训团队记录 : 为BR-MTC问题设计近似算法 阅读书籍和论文 近似算法设计思路变化总结 算法框架 改变初始顶点集 继续添加路径,作为新的初始顶点集 程序验证 近似解与最优解存在差距&& ...

  4. 创新实训(2)-Scrapy 学习

    创新实训(2)-Scrapy 学习 参考资料:Scrapy 0.25 文档 1.Scrapy简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理 ...

  5. 山东大学软件学院项目实训-创新实训-SDUMeeting(一)

    山东大学软件学院项目实训-创新实训-SDUMeeting(一) 一.前言: 这个项目是山东大学视频会议项目,这个项目基于webrtc构建多人视频会议系统,我负责视频会议客户端及服务端安全防护,这个专栏 ...

  6. 山东大学软件学院项目实训-创新实训-SDUMeeting(六)

    山东大学软件学院项目实训-创新实训-SDUMeeting(六) 端对端加密与密钥交换 端到端加密(end-to-end),是一种只有参与通讯的用户可以读取信息的通信系统.它可以防止潜在的窃听者--包括 ...

  7. 创新实训个人记录:approximation factor, maximum matchingvertex cover

    创新实训个人记录:approximation factor, maximum matching&&vertex cover approximation factor(近似比) maxi ...

  8. 创新实训个人记录:P versus NP

    创新实训个人记录:P versus NP computation&&computable&& computational efficiency 一些符号 decision ...

  9. 创新实训个人记录:metric k-center

    创新实训个人记录:metric k-center 一些概念 k-center(k-中心) dominating set(支配集) independent set(独立集) 独立集&&支 ...

  10. 国家开放大学计算机基础实训项目一,国家开放大学电大专科《微机系统与维护》网络课实训11及实训12作业及答案...

    国家开放大学电大专科<微机系统与维护>网络课实训11及实训12作业及答案 实训11 微机软件系统的维护实训报告 实训内容 操作系统维护工具的使用.注册表的维护.Windows优化大师软件的 ...

最新文章

  1. java数据结构堆_Java 数据结构-堆实现
  2. 这安全测试的面试题目也太简单了吧,分分钟入职成功
  3. 如何将记事本转换.php,记事本怎么变成表格?电脑便签如何将记事内容转化成Excel表格...
  4. [00004]-[2015-07-16]-[00]-[VC++ 开发Activity控件基础]
  5. python难度大吗_python需要学多久?自学两年也很难达到企业标准
  6. tomcat中 JVM 内存溢出及合理配置
  7. redis(redis概念,运用场景,如何操作基本数据类型)
  8. 最大乘积java_在Java中查找负数的最大乘积
  9. html设置按钮不同状态的背景图片,CSS实例:创建一个鼠标感应换图片的按钮
  10. python运维开发实战
  11. 【java】随机分组:设计一个GUI程序,可以用来随机分组功能,如小组作业、球赛赛程
  12. 我最喜爱的九位历史人物 - 苏轼(Space搬家)
  13. echarts关系图vue完整代码
  14. python解决中文显示问题Glyph 24179 (\N{CJK UNIFIED IDEOGRAPH-5E73}) missing from current font. func(*args)
  15. 39页大数据治理运营整体解决方案
  16. 查询某一日期所在的自然周,以周一为开始
  17. 1435 牛刀小试结构体
  18. java获取当前时间戳
  19. ajax检测用户名重复无效,用ajax实现检测注册用户名是否重复的完整例子
  20. 构件组装-总结与展望

热门文章

  1. 服务器主机性能,服务器主机性能分析
  2. 休闲实用英语:别误会这些英文的意思
  3. 繁荣 幸福 和平 PHP,松下幸之助——纯朴的心
  4. Dima and Lisa
  5. #读书笔记—《自控力》第一章
  6. 小菜鸟szx的测试博文
  7. 一张纸厚度是多少毫米_一张A4纸的厚度是多少mm?
  8. EPON+EOC 大批量设备网管解决方案
  9. 太阳神朱厚丞:揭秘2018年物联网发展趋势
  10. 什么软件测试卡路里,热量表(计算热量的仪表)_百度百科