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);