Mahout in Action 读书笔记chapter3 推荐数据的表示

http://blog.csdn.net/feitongxunke​
这一章主要介绍

  1. 在Mahout里面表示和访问推荐程序的相关数据时所用的关键类。
  2. Mahout中用于访问数据的关键抽象:DataModel。
  3. 当用户和物品的数据没有评分和偏好值时,也就是布尔偏好,这个时候需要做的处理。

1.偏好数据表示

1.1Preference对象

一个Prefernence对象表示一个用户对一个物品的偏好,是(用户ID,物品ID,偏好值)的抽象。最有可能实现的是:


   
   
  1. new GenericPreference(123, 456, 3.0f) //分别代表(用户ID,物品ID,偏好值)

1.2PrefernenceArray及其实现

如果要实现一组Prefernence,不能使用Collection or Prefernence[],因为这时候十分的占用内存。针对这种情况Mahout提供了PreferenceArray接口,表示一个偏好的聚合。这里可以举个例子:

GenericUserPrefernenceArray表示的是与某个用户关联的所有偏好。其内部包含一个单一用户ID,一个物品ID数组,以及一个偏好值数组。


   
   
  1. PreferenceArray user1Prefs = new GenericUserPreferenceArray(2);
  2. user1Prefs.setUserID(0, 1L);//设置用户ID
  3. user1Prefs.setItemID(0, 101L);
  4. user1Prefs.setValue(0, 2.0f);
  5. user1Prefs.setItemID(1, 102L);
  6. user1Prefs.setValue(1, 3.0f);
  7. Preference pref = user1Prefs.get(1);//提取物品102的偏好值

1.3FastByIDMap和FastIDSet

在Mahout里面有许多Map和Set的数据结构,但是这个和Java里面的集合有些不同。

  • FastByIDMap处理散列冲突是使用线性探测而不是链表法
  • key和member都是使用long类型
  • Set的内部没有使用Map
  • FastByIDMap可以作为高速缓存,超过这个大小时,若要新加入条目则会把不常用的移走。

2.内存级DataModel

2.1GenericDataModel

它简单地将偏好作为输入,采用FastByIDMap的形式,将用户ID映射到这些用户的数据所在的PreferenceArray上。


   
   
  1. FastByIDMap<PreferenceArray> preferences = new FastByIDMap<PreferenceArray>();
  2. PreferenceArray prefsForUser1 = new GenericUserPreferenceArray(10);
  3. prefsForUser1.setUserID(0, 1L);
  4. prefsForUser1.setItemID(0, 101L);//增加偏好
  5. prefsForUser1.setValue(0, 3.0f);
  6. prefsForUser1.setItemID(1, 102L);
  7. prefsForUser1.setValue(1, 4.5f);
  8. preferences.put(1L, prefsForUser1);//在输入中附上用户1的偏好
  9. DataModel model = new GenericDataModel(preferences);

3.无偏好值的处理

有时候我们会遇到没有评分的时候,只知道用户和物品是否关联,这时候称之为布尔型偏好。关于布尔型偏好的时候,书中举了个例子需要使用布尔型偏好的情况。一个人只对古典音乐感兴趣,对古典音乐家A给了很低的评分,给了古典音乐家B很高的评分,这个时候通过评分不能说明他对古典音乐是否感兴趣,但是如果这个时候转换成布尔型就可以了。

当使用无偏好值内存会得到大大节省,这个时候使用GenericBooleanPrefDataModel,这个将关联存为FastIDSet,没有偏好值。

给段代码看看:


   
   
  1. import org.apache.mahout.cf.taste.common.TasteException;
  2. import org.apache.mahout.cf.taste.eval.IRStatistics;
  3. import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
  4. import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
  5. import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator;
  6. import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
  7. import org.apache.mahout.cf.taste.impl.model.file.*;
  8. import org.apache.mahout.cf.taste.impl.neighborhood.*;
  9. import org.apache.mahout.cf.taste.impl.recommender.*;
  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. import org.apache.mahout.common.RandomUtils;
  16. import java.io.*;
  17. class RecommenderIntro {
  18. public static void main(String[] args) throws Exception {
  19. RandomUtils.useTestSeed();
  20. DataModel model = new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(new FileDataModel(new File("/Users/ericxk/Downloads/ml-100k/ua.base"))));
  21. RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
  22. RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
  23. public Recommender buildRecommender(DataModel model)throws TasteException {
  24. UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
  25. UserNeighborhood neighborhood =new NearestNUserNeighborhood(2, similarity, model);
  26. return new GenericUserBasedRecommender(model, neighborhood, similarity);
  27. }
  28. };
  29. IRStatistics stats = evaluator.evaluate(recommenderBuilder, null, model, null, 2, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
  30. System.out.println(stats.getPrecision());
  31. System.out.println(stats.getRecall());
  32. }
  33. }

最后文中讨论了用LogLikelihoodSimilarity代替PearsonCorrelationSimilarity,以及如果有缺失值的情况,关于这些后面章节会深入讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值