Mahout学习系列之推荐算法

摘要:
UserSimilarity用于定义两个用户之间的相似性。它是基于协作过滤的推荐引擎的核心部分,可用于计算用户的“邻居”。这里,我们指的是与邻居口味相似的用户。ItemSimilarity的相似之处在于它计算内容之间的相似性。UserNeighborhood用于基于用户相似度的推荐方法。基于查找与当前用户具有相似偏好的邻居用户的方式来生成推荐内容。推荐器是推荐引擎的抽象接口,也是Taste的核心组件。推荐IRStatsEvaluator:收集推荐的绩效相关指标,包括准确性、召回率等。

转载请注明出处:http://blog.csdn.net/gamer_gyt 
博主微博:http://weibo.com/234654758 
Github:https://github.com/thinkgamer

参考:

从源代码剖析Mahout推荐引擎      

mahout 推荐系统示例       

Mahout推荐算法API详解

使用Mahout实现协同过滤 

Mahout的taste推荐系统里的几种Recommender分析


前言:Mahout框架集成了大量的常用的机器学习算法,且都支持在Hadoop分布式环境下运行,很大程度上节约了数据处理的时间成本,其中的推荐算法引擎有cf.taste包实现,它提供了一套完整的推荐算法工具库,同时规范了数据结构,并标准了程序开发过程。

1:Mahout推荐算法介绍

2:Taste接口相关介绍

3:单机内存算法实现

4:基于hadoop分布式算法的实现

5:算法评判标准



一:Mahout推荐算法介绍

我们先看看一下org.apache.mahout.cf.taste如下图所示

Mahout学习系列之推荐算法第1张

packages的说明:

common:公共类包括,异常,数据刷新接口,权重常量

eval:定义构造器接口,类似于工厂模式(什么是工厂模式请参考:http://blog.chinaunix.net/uid-25958655-id-4243289.html

model:定义数据类型接口
neighborhood:定义近邻算法的接口
recommender:定义推荐算法的接口
similarity:定义相似度算法接口
transforms:定义数据转换接口
hadoop:基于hadoop的分布式算法的实现类
impl:单机内存算法实现类
从上面的packages情况来看,可以粗略的看出推荐引擎分为5个主要部分组成:数据模型,相似度算法,近邻算法,推荐算法,算法评分器
从数据处理能力上看,算法可以分为:单机内存算法,基于hadoop的分布式算法



二:Taste接口相关介绍

Mahout学习系列之推荐算法第2张

Mahout使用了Taste来提交协同过滤算法的实现,它是一个基于Java实现的可扩展的,高效的推荐系统,Taste既实现了最基本的基于用户的和基于内容的推荐算法,同时也提供了扩展接口,使用户可以方便的定义和实现自己的推荐算法,同时,Taste不仅仅只适用于Java应用程序,它可以作为内部服务器的一个组件以HTTP和Web Service的形式向外界提供推荐的逻辑,Taste的设计使它能满足企业对推荐引擎在性能,灵活性和可扩展性等方面的要求。

Taste主要包括以下几个接口:

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

目前,Mahout为DataModel提供了以下几种实现:

  • org.apache.mahout.cf.taste.impl.model.GenericDataModel
  • org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel
  • org.apache.mahout.cf.taste.impl.model.PlusAnonymousUserDataModel
  • org.apache.mahout.cf.taste.impl.model.file.FileDataModel
  • org.apache.mahout.cf.taste.impl.model.hbase.HBaseDataModel
  • org.apache.mahout.cf.taste.impl.model.cassandra.CassandraDataModel
  • org.apache.mahout.cf.taste.impl.model.mongodb.MongoDBDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.SQL92JDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.PostgreSQLJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.GenericJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.SQL92BooleanPrefJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.MySQLBooleanPrefJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.PostgreBooleanPrefSQLJDBCDataModel
  • org.apache.mahout.cf.taste.impl.model.jdbc.ReloadFromJDBCDataModel

从类名上就可以大概猜出来每个DataModel的用途,奇怪的是竟然没有HDFS的DataModel,有人实现了一个,请参考 MAHOUT-1579 。

UserSimilarity 和 ItemSimilarity 相似度实现有以下几种:

  • CityBlockSimilarity :基于Manhattan距离相似度
  • EuclideanDistanceSimilarity :基于欧几里德距离计算相似度
  • LogLikelihoodSimilarity :基于对数似然比的相似度
  • PearsonCorrelationSimilarity :基于皮尔逊相关系数计算相似度
  • SpearmanCorrelationSimilarity :基于皮尔斯曼相关系数相似度
  • TanimotoCoefficientSimilarity :基于谷本系数计算相似度
  • UncenteredCosineSimilarity :计算 Cosine 相似度

以上相似度的说明,请参考Mahout推荐引擎介绍。

UserNeighborhood 主要实现有两种:

  • NearestNUserNeighborhood:对每个用户取固定数量N个最近邻居
  • ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度限制以内的所有用户为邻居

Recommender分为以下几种实现:

  • GenericUserBasedRecommender:基于用户的推荐引擎
  • GenericBooleanPrefUserBasedRecommender:基于用户的无偏好值推荐引擎
  • GenericItemBasedRecommender:基于物品的推荐引擎
  • GenericBooleanPrefItemBasedRecommender:基于物品的无偏好值推荐引擎

RecommenderEvaluator有以下几种实现:

  • AverageAbsoluteDifferenceRecommenderEvaluator :计算平均差值
  • RMSRecommenderEvaluator :计算均方根差

RecommenderIRStatsEvaluator的实现类是GenericRecommenderIRStatsEvaluator。

三:单机内存算法实现

Mahout推荐算法API详解
单机算法实现:就是在单机环境下运行的算法,是由cf.taste项目实现的,象我们熟悉的User_CF,Item_CF都是支持单机运行的,并且参数可以灵活配置,单机算法实现的实例如下:
测试数据集如下:/home/thinkgamer/test.txt

单机算法实现参考:

mahout 推荐系统示例

1,101,5
1,102,3
1,103,2.5
2,101,2
2,102,2.5
2,103,5
2,104,2
3,101,2.5
3,104,4
3,105,4.5
3,107,5
4,101,5
4,103,3
4,104,4.5
4,106,4
5,101,4
5,102,3
5,103,2
5,104,4
5,105,3.5
5,106,4

实现的代码如下:

  1.  
    package tuijian_alone;
  2.  
     
  3.  
    import java.io.*;
  4.  
    import java.util.*;
  5.  
    import org.apache.mahout.cf.taste.common.TasteException;
  6.  
    import org.apache.mahout.cf.taste.impl.model.file.*;
  7.  
    import org.apache.mahout.cf.taste.impl.neighborhood.*;
  8.  
    import org.apache.mahout.cf.taste.impl.recommender.*;
  9.  
    import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
  10.  
    import org.apache.mahout.cf.taste.impl.similarity.*;
  11.  
    import org.apache.mahout.cf.taste.model.*;
  12.  
    import org.apache.mahout.cf.taste.neighborhood.*;
  13.  
    import org.apache.mahout.cf.taste.recommender.*;
  14.  
    import org.apache.mahout.cf.taste.similarity.*;
  15.  
     
  16.  
     
  17.  
    public class tuijian_alone {
  18.  
    // private TestMahout(){};
  19.  
     
  20.  
     
  21.  
    public static void main(String args[]) throws Exception {
  22.  
     
  23.  
    tuijian_alone testMahout = new tuijian_alone();
  24.  
    System.out.println("The baseUserCF Result:");
  25.  
    testMahout.baseUserCF();
  26.  
    System.out.println("The baseItemCF Result:");
  27.  
    testMahout.baseItemCF();
  28.  
    System.out.println("The baseSlopOne Result:");
  29.  
    testMahout.baseSlopOne();
  30.  
    }
  31.  
    //基于用户相似度的协同过滤推荐实现
  32.  
    public void baseUserCF(){
  33.  
    try {
  34.  
    // 1,构建模型
  35.  
    DataModel dataModel = new FileDataModel(new File("../test.txt"));
  36.  
    //2,计算相似度
  37.  
    UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(dataModel);
  38.  
    //3,查找K近邻
  39.  
    UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(2, userSimilarity, dataModel);
  40.  
    //4,构造推荐引擎
  41.  
    Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, userSimilarity);
  42.  
    //为用户i推荐2个item
  43.  
    for(int i=1;i<6;i++){
  44.  
    System.out.println("recommand for user:" + i);
  45.  
    List recommendations = recommender.recommend(i, 2);
  46.  
    for (RecommendedItem recommendation:recommendations){
  47.  
    System.out.println(recommendation);
  48.  
    }
  49.  
    }
  50.  
    }catch(IOException e){
  51.  
    e.printStackTrace();
  52.  
    }catch(TasteException e){
  53.  
    e.printStackTrace();
  54.  
    }
  55.  
    }
  56.  
     
  57.  
    //基于内容相似度的协同过滤推荐实现
  58.  
    public void baseItemCF(){
  59.  
    DataModel model;
  60.  
    try {
  61.  
    model = new FileDataModel(new File("../test.txt"));
  62.  
    ItemSimilarity itemsimilarity =new PearsonCorrelationSimilarity(model);
  63.  
    Recommender recommender= new GenericItemBasedRecommender(model,itemsimilarity);
  64.  
    List recommendations =recommender.recommend(1, 4);
  65.  
    for(RecommendedItem recommendation :recommendations){
  66.  
    System.out.println(recommendation);
  67.  
    }
  68.  
    } catch (IOException e) {
  69.  
    // TODO Auto-generated catch block
  70.  
    e.printStackTrace();
  71.  
    } catch (TasteException e) {
  72.  
    // TODO Auto-generated catch block
  73.  
    e.printStackTrace();
  74.  
    }
  75.  
     
  76.  
    }
  77.  
    //基于SlopOne的推荐实现
  78.  
    public void baseSlopOne(){
  79.  
    DataModel model;
  80.  
    try {
  81.  
    model = new FileDataModel(new File("/home/thinkgamer/Java/hadoop_shizhan/src/tuijian_alone/test.txt"));
  82.  
    Recommender recommender= new SlopeOneRecommender(model);
  83.  
    List recommendations =recommender.recommend(1, 4);
  84.  
    for(RecommendedItem recommendation :recommendations){
  85.  
    System.out.println(recommendation);
  86.  
    }
  87.  
    } catch (IOException e) {
  88.  
    // TODO Auto-generated catch block
  89.  
    System.out.println("Io Error");
  90.  
    e.printStackTrace();
  91.  
    } catch (TasteException e) {
  92.  
    // TODO Auto-generated catch block
  93.  
    System.out.println("Taste Error");
  94.  
    e.printStackTrace();
  95.  
    }
  96.  
     
  97.  
    }
  98.  
     
  99.  
    }

运行结果如下图所示:

Mahout学习系列之推荐算法第3张

单机内存算法的问题在于:受限于单机的资源,对于中等规模的数据,有能力计算,但是超过100G的数据对于单机来说是不可能完成的任务

四:基于Hadoop分布式算法实现

基于hadoop分布式算法的实现,就是把单机内存算法并行优化,把任务分散到多个计算机上一起运行,Mahout提供了基于ItemCFhadoop并行化算法实现,基于hadoop分布式算法实现参考:Mahout分步式程序开发 基于物品的协同过滤ItemCF

分布式算法的问题在于,如何让单机算法并行化,在单机算法中,我们只需要考虑算法,数据结构,内存,CPU就够了,但是分布式算法还要额外考虑很多情况,比如多结点的数据合并,数据排序,网络通信故障,节点宕机重算,数据分布式存储等等很多问题

并行化算法实现参考:用Mahout构建职位推荐引擎   

五:算法评判标准:召回率(recall)与查准率(precision)

Mahout提供了2个评估推荐器的指标,查准率和召回率(查全率),这两个指标是搜索引擎中经典的度量方法。

Mahout学习系列之推荐算法第4张

  1.  
    相关 不相关
  2.  
    检索到 A C
  3.  
    未检索到 B D
  • A:检索到的,相关的 (搜到的也想要的)
  • B:未检索到的,但是相关的 (没搜到,然而实际上想要的)
  • C:检索到的,但是不相关的 (搜到的但没用的)
  • D:未检索到的,也不相关的 (没搜到也没用的)

被检索到的越多越好,这是追求“查全率”,即A/(A+B),越大越好。
被检索到的,越相关的越多越好,不相关的越少越好,这是追求“查准率”,即A/(A+C),越大越好。

在大规模数据集合中,这两个指标是相互制约的。当希望索引出更多的数据的时候,查准率就会下降,当希望索引更准确的时候,会索引更少的数据。

免责声明:文章转载自《Mahout学习系列之推荐算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Green.AgileMapper项目(2)新增DO和DTO代码生成判断list为空的条件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

产品逻辑中的—B端技术常识:同步异步接口模式

参看:http://www.woshipm.com/pd/3085570.html;http://www.woshipm.com/pd/3544202.html 在软件开发中,接口是一个非常重要的概念。所谓接口,是指两个对象进行通信的方式和协议。 软件领域的接口和我们生活中所使用的硬件设备的接口(例如USB接口、苹果的Lighting接口、3.5mm耳机接...

数据结构和算法可视化工具——Data Structure Visualizations

正好最近关注到学习数据结构和算法的两个工具,特别好用。下面我就分别介绍下这两个工具,各位可以收藏一下,说不定以后能用到。 第一个工具是数据结构和算法可视化工具——Data Structure Visualizations。该工具由旧金山大学开发,地址: https://www.cs.usfca.edu/~galles/visualization/Algor...

Base64编解码算法详解(附C/C++源码)[转自CSDN]

Base64不是什么新奇的算法了,不过如果你没从事过页面开发(或者说动态页面开发,尤其是邮箱服务),你都不怎么了解过,只是听起来很熟悉。对于黑客来说,Base64与MD5算法有着同样的位置,因为电子邮箱(e-mail)正文就是base64编码的。那么,我们就一起来深入的探讨一下这个东东吧。对于一种算法,与其问“它是什么?”,不如问“它实现了什么?”Base...

人脸识别的会遇到的问题及解决方法

参考:https://blog.csdn.net/duan19920101/article/details/50683988/?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242 注:以前做过基于KNN算法的人脸识别,但是未做这样的总结,这...

从零开始学区块链(4)

转自:区块链大师 1. 传统分布式一致性算法和区块链共识过程的异同点 相同点: Append only(只能增加) 强调序列化 少数服从多数原则 分离覆盖的问题:即长链覆盖短链区块,多节点覆盖少数节点日志 不同点: 传统分布式一致性算法大多不考虑拜占庭容错(Byzanetine Paxos除外),即假设所有节点只发生宕机、网络故障等非人为问题,并不考...

信息熵 和 算法时间复杂度

本文仅仅是我个人的理解,发现错误请告诉我一下。 前几天虽然看完了吴军先生的《数学之美》,但一直搞不懂信息熵所以连带着也没搞懂 最大熵的原理,直到今天白天看了TopLanguage的一个讨论信息论的帖子 再经过晚上散步时思考才顿悟信息熵的意义。 信息是个很抽象的概念。人们常常说信息很多,或者信息较少,但却很难说清楚信息到底有多少。比如一本五十万字的中文书到底...