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,以及如果有缺失值的情况,关于这些后面章节会深入讨论。

你可能感兴趣的:(Mahout)