• 协同过滤算法——推荐引擎比你更了解你自己



    1. 背景
      在数据爆炸我们每天被数据困扰的今天,数据量发生指数级的增长,每一年产生的大数据是过去历史的总和。那么在茫茫数据大海中,对于数据生产者,怎么将自己的信息精准投放给所需的用户呢?而对于数据消费者,怎么从海量数据中快速获取自己需要的信息呢?这时推荐引擎应运而生。
      推荐应用其实已经走进我们的生活,典型的推荐应用:
    a. 豆瓣网站
      豆瓣根据我的读书列表,及相应评论,为我推荐出如下结果:

                           
    b. 购物网站
      亚马孙根据我的购书清单和相应书评,为我推荐的如下结果:
                          


    1.1 问题抽象
        我们可以把推荐模型进行数据的抽象,假设有1,2,3,4和5个用户分别各自购买了101,102,103至107物品中的物品,并对其进行了各自购买的物品进行评分,那么推荐引擎如何根据用户喜好,推荐他们各自未买的物品呢?如下数据集:
               

    2. 推荐引擎背景及算法

          如果你最近想看电影,你可能咨询周围的人,而且通常你更倾向询问与“兴趣相投”的人,从他们的口味中,得出一个最近电影排名集,来敲定你想看的电影,这是协同过滤的基本思想。图解:

                       

     

      算法具体解决的两个问题:
      a. 如何找到“兴趣相投的”人群,形成一个群体,我们称之为邻域“neighborhood“。
      b. 如何从既定的邻域中,排序出喜好的项目列表?

    2.1 相似度
      如果我们把每个用户的评分列表看成一个一维度向量,那么可以根据向量的相似度定量化用户之间的相似性。相似度分类主要有:

     a. 基于欧几里德距离计算相似度

      

     b. 基于 Cosine 相似度

      

     c. 基于皮尔逊相关系数计算相似度

     

     d. 基于 Tanimoto 系数计算相似度

     


    2.2 邻域
      物以类聚,既然我们获取了用户之间的相似度值,那么那些人群归为一个邻域呢?通常有两种方法:

     a.  规定 Fix-size,根据相似度值排名,取前fix-size的个数作为一个邻域

     b. 规定threshold,相似度值大于规定值归为一个邻域


                  

    2.3 推荐值计算
      定量的计算推测用户a对某个物品v的喜好程度,公式如下: ΣSim(i,j)Vi

      即为其它各位用户对物品v的评分值的线性加权平均,其中,权重是相似度值sim,v表示对各物品的评分。

         所以整个计算的过程是通过2.1和2.2解决问题a,然后根据2.3解决问题b的过程。 

    2.4 推荐算法分类
      典型的推荐算法有:基于用户的推荐和基于物品的推荐两种。
      上述的思路从基于用户的推荐方法讲解的,而在实际电商网站应用中,由于物品数量是远远大于每位用户的购买数量的,而且用户之间购买的物品重叠性较低,很难找到邻域。这时,可以换个从商品的角度思考,商品间的相似性。根据用户购物历史偏好,计算物品间的相似性,流程和基于用户的推荐一样。 

    3. mahout协同过滤的应用接口

    3.1 相似度
      相似度接口有UserSimilarity和ItemSimilarity,其主要方法如下:

    double userSimilarity(long userID1, long userID2)
    double itemSimilarity(long itemID1, long itemID2)

      其继承类分别:

    a. PearsonCorrelationSimilarity:基于皮尔逊相关系数计算相似度
    b. EuclideanDistanceSimilarity:基于欧几里德距离计算相似度
    c. TanimotoCoefficientSimilarity:基于 Tanimoto 系数计算相似度
    d. UncerteredCosineSimilarity:计算 Cosine 相似度

    3.2 邻域
       邻域类UserNeighborhood,其主要接口如下:

     long[] getUserNeighborhood(long userID) 

    输入给定用户,给出与其相似的用户列表

    其继承类分别:
    a. NearestNUserNeighborhood:对每个用户取固定数量 N 的最近邻居
    b. ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度门限内的所有用户为邻居。

    3.3 Recommender

      关联数据模型和相似度算法模型,进行具体的计算,接口如下:

    List<RecommendedItem> recommend(long userID, int howMany)

       给定用户id和推荐的结果个数,返回推荐的结果

    3.4 各类图关系如下:

                   

    4. 代码样例和推荐结果
    4.1 mahout代码样例

     public static void main(String[] args) throws IOException, TasteException {
            // TODO Auto-generated method stub
            System.out.println("starting ");
    
            String file = "item.csv";
            DataModel model = new FileDataModel(new File(file));
    
            System.out.println("starting userCF ");
            userCF(model);
    
            System.out.println();
            System.out.println("starting itemCF");
            itemCF(model);
        }
    
        public static void userCF(DataModel model) {
            try {
                UserSimilarity user = new UncenteredCosineSimilarity(model);
                NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model);
                Recommender r = new GenericUserBasedRecommender(model, neighbor, user);
                LongPrimitiveIterator iter = model.getUserIDs();
    
                while (iter.hasNext()) {
                    long uid = iter.nextLong();
                    List<RecommendedItem> list = r.recommend(uid, RECOMMENDER_NUM);
    
                    System.out.printf("user:%s", uid);
                    for (RecommendedItem rItem : list) {
                        System.out.printf("(%s,%f)", rItem.getItemID(), rItem.getValue());
                    }
                    System.out.println();
                }
    
            } catch (TasteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
        public static void itemCF(DataModel dataModel) {
            try {
                ItemSimilarity itemSimilarity = new UncenteredCosineSimilarity(dataModel);
                Recommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity);
                Recommender cachingRecommender = new CachingRecommender(recommender);
    
                LongPrimitiveIterator iter = dataModel.getUserIDs();
                while (iter.hasNext()) {
                    long uid = iter.nextLong();
                    List<RecommendedItem> list = cachingRecommender.recommend(uid, RECOMMENDER_NUM);
    
                    System.out.printf("user:%s", uid);
                    for (RecommendedItem rItem : list) {
                        System.out.printf("(%s,%f)", rItem.getItemID(), rItem.getValue());
                    }
                    System.out.println();
                }
    
            } catch (TasteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    4.2 推荐结果

                

    5. 评估标准
         结果推荐出来,自然需要一套标准评判各自方法推荐的结果好坏。评价标准可以参考http://blog.fens.me/mahout-recommendation-api/#gsc.tab=0的2节。

     

      参考

    1. http://en.wikipedia.org/wiki/Collaborative_filtering

    2. http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy1/

    3. https://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy2/

    4. http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy3/

    5. http://blog.csdn.net/huagong_adu/article/details/7362908

    6. http://blog.fens.me/mahout-recommendation-api/#gsc.tab=0

  • 相关阅读:
    再深一点:如何给女朋友解释什么是微服务?
    图文详解:内存总是不够,我靠HBase说服了Leader为新项目保驾护航
    Java多态总结
    猴子吃桃问题(南阳ACM324)
    杭电acm-2007平方和立方和
    出现错误,修改后的
    今天的第一个程序-南阳acm输入三个数排序
    Azure Blob上传和下载
    用Aspose.Cells把Excel文件转成PDF
    Ionic IOS打包第二节
  • 原文地址:https://www.cnblogs.com/gisorange/p/3516425.html
Copyright © 2020-2023  润新知