Author: srowen
Date: Sat Jan  3 21:05:24 2009
New Revision: 731177

URL: http://svn.apache.org/viewvc?rev=731177&view=rev
Log: (empty)

Added:
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/Book.java
      - copied, changed from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/Movie.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
      - copied, changed from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
      - copied, changed from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommender.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java
      - copied, changed from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderBuilder.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java
      - copied, changed from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderEvaluatorRunner.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java
Modified:
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterable.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterable.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterable.java?rev=731177&r1=731176&r2=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterable.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterable.java
 Sat Jan  3 21:05:24 2009
@@ -31,26 +31,28 @@
 
   private final File file;
   private final Charset encoding;
+  private final boolean skipFirstLine;
 
   /**
    * Creates a {...@link FileLineIterable} over a given file, assuming a UTF-8 
encoding.
    */
-  public FileLineIterable(File file) {
-    this(file, Charset.forName("UTF-8"));
+  public FileLineIterable(File file, boolean skipFirstLine) {
+    this(file, Charset.forName("UTF-8"), skipFirstLine);
   }
 
   /**
    * Creates a {...@link FileLineIterable} over a given file, using the given 
encoding.
    */
-  public FileLineIterable(File file, Charset encoding) {
+  public FileLineIterable(File file, Charset encoding, boolean skipFirstLine) {
     this.file = file;
     this.encoding = encoding;
+    this.skipFirstLine = skipFirstLine;
   }
 
   @Override
   public Iterator<String> iterator() {
     try {
-      return new FileLineIterator(file, encoding);
+      return new FileLineIterator(file, encoding, skipFirstLine);
     } catch (IOException ioe) {
       throw new IllegalStateException(ioe);
     }

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java?rev=731177&r1=731176&r2=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
 Sat Jan  3 21:05:24 2009
@@ -45,8 +45,8 @@
    * @throws FileNotFoundException if the file does not exist
    * @throws IOException if the file cannot be read
    */
-  public FileLineIterator(File file) throws IOException {
-    this(file, Charset.forName("UTF-8"));
+  public FileLineIterator(File file, boolean skipFirstLine) throws IOException 
{
+    this(file, Charset.forName("UTF-8"), skipFirstLine);
   }
 
   /**
@@ -55,9 +55,12 @@
    * @throws FileNotFoundException if the file does not exist
    * @throws IOException if the file cannot be read
    */
-  public FileLineIterator(File file, Charset encoding) throws IOException {
+  public FileLineIterator(File file, Charset encoding, boolean skipFirstLine) 
throws IOException {
     InputStream is = new FileInputStream(file);
     reader = new BufferedReader(new InputStreamReader(is, encoding));
+    if (skipFirstLine) {
+      reader.readLine();
+    }
     nextLine = reader.readLine();
   }
 

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java?rev=731177&r1=731176&r2=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java
 Sat Jan  3 21:05:24 2009
@@ -116,7 +116,7 @@
   private void processFile(Map<String, List<Preference>> data) {
     log.info("Reading file info...");
     Map<String, Item> itemCache = new FastMap<String, Item>(1001);
-    for (String line : new FileLineIterable(dataFile)) {
+    for (String line : new FileLineIterable(dataFile, false)) {
       if (line.length() > 0) {
         log.debug("Read line: {}", line);
         processLine(line, data, itemCache);

Copied: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/Book.java
 (from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/Movie.java)
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/Book.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/Book.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/Movie.java&r1=730810&r2=731177&rev=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/Movie.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/Book.java
 Sat Jan  3 21:05:24 2009
@@ -15,24 +15,46 @@
  * limitations under the License.
  */
 
-package org.apache.mahout.cf.taste.example.grouplens;
+package org.apache.mahout.cf.taste.example.bookcrossing;
 
 import org.apache.mahout.cf.taste.impl.model.GenericItem;
 
-final class Movie extends GenericItem<String> {
+final class Book extends GenericItem<String> {
 
-  private final String movieTitle;
-  private final String genres;
+  private final String isbn;
+  private final String title;
+  private final String author;
+  private final int year;
+  private final String publisher;
+
+  Book(String isbn, String title, String author, int year, String publisher) {
+    super(isbn);
+    this.isbn = isbn;
+    this.title = title;
+    this.author = author;
+    this.year = year;
+    this.publisher = publisher;
+  }
+
+
+  String getIsbn() {
+    return isbn;
+  }
+
+  String getTitle() {
+    return title;
+  }
+
+  String getAuthor() {
+    return author;
+  }
 
-  Movie(String id, String movieTitle, String genres) {
-    super(id);
-    this.movieTitle = movieTitle;
-    this.genres = genres;
+  int getYear() {
+    return year;
   }
 
-  @Override
-  public String toString() {
-    return getID().toString() + '\t' + movieTitle + '\t' + genres;
+  String getPublisher() {
+    return publisher;
   }
 
-}
+}
\ No newline at end of file

Copied: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
 (from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java)
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java&r1=730810&r2=731177&rev=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
 Sat Jan  3 21:05:24 2009
@@ -15,76 +15,162 @@
  * limitations under the License.
  */
 
-package org.apache.mahout.cf.taste.example.grouplens;
+package org.apache.mahout.cf.taste.example.bookcrossing;
 
 import org.apache.mahout.cf.taste.impl.common.FastMap;
 import org.apache.mahout.cf.taste.impl.common.FileLineIterable;
 import org.apache.mahout.cf.taste.impl.common.IOUtils;
 import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
 import org.apache.mahout.cf.taste.model.Item;
+import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.example.grouplens.GroupLensDataModel;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.OutputStreamWriter;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.List;
 import java.nio.charset.Charset;
 
-public final class GroupLensDataModel extends FileDataModel {
+public final class BookCrossingDataModel extends FileDataModel {
 
-  private final Map<String, Movie> movieMap;
-
-  public GroupLensDataModel() throws IOException {
-    
this(readResourceToTempFile("/org/apache/mahout/cf/taste/example/grouplens/ratings.dat"),
-         
readResourceToTempFile("/org/apache/mahout/cf/taste/example/grouplens/movies.dat"));
+  private Map<String, Book> bookMap;
+  private Map<String, String[]> userDataMap;
+  private final File booksFile;
+  private final File usersFile;
+
+  public BookCrossingDataModel() throws IOException {
+    
this(GroupLensDataModel.readResourceToTempFile("/org/apache/mahout/cf/taste/example/bookcrossing/BX-Book-Ratings.csv"),
+         
GroupLensDataModel.readResourceToTempFile("/org/apache/mahout/cf/taste/example/bookcrossing/BX-Books.csv"),
+         
GroupLensDataModel.readResourceToTempFile("/org/apache/mahout/cf/taste/example/bookcrossing/BX-Users.csv"));
   }
 
   /**
-   * @param ratingsFile GroupLens ratings.dat file in its native format
-   * @param moviesFile GroupLens movies.dat file in its native format
+   * @param ratingsFile BookCrossing ratings file in its native format
+   * @param booksFile BookCrossing books file in its native format
+   * @param usersFile BookCrossing books file in its native format
    * @throws IOException if an error occurs while reading or writing files
    */
-  public GroupLensDataModel(File ratingsFile, File moviesFile) throws 
IOException {
-    super(convertGLFile(ratingsFile, true));
-    File convertedMoviesFile = convertGLFile(moviesFile, false);
-    movieMap = new FastMap<String, Movie>(5001);
-    for (String line : new FileLineIterable(convertedMoviesFile)) {
-      String[] tokens = line.split(",");
-      String id = tokens[0];
-      movieMap.put(id, new Movie(id, tokens[1], tokens[2]));
+  public BookCrossingDataModel(File ratingsFile, File booksFile, File 
usersFile) throws IOException {
+    super(convertBCFile(ratingsFile));
+    this.booksFile = booksFile;
+    this.usersFile = usersFile;
+  }
+
+  @Override
+  protected void reload() {
+    bookMap = new FastMap<String, Book>(5001);
+    userDataMap = new FastMap<String, String[]>(5001);
+
+    for (String line : new FileLineIterable(booksFile, true)) {
+      String[] tokens = tokenizeLine(line, 5);
+      if (tokens != null) {
+        String id = tokens[0];
+        bookMap.put(id, new Book(id, tokens[1], tokens[2], 
Integer.parseInt(tokens[3]), tokens[4]));
+      }
+    }
+    for (String line : new FileLineIterable(usersFile, true)) {
+      String[] tokens = tokenizeLine(line, 3);
+      if (tokens != null) {
+        String id = tokens[0];
+        userDataMap.put(id, new String[] { tokens[1], tokens[2] });
+      }
+    }
+
+    super.reload();
+    bookMap = null;
+    userDataMap = null;
+  }
+
+  private static String[] tokenizeLine(String line, int numTokens) {
+    String[] result = new String[numTokens];
+    int pos = 0;
+    int token = 0;
+    int start = 0;
+    int end = 0;
+    boolean inQuote = false;
+    int length = line.length();
+    while (pos < length && token < numTokens) {
+      char c = line.charAt(pos);
+      if (c == '"') {
+        if (inQuote) {
+          if (line.charAt(pos - 1) != '\\') {
+            end = pos;
+            inQuote = false;
+          }
+        } else {
+          start = pos + 1;
+          inQuote = true;
+        }
+      } else if (c == ';' && !inQuote) {
+        if (start == end) {
+          // last token was unquoted
+          end = pos + 1;
+        }
+        result[token] = line.substring(start, end);
+        start = pos + 1;
+        end = pos + 1;
+        token++;
+      }
+      pos++;
+    }
+    if (token == numTokens - 1) {
+      // one more at end
+      if (start == end) {
+        // last token was unquoted
+        end = pos;
+      }
+      result[token] = line.substring(start, end);
+      token++;
+    }
+    if (token != numTokens) {
+      return null;
     }
+    for (int i = 0; i < result.length; i++) {
+      if ("NULL".equalsIgnoreCase(result[i])) {
+        result[i] = null;
+      }
+    }
+    return result;
+  }
+  
+  @Override
+  protected User buildUser(String id, List<Preference> prefs) {
+    String[] userData = userDataMap.get(id);
+    if (userData == null) {
+      throw new NoSuchElementException();
+    }
+    String location = userData[0];
+    Integer age = userData[1] == null ? null : Integer.valueOf(userData[1]);
+    return new BookCrossingUser(id, prefs, location, age);
   }
 
   @Override
   protected Item buildItem(String id) {
-    Item item = movieMap.get(id);
+    Item item = bookMap.get(id);
     if (item == null) {
-      throw new NoSuchElementException();
+      // some books aren't in books file?
+      return new Book(id, null, null, 0, null);
     }
     return item;
   }
 
-  private static File convertGLFile(File originalFile, boolean ratings) throws 
IOException {
-    // Now translate the file; remove commas, then convert "::" delimiter to 
comma
-    File resultFile = new File(new File(System.getProperty("java.io.tmpdir")),
-                                     "taste." + (ratings ? "ratings" : 
"movies") + ".txt");
+  private static File convertBCFile(File originalFile) throws IOException {
+    File resultFile = new File(new File(System.getProperty("java.io.tmpdir")), 
"taste.bookcrossing.txt");
     if (!resultFile.exists()) {
       PrintWriter writer = null;
       try {
         writer = new PrintWriter(new OutputStreamWriter(new 
FileOutputStream(resultFile), Charset.forName("UTF-8")));
-        for (String line : new FileLineIterable(originalFile)) {
-          String convertedLine;
-          if (ratings) {
-            // toss the last column of data, which is a timestamp we don't want
-            convertedLine = line.substring(0, 
line.lastIndexOf("::")).replace("::", ",");
-          } else {
-            convertedLine = line.replace(",", "").replace("::", ",");
+        for (String line : new FileLineIterable(originalFile, true)) {
+          if (line.indexOf(',') >= 0) {
+            // crude hack to work around corruptions in data file -- some bad 
lines with commas in them
+            continue;
           }
+          String convertedLine = line.replace(';', ',').replace("\"", "");
           writer.println(convertedLine);
         }
         writer.flush();
@@ -98,34 +184,9 @@
     return resultFile;
   }
 
-  private static File readResourceToTempFile(String resourceName) throws 
IOException {
-    InputStream is = 
GroupLensRecommender.class.getResourceAsStream(resourceName);
-    if (is == null) {
-      is = new FileInputStream("src/main/java" + resourceName);
-    }
-    try {
-      File tempFile = File.createTempFile("taste", null);
-      tempFile.deleteOnExit();
-      OutputStream os = new FileOutputStream(tempFile);
-      try {
-        int bytesRead;
-        for (byte[] buffer = new byte[32768]; (bytesRead = is.read(buffer)) > 
0;) {
-          os.write(buffer, 0, bytesRead);
-        }
-        os.flush();
-        return tempFile;
-      } finally {
-        IOUtils.quietClose(os);
-      }
-    } finally {
-      IOUtils.quietClose(is);
-    }
-  }
-
-
   @Override
   public String toString() {
-    return "GroupLensDataModel";
+    return "BookCrossingDataModel";
   }
 
-}
+}
\ No newline at end of file

Copied: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
 (from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommender.java)
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommender.java&r1=730810&r2=731177&rev=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommender.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
 Sat Jan  3 21:05:24 2009
@@ -15,46 +15,42 @@
  * limitations under the License.
  */
 
-package org.apache.mahout.cf.taste.example.grouplens;
+package org.apache.mahout.cf.taste.example.bookcrossing;
 
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
-import 
org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
+import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
+import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
+import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.model.Item;
 import org.apache.mahout.cf.taste.recommender.RecommendedItem;
 import org.apache.mahout.cf.taste.recommender.Recommender;
 import org.apache.mahout.cf.taste.recommender.Rescorer;
+import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
 
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 
 /**
- * A simple {...@link Recommender} implemented for the GroupLens demo.
+ * 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 GroupLensRecommender implements Recommender {
+public final class BookCrossingRecommender implements Recommender {
 
   private final Recommender recommender;
 
-  /**
-   * @throws IOException if an error occurs while creating the {...@link 
GroupLensDataModel}
-   * @throws TasteException if an error occurs while initializing this 
{...@link GroupLensRecommender}
-   */
-  public GroupLensRecommender() throws IOException, TasteException {
-    this(new GroupLensDataModel());
-  }
-
-  /**
-   * <p>Alternate constructor that takes a {...@link DataModel} argument, 
which allows this {...@link Recommender}
-   * to be used with the {...@link 
org.apache.mahout.cf.taste.eval.RecommenderEvaluator} framework.</p>
-   *
-   * @param dataModel data model
-   * @throws TasteException if an error occurs while initializing this 
{...@link GroupLensRecommender}
-   */
-  public GroupLensRecommender(DataModel dataModel) throws TasteException {
-    recommender = new CachingRecommender(new SlopeOneRecommender(dataModel));
+  public BookCrossingRecommender() throws IOException, TasteException {
+    this(new BookCrossingDataModel());
+  }
+
+  public BookCrossingRecommender(DataModel dataModel) throws TasteException {
+    UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
+    UserNeighborhood neighborhood = new NearestNUserNeighborhood(5, 
similarity, dataModel);
+    recommender = new CachingRecommender(new 
GenericUserBasedRecommender(dataModel, neighborhood, similarity));
   }
 
   @Override
@@ -95,7 +91,7 @@
 
   @Override
   public String toString() {
-    return "GroupLensRecommender[recommender:" + recommender + ']';
+    return "BookCrossingRecommender[recommender:" + recommender + ']';
   }
 
-}
+}
\ No newline at end of file

Copied: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java
 (from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderBuilder.java)
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderBuilder.java&r1=730810&r2=731177&rev=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderBuilder.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderBuilder.java
 Sat Jan  3 21:05:24 2009
@@ -15,18 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.mahout.cf.taste.example.grouplens;
+package org.apache.mahout.cf.taste.example.bookcrossing;
 
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.recommender.Recommender;
 
-final class GroupLensRecommenderBuilder implements RecommenderBuilder {
+final class BookCrossingRecommenderBuilder implements RecommenderBuilder {
 
   @Override
   public Recommender buildRecommender(DataModel dataModel) throws 
TasteException {
-    return new GroupLensRecommender(dataModel);
+    return new BookCrossingRecommender(dataModel);
   }
 
-}
+}
\ No newline at end of file

Copied: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java
 (from r730810, 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderEvaluatorRunner.java)
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java?p2=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java&p1=lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderEvaluatorRunner.java&r1=730810&r2=731177&rev=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommenderEvaluatorRunner.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommenderEvaluatorRunner.java
 Sat Jan  3 21:05:24 2009
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.mahout.cf.taste.example.grouplens;
+package org.apache.mahout.cf.taste.example.bookcrossing;
 
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
@@ -27,23 +27,23 @@
 
 /**
  * <p>A simple example "runner" class which will evaluate the performance of 
the current
- * implementation of {...@link GroupLensRecommender}.</p>
+ * implementation of {...@link 
org.apache.mahout.cf.taste.example.grouplens.GroupLensRecommender}.</p>
  */
-public final class GroupLensRecommenderEvaluatorRunner {
+public final class BookCrossingRecommenderEvaluatorRunner {
 
-  private static final Logger log = 
LoggerFactory.getLogger(GroupLensRecommenderEvaluatorRunner.class);
+  private static final Logger log = 
LoggerFactory.getLogger(BookCrossingRecommenderEvaluatorRunner.class);
 
-  private GroupLensRecommenderEvaluatorRunner() {
+  private BookCrossingRecommenderEvaluatorRunner() {
     // do nothing
   }
 
   public static void main(String... args) throws IOException, TasteException {
     RecommenderEvaluator evaluator = new 
AverageAbsoluteDifferenceRecommenderEvaluator();
-    double evaluation = evaluator.evaluate(new GroupLensRecommenderBuilder(),
-                                                 new GroupLensDataModel(),
+    double evaluation = evaluator.evaluate(new 
BookCrossingRecommenderBuilder(),
+                                                 new BookCrossingDataModel(),
                                                  0.9,
                                                  0.1);
     log.info(String.valueOf(evaluation));
   }
 
-}
+}
\ No newline at end of file

Added: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java?rev=731177&view=auto
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java
 (added)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java
 Sat Jan  3 21:05:24 2009
@@ -0,0 +1,44 @@
+/**
+ * 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.impl.model.GenericUser;
+import org.apache.mahout.cf.taste.model.Preference;
+
+import java.util.List;
+
+final class BookCrossingUser extends GenericUser<String> {
+
+  private final String location;
+  private final Integer age;
+
+  BookCrossingUser(String id, List<Preference> prefs, String location, Integer 
age) {
+    super(id, prefs);
+    this.location = location;
+    this.age = age;
+  }
+
+  String getLocation() {
+    return location;
+  }
+
+  Integer getAge() {
+    return age;
+  }
+
+}
\ No newline at end of file

Modified: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java?rev=731177&r1=731176&r2=731177&view=diff
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
 (original)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
 Sat Jan  3 21:05:24 2009
@@ -37,7 +37,8 @@
 
 public final class GroupLensDataModel extends FileDataModel {
 
-  private final Map<String, Movie> movieMap;
+  private Map<String, Movie> movieMap;
+  private final File moviesFile;
 
   public GroupLensDataModel() throws IOException {
     
this(readResourceToTempFile("/org/apache/mahout/cf/taste/example/grouplens/ratings.dat"),
@@ -51,13 +52,7 @@
    */
   public GroupLensDataModel(File ratingsFile, File moviesFile) throws 
IOException {
     super(convertGLFile(ratingsFile, true));
-    File convertedMoviesFile = convertGLFile(moviesFile, false);
-    movieMap = new FastMap<String, Movie>(5001);
-    for (String line : new FileLineIterable(convertedMoviesFile)) {
-      String[] tokens = line.split(",");
-      String id = tokens[0];
-      movieMap.put(id, new Movie(id, tokens[1], tokens[2]));
-    }
+    this.moviesFile = moviesFile;
   }
 
   @Override
@@ -69,6 +64,24 @@
     return item;
   }
 
+  @Override
+  protected void reload() {
+    File convertedMoviesFile;
+    try {
+      convertedMoviesFile = convertGLFile(moviesFile, false);
+    } catch (IOException ioe) {
+      throw new RuntimeException(ioe); // better way?
+    }
+    movieMap = new FastMap<String, Movie>(5001);
+    for (String line : new FileLineIterable(convertedMoviesFile, false)) {
+      String[] tokens = line.split(",");
+      String id = tokens[0];
+      movieMap.put(id, new Movie(id, tokens[1], tokens[2]));
+    }
+    super.reload();
+    movieMap = null;
+  }
+
   private static File convertGLFile(File originalFile, boolean ratings) throws 
IOException {
     // Now translate the file; remove commas, then convert "::" delimiter to 
comma
     File resultFile = new File(new File(System.getProperty("java.io.tmpdir")),
@@ -77,7 +90,7 @@
       PrintWriter writer = null;
       try {
         writer = new PrintWriter(new OutputStreamWriter(new 
FileOutputStream(resultFile), Charset.forName("UTF-8")));
-        for (String line : new FileLineIterable(originalFile)) {
+        for (String line : new FileLineIterable(originalFile, false)) {
           String convertedLine;
           if (ratings) {
             // toss the last column of data, which is a timestamp we don't want
@@ -98,10 +111,11 @@
     return resultFile;
   }
 
-  private static File readResourceToTempFile(String resourceName) throws 
IOException {
+  public static File readResourceToTempFile(String resourceName) throws 
IOException {
     InputStream is = 
GroupLensRecommender.class.getResourceAsStream(resourceName);
     if (is == null) {
-      is = new FileInputStream("src/main/java" + resourceName);
+      // No resource found, try just using the file
+      return new File("src/main/java" + resourceName);
     }
     try {
       File tempFile = File.createTempFile("taste", null);


Reply via email to