协同过滤算法——推荐引擎比你更了解你本身


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

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


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

2. 推荐引擎背景及算法api

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

                   

 

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

2.1 类似度
  若是咱们把每一个用户的评分列表当作一个一维度向量,那么能够根据向量的类似度定量化用户之间的类似性。类似度分类主要有:网站

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

  

 b. 基于 Cosine 类似度idea

  

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

 

 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

相关文章
相关标签/搜索