You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by sr...@apache.org on 2010/03/10 21:00:24 UTC

svn commit: r921534 - /lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/

Author: srowen
Date: Wed Mar 10 20:00:23 2010
New Revision: 921534

URL: http://svn.apache.org/viewvc?rev=921534&view=rev
Log:
Update to consider 0 ratings as non-ratings; add boolean variation for fun

Added:
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommender.java
      - copied, changed from r921351, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderBuilder.java
      - copied, changed from r921189, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderEvaluatorRunner.java
      - copied, changed from r921289, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModelBuilder.java
Modified:
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
    lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java

Copied: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommender.java (from r921351, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommender.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommender.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java&r1=921351&r2=921534&rev=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommender.java Wed Mar 10 20:00:23 2010
@@ -17,16 +17,12 @@
 
 package org.apache.mahout.cf.taste.example.bookcrossing;
 
-import java.util.Collection;
-import java.util.List;
-
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
-import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
 import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
 import org.apache.mahout.cf.taste.impl.similarity.CachingUserSimilarity;
-import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
+import org.apache.mahout.cf.taste.impl.similarity.LogLikelihoodSimilarity;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
 import org.apache.mahout.cf.taste.recommender.IDRescorer;
@@ -34,59 +30,62 @@ import org.apache.mahout.cf.taste.recomm
 import org.apache.mahout.cf.taste.recommender.Recommender;
 import org.apache.mahout.cf.taste.similarity.UserSimilarity;
 
+import java.util.Collection;
+import java.util.List;
+
 /**
  * A simple {@link Recommender} implemented for the Book Crossing demo.
  * See the <a href="http://www.informatik.uni-freiburg.de/~cziegler/BX/">Book Crossing site</a>.
  */
-public final class BookCrossingRecommender implements Recommender {
+public final class BookCrossingBooleanRecommender implements Recommender {
 
   private final Recommender recommender;
 
-  public BookCrossingRecommender(DataModel bcModel) throws TasteException {
-    UserSimilarity similarity = new CachingUserSimilarity(new EuclideanDistanceSimilarity(bcModel), bcModel);
-    UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, 0.2, similarity, bcModel, 0.2);
-    recommender = new CachingRecommender(new GenericUserBasedRecommender(bcModel, neighborhood, similarity));
+  public BookCrossingBooleanRecommender(DataModel bcModel) throws TasteException {
+    UserSimilarity similarity = new CachingUserSimilarity(new LogLikelihoodSimilarity(bcModel), bcModel);
+    UserNeighborhood neighborhood = new NearestNUserNeighborhood(5, Double.NEGATIVE_INFINITY, similarity, bcModel, 1.0);
+    recommender = new GenericUserBasedRecommender(bcModel, neighborhood, similarity);
   }
-  
+
   @Override
   public List<RecommendedItem> recommend(long userID, int howMany) throws TasteException {
     return recommender.recommend(userID, howMany);
   }
-  
+
   @Override
   public List<RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
   throws TasteException {
     return recommender.recommend(userID, howMany, rescorer);
   }
-  
+
   @Override
   public float estimatePreference(long userID, long itemID) throws TasteException {
     return recommender.estimatePreference(userID, itemID);
   }
-  
+
   @Override
   public void setPreference(long userID, long itemID, float value) throws TasteException {
     recommender.setPreference(userID, itemID, value);
   }
-  
+
   @Override
   public void removePreference(long userID, long itemID) throws TasteException {
     recommender.removePreference(userID, itemID);
   }
-  
+
   @Override
   public DataModel getDataModel() {
     return recommender.getDataModel();
   }
-  
+
   @Override
   public void refresh(Collection<Refreshable> alreadyRefreshed) {
     recommender.refresh(alreadyRefreshed);
   }
-  
+
   @Override
   public String toString() {
-    return "BookCrossingRecommender[recommender:" + recommender + ']';
+    return "BookCrossingBooleanRecommender[recommender:" + recommender + ']';
   }
-  
+
 }
\ No newline at end of file

Copied: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderBuilder.java (from r921189, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderBuilder.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderBuilder.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java&r1=921189&r2=921534&rev=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderBuilder.java Wed Mar 10 20:00:23 2010
@@ -22,11 +22,11 @@ import org.apache.mahout.cf.taste.eval.R
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.recommender.Recommender;
 
-final class BookCrossingRecommenderBuilder implements RecommenderBuilder {
-  
+final class BookCrossingBooleanRecommenderBuilder implements RecommenderBuilder {
+
   @Override
   public Recommender buildRecommender(DataModel dataModel) throws TasteException {
-    return new BookCrossingRecommender(dataModel);
+    return new BookCrossingBooleanRecommender(dataModel);
   }
-  
+
 }
\ No newline at end of file

Copied: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderEvaluatorRunner.java (from r921289, lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderEvaluatorRunner.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderEvaluatorRunner.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java&r1=921289&r2=921534&rev=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingBooleanRecommenderEvaluatorRunner.java Wed Mar 10 20:00:23 2010
@@ -17,42 +17,47 @@
 
 package org.apache.mahout.cf.taste.example.bookcrossing;
 
-import java.io.File;
-import java.io.IOException;
-
 import org.apache.commons.cli2.OptionException;
 import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
+import org.apache.mahout.cf.taste.eval.IRStatistics;
+import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
 import org.apache.mahout.cf.taste.example.TasteOptionParser;
-import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
+import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class BookCrossingRecommenderEvaluatorRunner {
-  
-  private static final Logger log = LoggerFactory.getLogger(BookCrossingRecommenderEvaluatorRunner.class);
-  
-  private BookCrossingRecommenderEvaluatorRunner() {
+import java.io.File;
+import java.io.IOException;
+
+public final class BookCrossingBooleanRecommenderEvaluatorRunner {
+
+  private static final Logger log = LoggerFactory.getLogger(BookCrossingBooleanRecommenderEvaluatorRunner.class);
+
+  private BookCrossingBooleanRecommenderEvaluatorRunner() {
     // do nothing
   }
-  
+
   public static void main(String... args) throws IOException, TasteException, OptionException {
-    RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
+    RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
     DataModel model;
     File ratingsFile = TasteOptionParser.getRatings(args);
     if (ratingsFile != null) {
-      model = new BookCrossingDataModel(ratingsFile);
+      model = new BookCrossingDataModel(ratingsFile, true);
     } else {
-      model = new BookCrossingDataModel();
+      model = new BookCrossingDataModel(true);
     }
-    
-    double evaluation = evaluator.evaluate(new BookCrossingRecommenderBuilder(),
-      null,
-      model,
-      0.9,
-      0.3);
+
+    IRStatistics evaluation = evaluator.evaluate(
+        new BookCrossingBooleanRecommenderBuilder(),
+        new BookCrossingDataModelBuilder(),
+        model,
+        null,
+        3,
+        Double.NEGATIVE_INFINITY,
+        1.0);
+
     log.info(String.valueOf(evaluation));
   }
-  
-}
+
+}
\ No newline at end of file

Modified: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java?rev=921534&r1=921533&r2=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java Wed Mar 10 20:00:23 2010
@@ -36,22 +36,24 @@ import org.apache.mahout.common.IOUtils;
  * data needed by this class. The BX-Book-Ratings.csv file is needed.
  */
 public final class BookCrossingDataModel extends FileDataModel {
+
   private static final Pattern NON_DIGIT_SEMICOLON_PATTERN = Pattern.compile("[^0-9;]");
-  
-  public BookCrossingDataModel() throws IOException {
+
+  public BookCrossingDataModel(boolean ignoreRatings) throws IOException {
     this(GroupLensDataModel.readResourceToTempFile(
-    "/org/apache/mahout/cf/taste/example/bookcrossing/BX-Book-Ratings.csv"));
+             "/org/apache/mahout/cf/taste/example/bookcrossing/BX-Book-Ratings.csv"),
+         ignoreRatings);
   }
   
   /**
    * @param ratingsFile BookCrossing ratings file in its native format
    * @throws IOException if an error occurs while reading or writing files
    */
-  public BookCrossingDataModel(File ratingsFile) throws IOException {
-    super(convertBCFile(ratingsFile));
+  public BookCrossingDataModel(File ratingsFile, boolean ignoreRatings) throws IOException {
+    super(convertBCFile(ratingsFile, ignoreRatings));
   }
   
-  private static File convertBCFile(File originalFile) throws IOException {
+  private static File convertBCFile(File originalFile, boolean ignoreRatings) throws IOException {
     if (!originalFile.exists()) {
       throw new FileNotFoundException(originalFile.toString());
     }
@@ -61,12 +63,20 @@ public final class BookCrossingDataModel
     try {
       writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(resultFile), Charset.forName("UTF-8")));
       for (String line : new FileLineIterable(originalFile, true)) {
+        // 0 ratings are basically "no rating", ignore them (thanks h.9000)
+        if (line.endsWith("\"0\"")) {
+          continue;
+        }
         // Delete replace anything that isn't numeric, or a semicolon delimiter. Make comma the delimiter.
         String convertedLine = BookCrossingDataModel.NON_DIGIT_SEMICOLON_PATTERN.matcher(line).replaceAll("").replace(';', ',');
         // If this means we deleted an entire ID -- few cases like that -- skip the line
         if (convertedLine.contains(",,")) {
           continue;
         }
+        if (ignoreRatings) {
+          // drop rating
+          convertedLine = convertedLine.substring(0, convertedLine.lastIndexOf(','));
+        }
         writer.println(convertedLine);
       }
       writer.flush();

Added: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModelBuilder.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModelBuilder.java?rev=921534&view=auto
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModelBuilder.java (added)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModelBuilder.java Wed Mar 10 20:00:23 2010
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.cf.taste.example.bookcrossing;
+
+import org.apache.mahout.cf.taste.eval.DataModelBuilder;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+
+final class BookCrossingDataModelBuilder implements DataModelBuilder {
+
+  @Override
+  public DataModel buildDataModel(FastByIDMap<PreferenceArray> trainingData) {
+    return new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(trainingData));
+  }
+
+}

Modified: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java?rev=921534&r1=921533&r2=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java Wed Mar 10 20:00:23 2010
@@ -45,7 +45,7 @@ public final class BookCrossingRecommend
   public BookCrossingRecommender(DataModel bcModel) throws TasteException {
     UserSimilarity similarity = new CachingUserSimilarity(new EuclideanDistanceSimilarity(bcModel), bcModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, 0.2, similarity, bcModel, 0.2);
-    recommender = new CachingRecommender(new GenericUserBasedRecommender(bcModel, neighborhood, similarity));
+    recommender = new GenericUserBasedRecommender(bcModel, neighborhood, similarity);
   }
   
   @Override

Modified: lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java?rev=921534&r1=921533&r2=921534&view=diff
==============================================================================
--- lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java (original)
+++ lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java Wed Mar 10 20:00:23 2010
@@ -42,9 +42,9 @@ public final class BookCrossingRecommend
     DataModel model;
     File ratingsFile = TasteOptionParser.getRatings(args);
     if (ratingsFile != null) {
-      model = new BookCrossingDataModel(ratingsFile);
+      model = new BookCrossingDataModel(ratingsFile, false);
     } else {
-      model = new BookCrossingDataModel();
+      model = new BookCrossingDataModel(false);
     }
     
     double evaluation = evaluator.evaluate(new BookCrossingRecommenderBuilder(),