Mahout之推荐

2024-06-18 18:08
文章标签 推荐 mahout

本文主要是介绍Mahout之推荐,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/huhui_cs/article/details/8596388

3 工程开发

3.1 推荐引擎简介

推荐引擎利用特殊的信息过滤(IF,Information Filtering)技术,将不同的内容(例如电影、音乐、书籍、新闻、图片、网页等)推荐给可能感兴趣的用户。通常情况下,推荐引擎的实现是通过将用户的个人喜好与特定的参考特征进行比较,并试图预测用户对一些未评分项目的喜好程度。参考特征的选取可能是从项目本身的信息中提取的,或是基于用户所在的社会或社团环境。
根据如何抽取参考特征,我们可以将推荐引擎分为以下四大类:
基于内容的推荐引擎:它将计算得到并推荐给用户一些与该用户已选择过的项目相似的内容。例如,当你在网上购书时,你总是购买与历史相关的书籍,那么基于内容的推荐引擎就会给你推荐一些热门的历史方面的书籍。
基于协同过滤的推荐引擎:它将推荐给用户一些与该用户品味相似的其他用户喜欢的内容。例如,当你在网上买衣服时,基于协同过滤的推荐引擎会根据你的历史购买记录或是浏览记录,分析出你的穿衣品位,并找到与你品味相似的一些用户,将他们浏览和购买的衣服推荐给你。
基于关联规则的推荐引擎:它将推荐给用户一些采用关联规则发现算法计算出的内容。关联规则的发现算法有很多,如 Apriori、AprioriTid、DHP、FP-tree 等。
混合推荐引擎:结合以上各种,得到一个更加全面的推荐效果。

3.2 Taste简介

       Taste 是 Apache Mahout 提供的一个协同过滤算法的高效实现,它是一个基于 Java 实现的可扩展的,高效的推荐引擎。Taste 既实现了最基本的基于用户的和基于内容的推荐算法,同时也提供了扩展接口,使用户可以方便的定义和实现自己的推荐算法。同时,Taste 不仅仅只适用于 Java 应用程序,它可以作为内部服务器的一个组件以 HTTP 和 Web Service 的形式向外界提供推荐的逻辑。


3.3 Taste工作原理

Taste 由以下五个主要的组件组成:
  • DataModel:DataModel 是用户喜好信息的抽象接口,它的具体实现支持从任意类型的数据源抽取用户喜好信息。Taste 默认提供 JDBCDataModel 和 FileDataModel,分别支持从数据库和文件中读取用户的喜好信息。
  • UserSimilarity 和 ItemSimilarity:UserSimilarity 用于定义两个用户间的相似度,它是基于协同过滤的推荐引擎的核心部分,可以用来计算用户的“邻居”,这里我们将与当前用户口味相似的用户称为他的邻居。ItemSimilarity 类似的,计算内容之间的相似度。
  • UserNeighborhood:用于基于用户相似度的推荐方法中,推荐的内容是基于找到与当前用户喜好相似的“邻居用户”的方式产生的。UserNeighborhood 定义了确定邻居用户的方法,具体实现一般是基于 UserSimilarity 计算得到的。
  • Recommender:Recommender 是推荐引擎的抽象接口,Taste 中的核心组件。程序中,为它提供一个 DataModel,它可以计算出对不同用户的推荐内容。实际应用中,主要使用它的实现类 GenericUserBasedRecommender 或者 GenericItemBasedRecommender,分别实现基于用户相似度的推荐引擎或者基于内容的推荐引擎。
 

                                                                 图1 Taste的主要组件图


3.4 基于Taste构建电影推荐引擎

3.4.1 数据下载

本工程所用到的数据来源于此处: http://www.grouplens.org/node/12 ,下载数据“MovieLens 1M - Consists of 1 million ratings from 6000 users on 4000 movies.”

这个数据文件夹下有三个文件:movies.dat,ratings.dat和users.dat,数据形式如下三个图所示:




movies.dat的文件描述是 电影编号::电影名::电影类别
ratings.dat的文件描述是 用户编号::电影编号::电影评分::时间戳
users.dat的文件描述是 用户编号::性别::年龄::职业::Zip-code

这些文件包含来自6040个MovieLens用户在2000年对约3900部电影的1000209个匿名评分信息。


3.4.2 构造数据库

构建推荐引擎,可以直接使用movie.dat文件作为数据源,也可以使用数据库中的数据作为数据源,本实验中,这两种方式都实现了,所以下面介绍利用dat文件建立数据库。
构建数据库的SQL语句如下:
[sql]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CREATE DATABASE movie;   
  2.  USE movie;   
  3.  CREATE TABLE movies (  // 保存电影相关的信息。  
  4.     id INTEGER NOT NULL AUTO_INCREMENT,   
  5.     name varchar(100) NOT NULL,   
  6.     published_year varchar(4) default NULL,   
  7.     type varchar(100) default NULL,   
  8.     PRIMARY KEY (id)   
  9.  );   
  10.  CREATE TABLE movie_preferences (  // 保存用户对电影的评分,即喜好程度  
  11.     userID INTEGER NOT NULL,   
  12.     movieID INTEGER NOT NULL,   
  13.     preference INTEGER NOT NULL DEFAULT 0,   
  14.     timestamp INTEGER not null default 0,   
  15.     FOREIGN KEY (movieID) REFERENCES movies(id) ON DELETE CASCADE   
  16.  );   
•Movie:表示电影,包含电影的基本信息:编号、名称、发布时间、类型等等。
•Movie Reference:表示某个用户对某个电影的喜好程度,包含用户编号、电影编号、用户的评分以及评分的时间。
至于如何将dat文件中的内容导入到MySQL数据库中,分别由本工程目录文件下的ImportMovies.java和ImportRatings.java文件实现。

MySQL数据库中的数据如下图:


                                                                                                                                                                图二 movie_preferences表记录


                                                                                                                                                                    图三 movies表记录

3.4.3 推荐引擎实现

在本工程中,我实现了三种方式的推荐引擎:基于用户相似度的推荐引擎,基于内容相似度的推荐引擎,以及基于Slope One 的推荐引擎。在这些推荐引擎中,我分别使用了三种DataModel,即Database-based DataModel,File-based DataModel和In-memory DataModel。
a) 基于用户相似度的推荐引擎
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MyUserBasedRecommender {  
  2.     public List<RecommendedItem> userBasedRecommender(long userID,int size) {  
  3.         // step:1 构建模型 2 计算相似度 3 查找k紧邻 4 构造推荐引擎  
  4.         List<RecommendedItem> recommendations = null;  
  5.         try {  
  6.             DataModel model = MyDataModel.myDataModel();//构造数据模型,Database-based  
  7.             UserSimilarity similarity = new PearsonCorrelationSimilarity(model);//用PearsonCorrelation 算法计算用户相似度  
  8.             UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, similarity, model);//计算用户的“邻居”,这里将与该用户最近距离为 3 的用户设置为该用户的“邻居”。  
  9.             Recommender recommender = new CachingRecommender(new GenericUserBasedRecommender(model, neighborhood, similarity));//构造推荐引擎,采用 CachingRecommender 为 RecommendationItem 进行缓存  
  10.             recommendations = recommender.recommend(userID, size);//得到推荐的结果,size是推荐接过的数目  
  11.         } catch (Exception e) {  
  12.             // TODO: handle exception  
  13.             e.printStackTrace();  
  14.         }  
  15.         return recommendations;  
  16.     }  
  17.   
  18.   
  19.     public static void main(String args[]) throws Exception {  
  20.   
  21.     }  
  22. }  


在这个推荐引擎中,由于使用的是MySQLJDBCDataModel和JNDI,所以需要在tomcat的server.xml文件中添加如下信息:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <Context path="/MyRecommender" docBase="/home/huhui/develop/apache-tomcat-6.0.35/webapps/MyRecommender" debug="0" reloadable="true">  
  2.                 <Resource name="jdbc/movie" auth="Container" type="javax.sql.DataSource"  
  3.                         username="root"  
  4.                         password="***"  
  5.                         driverClassName="com.mysql.jdbc.Driver"  
  6.                         url="jdbc:mysql://localhost:3306/movie"  
  7.                         maxActive="15"  
  8.                         maxIdle="7"  
  9.                         defaultTransactionIsolation="READ_COMMITTED"  
  10.                         validationQuery="Select 1" />  
  11. </Context>  

Mahout 中提供了基本的相似度的计算,它们都实现了 UserSimilarity 这个接口,以实现用户相似度的计算,包括下面这些常用的:
•PearsonCorrelationSimilarity:基于皮尔逊相关系数计算相似度   (它表示两个数列对应数字一起增大或一起减小的可能性。是两个序列协方差与二者方差乘积的比值)
•EuclideanDistanceSimilarity:基于欧几里德距离计算相似度
•TanimotoCoefficientSimilarity:基于 Tanimoto 系数计算相似度


根据建立的相似度计算方法,找到邻居用户。这里找邻居用户的方法根据前面我们介绍的,也包括两种:“固定数量的邻居”和“相似度门槛邻居”计算方法,Mahout 提供对应的实现:
•NearestNUserNeighborhood:对每个用户取固定数量 N 的最近邻居
•ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度门限内的所有用户为邻居。


基于 DataModel,UserNeighborhood 和 UserSimilarity 构建 GenericUserBasedRecommender,从而实现基于用户的推荐策略。


b) 基于内容相似度的推荐引擎
理解了基于用户相似读的推荐引擎,基于内容相似读的推荐引擎类似,甚至更加简单。
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MyItemBasedRecommender {  
  2.     public List<RecommendedItem> myItemBasedRecommender(long userID,int size){  
  3.         List<RecommendedItem> recommendations = null;  
  4.         try {  
  5.             DataModel model = new FileDataModel(new File("/home/huhui/movie_preferences.txt"));//构造数据模型,File-based  
  6.             ItemSimilarity similarity = new PearsonCorrelationSimilarity(model);//计算内容相似度  
  7.             Recommender recommender = new GenericItemBasedRecommender(model, similarity);//构造推荐引擎  
  8.             recommendations = recommender.recommend(userID, size);//得到推荐接过  
  9.         } catch (Exception e) {  
  10.             // TODO: handle exception  
  11.             e.printStackTrace();  
  12.         }  
  13.         return recommendations;  
  14.     }  
  15. }  

在这个推荐引擎中,使用的是File-based Datamodel,数据文件格式如下图所示:
 

每一行都是一个简单的三元组< 用户 ID, 物品 ID, 用户偏好 >。


c) 基于Slop One的推荐引擎
基于用户和基于内容是最常用最容易理解的两种推荐策略,但在大数据量时,它们的计算量会很大,从而导致推荐效率较差。因此 Mahout 还提供了一种更加轻量级的 CF 推荐策略:Slope One。
Slope One 是有 Daniel Lemire 和 Anna Maclachlan 在 2005 年提出的一种对基于评分的协同过滤推荐引擎的改进方法,下面简单介绍一下它的基本思想。
假设系统对于物品 A,物品 B 和物品 C 的平均评分分别是 3,4 和 4。基于 Slope One 的方法会得到以下规律:
•用户对物品 B 的评分 = 用户对物品 A 的评分 + 1
•用户对物品 B 的评分 = 用户对物品 C 的评分
基于以上的规律,我们可以对用户 A 和用户 B 的打分进行预测:
•对用户 A,他给物品 A 打分 4,那么我们可以推测他对物品 B 的评分是 5,对物品 C 的打分也是 5。
•对用户 B,他给物品 A 打分 2,给物品 C 打分 4,根据第一条规律,我们可以推断他对物品 B 的评分是 3;而根据第二条规律,推断出评分是 4。当出现冲突时,我们可以对各种规则得到的推断进行就平均,所以给出的推断是 3.5。
这就是 Slope One 推荐的基本原理,它将用户的评分之间的关系看作简单的线性关系:
Y = mX + b;
当 m = 1 时就是 Slope One,也就是我们刚刚展示的例子。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MySlopeOneRecommender {  
  2.     public List<RecommendedItem> mySlopeOneRecommender(long userID,int size){  
  3.         List<RecommendedItem> recommendations = null;  
  4.         try {  
  5.             DataModel model = new FileDataModel(new File("/home/huhui/movie_preferences.txt"));//构造数据模型  
  6.             Recommender recommender = new CachingRecommender(new SlopeOneRecommender(model));//构造推荐引擎  
  7.             recommendations = recommender.recommend(userID, size);//得到推荐结果  
  8.         } catch (Exception e) {  
  9.             // TODO: handle exception  
  10.             e.printStackTrace();  
  11.         }  
  12.         return recommendations;  
  13.     }  
  14. }  


d) 对数据模型的优化——In-memory DataModel
上面所叙述的三种推荐引擎,输入的都是用户的历史偏好信息,在 Mahout 里它被建模为 Preference(接口),一个 Preference 就是一个简单的三元组 < 用户 ID, 物品 ID, 用户偏好 >,它的实现类是 GenericPreference,可以通过以下语句创建一个 GenericPreference:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. GenericPreference preference = new GenericPreference(11014.0f);  
这其中, 1是用户 ID,long 型;101是物品 ID,long 型;4.0f 是用户偏好,float 型。从这个例子可以看出,一个 GenericPreference 的数据就占用8+8+4=20 字节,所以如果只简单实用数组 Array 加载用户偏好数据,必然占用大量的内存,Mahout 在这方面做了一些优化,它创建了 PreferenceArray(接口)保存一组用户偏好数据,为了优化性能,Mahout 给出了两个实现类,GenericUserPreferenceArray 和 GenericItemPreferenceArray,分别按照用户和物品本身对用户偏好进行组装,这样就可以压缩用户 ID 或者物品 ID 的空间。
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. FastByIDMap<PreferenceArray> preferences = new FastByIDMap<PreferenceArray>();  
  2.   
  3.   
  4. PreferenceArray prefsForUser1 = new GenericUserPreferenceArray(3);// 注意这里的数字  
  5. // 这里是用来存储一个用户的元数据,这些元数据通常来自日志文件,比如浏览历史,等等,不同的业务场合,它的业务语义是不一样  
  6.   
  7. prefsForUser1.setUserID(01);  
  8.   
  9. prefsForUser1.setItemID(0101);  
  10. prefsForUser1.setValue(05.0f);//<1, 101, 5.0f>         < 用户 ID, 物品 ID, 用户偏好 >  
  11.   
  12.   
  13. prefsForUser1.setItemID(1102);  
  14. prefsForUser1.setValue(13.0f);//<1, 102, 3.0f>  
  15.   
  16.   
  17. prefsForUser1.setItemID(2103);  
  18. prefsForUser1.setValue(22.5f);//<1, 103, 2.5f>  
  19.   
  20.   
  21. preferences.put(1l, prefsForUser1);// 在这里添加数据,userID作为key  
  22. ........  

由于代码比较长,此处就不全部贴出来,详见工程文件中的RecommenderIntro.java文件。


4 程序演示

这个项目工程是B/S模式的,基于MVC开发模式开发的,开发环境是Ubuntu,IDE是MyEclipse8.0,工程文件目录如下图:
 
                           图四 工程文件目录


                                                                                      主要类文件之间的关系


项目首页提供三个输入:用户id,推荐电影的数目(默认为25),推荐策略。


                                                                 图五 首页



                                                                                                      图六 编号为10的用户,基于用户相似度的推荐结果


 
                                                                                                              图七 编号为10的用户,基于内容相似度的推荐结果


 

                                                        


这篇关于Mahout之推荐的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072725

相关文章

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

Java中实现订单超时自动取消功能(最新推荐)

《Java中实现订单超时自动取消功能(最新推荐)》本文介绍了Java中实现订单超时自动取消功能的几种方法,包括定时任务、JDK延迟队列、Redis过期监听、Redisson分布式延迟队列、Rocket... 目录1、定时任务2、JDK延迟队列 DelayQueue(1)定义实现Delayed接口的实体类 (

shell脚本自动删除30天以前的文件(最新推荐)

《shell脚本自动删除30天以前的文件(最新推荐)》该文章介绍了如何使用Shell脚本自动删除指定目录下30天以前的文件,并通过crontab设置定时任务,此外,还提供了如何使用Shell脚本删除E... 目录shell脚本自动删除30天以前的文件linux按照日期定时删除elasticsearch索引s

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

MySql9.1.0安装详细教程(最新推荐)

《MySql9.1.0安装详细教程(最新推荐)》MySQL是一个流行的关系型数据库管理系统,支持多线程和多种数据库连接途径,能够处理上千万条记录的大型数据库,本文介绍MySql9.1.0安装详细教程,... 目录mysql介绍:一、下载 Mysql 安装文件二、Mysql 安装教程三、环境配置1.右击此电脑

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最