推荐系统概述

推荐系统概述

推荐算法分类:

按数据使用划分:

  • 协同过滤算法:UserCF, ItemCF, ModelCF
  • 基于内容的推荐: 用户内容属性和物品内容属性
  • 社会化过滤:基于用户的社会网络关系

按模型划分:

  • 最近邻模型:基于距离的协同过滤算法
  • Latent Factor Mode(SVD):基于矩阵分解的模型
  • Graph:图模型,社会网络图模型

基于用户的协同过滤算法UserCF

基于用户的协同过滤,通过不同用户对物品的评分来评测用户之间的相似性,基于用户之间的相似性做出推荐。简单来讲就是:给用户推荐和他兴趣相似的其他用户喜欢的物品。

基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量 来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。图 2 给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 – 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。

基于物品的协同过滤算法ItemCF

于item的协同过滤,通过用户对不同item的评分来评测item之间的相似性,基于item之间的相似性做出推荐。简单来讲就是:给用户推荐和他之前喜欢的物品相似的物品。

基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算 的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的 物品,计算得到一个排序的物品列表作为推荐。图 3 给出了一个例子,对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出用户 C 可能也喜欢物品 C。

注:基于物品的协同过滤算法,是目前商用最广泛的推荐算法。

协同过滤算法实现,分为2个步骤

  1. 计算物品之间的相似度
  2. 根据物品的相似度和用户的历史行为给用户生成推荐列表

Mathout:

东西太多……还是自己看博客吧

  • 从源代码剖析Mahout推荐引擎
  • Mahout推荐算法API详解

实战

数据源

取数据库t_recent_listen_00数据,总数据5323626条,导出sql文件导入本地数据库
导入时间大约15个小时后中断,删除user_id为0的数据等数据清理操作,共导入了2019-02-16及之前的收听记录,总条数4866861条

  • 节目收听记录538805条
  • 书籍收听记录3842982条
  • 阅读记录484644条

生成csv格式文件

  • book_csv_file.csv
  • album_csv_file.csv
  • read_csv_file.csv

python生成csv

import pymysql
import csv
import sys
import osclass ToCsv:def __init__(self):self.db = pymysql.connect(host='', user='', passwd='', port=3306, db='hi')self.cursor = self.db.cursor()self.last_id = 0self.count = 0self.book_count = 0self.album_count = 0self.read_count = 0def _release_db(self):self.db.close()self.cursor.close()def _do(self):while 1:ret = self._search_data()if ret == 0:breakdef _search_data(self):self.cursor.size = 50sql = 'select * from t_recent_listen_00 where id>%s limit 50'self.cursor.execute(sql, self.last_id)lines = self.cursor.fetchall()if (len(lines) > 0):self.last_id = lines[len(lines)-1][0]self.count = len(lines) + self.count;self._write_cvs(lines)if (self.count % 1000 == 0):print(self.count)return len(lines)# print(self.last_id)def _write_cvs(self, lines):for item in lines:if (item[10] == 4):book_cvs_file = open('book_csv_file.csv', 'a', newline='')book_writers = csv.writer(book_cvs_file)# book_writers.writerow(['user_id', 'book_id'])user_id = item[1]book_id = item[2]self.book_count += 1if (self.book_count % 1000 == 0):print("book count", self.book_count)book_writers.writerow([str(user_id), str(book_id)])if (item[10] == 2):album_cvs_file = open('album_csv_file.csv', 'a', newline='')album_writers = csv.writer(album_cvs_file)# album_writers.writerow(['user_id', 'book_id'])user_id = item[1]book_id = item[2]self.album_count += 1if (self.album_count % 1000 == 0):print("album count", self.album_count)album_writers.writerow([str(user_id), str(book_id)])if (item[10] == 10):read_cvs_file = open('read_csv_file.csv', 'a', newline='')read_writers = csv.writer(read_cvs_file)# album_writers.writerow(['user_id', 'book_id'])user_id = item[1]book_id = item[2]self.read_count += 1if (self.read_count % 1000 == 0):print("read count", self.read_count)read_writers.writerow([str(user_id), str(book_id)])def main(self):passif __name__ == '__main__':c = ToCsv()c._do()c._release_db()

简单讲解一下,就是读数据库,每次查询50条并写在csv文件最后,自己写的demo写注释太累了

book_csv_file.csv文件大小60M

java实现推荐系统

pom.xml

  <properties><mahout.version>0.9</mahout.version></properties><dependencies>...<dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-core</artifactId><version>${mahout.version}</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-integration</artifactId><version>${mahout.version}</version><exclusions><exclusion><groupId>org.mortbay.jetty</groupId><artifactId>jetty</artifactId></exclusion><exclusion><groupId>org.apache.cassandra</groupId><artifactId>cassandra-all</artifactId></exclusion><exclusion><groupId>me.prettyprint</groupId><artifactId>hector-core</artifactId></exclusion></exclusions></dependency></dependencies>

MahoutController

@RestController
@Slf4j
@RequestMapping("/")
public class MahoutController {@GetMappingpublic List<RecommendedItem> mahout(@RequestParam String userId,@RequestParam int type){//数据模型DataModel model = null;List<RecommendedItem> list = Lists.newArrayList();File cvsFile = null;try {long startTime = System.currentTimeMillis();
//            File bookCsvFile = ResourceUtils.getFile("classpath:csv/book_cvs_file.csv");if (type == 1) {cvsFile = new File("E:\\code\\python\\to_csv\\book_csv_file.csv");}else if(type == 2){cvsFile = new File("E:\\code\\python\\to_csv\\read_csv_file.csv");}else if(type == 3){cvsFile = new File("E:\\code\\python\\to_csv\\album_csv_file.csv");}model = new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(new FileDataModel(cvsFile)));ItemSimilarity item=new LogLikelihoodSimilarity(model);//物品推荐算法Recommender r=new GenericItemBasedRecommender(model,item);list = r.recommend(Long.parseLong(userId), 10);list.forEach(System.out::println);long endTime = System.currentTimeMillis();log.info((endTime-startTime) +"");} catch (IOException e) {e.printStackTrace();} catch (TasteException e) {e.printStackTrace();}return list;}@GetMapping("/user")public List<RecommendedItem> mahoutUser(@RequestParam String userId,@RequestParam int type){//数据模型DataModel model = null;List<RecommendedItem> list = Lists.newArrayList();File cvsFile = null;try {long startTime = System.currentTimeMillis();
//            File bookCsvFile = ResourceUtils.getFile("classpath:csv/book_cvs_file.csv");if (type == 1) {cvsFile = new File("E:\\code\\python\\to_csv\\book_csv_file.csv");}else if(type == 2){cvsFile = new File("E:\\code\\python\\to_csv\\read_csv_file.csv");}else if(type == 3){cvsFile = new File("E:\\code\\python\\to_csv\\album_csv_file.csv");}model = new FileDataModel(cvsFile);//用户相识度算法UserSimilarity userSimilarity=new LogLikelihoodSimilarity(model);UserNeighborhood neighborhood = new NearestNUserNeighborhood(20,userSimilarity, model);Recommender r=new GenericUserBasedRecommender(model, neighborhood, userSimilarity);list = r.recommend(Long.parseLong(userId), 10);list.forEach(System.out::println);long endTime = System.currentTimeMillis();log.info((endTime-startTime) +"");} catch (IOException e) {e.printStackTrace();} catch (TasteException e) {e.printStackTrace();}return list;}
}

根据传入user_id来计算出推荐的物品id

结果

测试基于用户协同过滤和基于物品协同过滤输出结果

380万的数据计算一次需要4-6秒,如果实时解析文件生成推荐内容明显会拖累接口相应速度

测试结果还有一点,因为数据的问题csv只生成了用户id与物品id的对应关系,并没有生成用户对物品的打分数据,在实际过程中可以通过最近收听的数据库记录,计算用户听了改资源多长时间来判断用户对物品的喜好程度。
基于用户协同过滤和基于物品协同过滤输出的结果迥异,代码中物品协同过滤算法在不同用户id下返回的数据重复性很高,不大使用,而相比之下,代码中用户协同过滤算法在不同用户id下返回数据看起来比较可靠。实际开发过程中也需要对实际的数据进行判断,否则无法进行很好的推荐,反而会变成一个用户体验很差的功能。

小结

单机版的mahout在实际开发过程中无法胜任实时推荐,特别是在大数量的情况下。
可以考虑后台启动定时任务,每天/每周生成csv文件(python代码中生成csv的代码查数据库很慢……生成了N个小时,java应该会好一些),再通过定时任务计算用户并保存不同用户的不同推荐内容(需要根据实际情况进行判断,毕竟这个量也不小)

Java实现算法推荐:Mahout实践相关推荐

  1. Java开发在线购物推荐网 购物商城推荐系统 基于用户、物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、人工智能、机器学习项目开发

    Java开发在线购物推荐网 购物商城推荐系统 基于用户.物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据.人工智能.机器学习项目开发Sh ...

  2. 基于KMeans聚类的协同过滤推荐算法推荐原理、过程、代码实现 Canopy聚类算法 KMeans+Canopy聚类算法 聚类算法程序实现 KMEans聚类算法代码java

    基于KMeans聚类的协同过滤推荐算法可运用于基于用户和基于项目的协同过滤推荐算法中,作为降低数据稀疏度和提高推荐准确率的方法之一,一个协同过滤推荐过程可实现多次KMeans聚类. 一.基于KMean ...

  3. Java进阶书籍推荐,赶快收藏起来!

    最近有很多学习或者已经在工作的java技术的同学都想要更进一步的提升自己,那么阅读书籍可以给大家带来帮助.今天,小千将分享过去几年中一些最好的Java进阶书籍,您可以在2021年阅读这些书籍,以更好地 ...

  4. java hadoop mahout_hadoop 之Mahout 数据挖掘

    Mahout 仅提供一些java的算法包,通过Mahout执行这些算法包,并把hdfs上的文件作为输入可以在hadoop上做分布式计算 提供的常用算法 Mahout 提供了常用算法的程序库,可以基于分 ...

  5. java进阶书籍推荐(不包括基础)

    java进阶书籍推荐(不包括基础) 个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 &q ...

  6. java python算法_用Python,Java和C ++示例解释的排序算法

    java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...

  7. 人工智能、大数据的广泛应用,算法推荐如何守好边界

    来源:人民数据 本文共2000字,建议阅读5分钟 人工智能.大数据的广泛应用,给互联网平台带来了自动化的算法技术. 人工智能.大数据的广泛应用,给互联网平台带来了自动化的算法技术.一方面,互联网平台利 ...

  8. 机器学习算法与Python实践之(三)支持向量机(SVM)进阶

    机器学习算法与Python实践这个系列主要是参考<机器学习实战>这本书.因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学 ...

  9. 机器学习算法与Python实践之(二)支持向量机(SVM)初

    机器学习算法与Python实践这个系列主要是参考<机器学习实战>这本书.因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学 ...

最新文章

  1. 服务器清理c盘日志文件,清理WIN2003服务器C盘垃圾的批处理
  2. [云炬python3玩转机器学习笔记] 2-7开发环境搭建笔记
  3. i2c--insmod
  4. Mysql中行转列和列转行
  5. 腾讯首度披露基础架构演进史:“海量之道”进化“生而为云”
  6. java变量数据类型_java变量与数据类型
  7. element UI Cascader 级联选择器 动态加载次级选项
  8. java静态变量重复new_Java非静态成员变量之死循环(详解)
  9. 剑指offer38 数字在排序数组中出现的次数
  10. 关于解决MyEclipse的耗内存的办法
  11. JavaScript中的match方法和search方法
  12. C语言:编写一个程序,求s=1+(1+2)+(1+2+3)+....+(1+2+3+....+n)的值。
  13. 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员……
  14. 172篇文献:NUS颜水成等发布首篇《深度长尾学习》综述
  15. python 编程自学手册 pdf-跪求《python学习手册》(第五版)pdf中文版!/
  16. eclipse:设置maven本地仓库
  17. SPACEMACS 配置
  18. 工程项目管理系统java程序,基于jsp的工程项目管理系统-JavaEE实现工程项目管理系统 - java项目源码...
  19. Swiper 参数说明
  20. Android 界面一键变灰/黑白

热门文章

  1. 【Arcmap导出地图】可控制影像精度
  2. Lucene布尔查询
  3. 设计模式之策略模式(实例+Demo)
  4. iptable防火墙
  5. vs2019中打开qt中的后缀.ui文件提示未能完成操作,未指定的错误
  6. 2023年了现在想入局shopee可以吗?
  7. 猫冬的jQuery formValidator 插件和演示地址
  8. java截取数组_JS Array.slice 截取数组的实现方法
  9. Electronic Commerce_ywyuan_新浪博客
  10. 基于Apache Spark机器学习的客户流失预测