Author: srowen
Date: Wed Jan 14 16:49:38 2009
New Revision: 734586

URL: http://svn.apache.org/viewvc?rev=734586&view=rev
Log:
Re-added the Netflix data set example

Added:
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java
    
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixMovie.java

Added: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java?rev=734586&view=auto
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java
 (added)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java
 Wed Jan 14 16:49:38 2009
@@ -0,0 +1,202 @@
+/**
+ * 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.netflix;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
+import org.apache.mahout.cf.taste.impl.model.GenericPreference;
+import org.apache.mahout.cf.taste.impl.model.GenericUser;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
+import org.apache.mahout.cf.taste.impl.common.FileLineIterable;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.Item;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.User;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+/**
+ * <p>This is a {...@link DataModel} that reads the Netflix data set, as 
represented in its
+ * unpacked file structure. Note that unpacking the distribution entails 
untarring the main
+ * archive, then untarring the archive of training set data files.</p>
+ */
+public final class NetflixDataModel implements DataModel {
+
+       private static final Logger log = 
Logger.getLogger(NetflixDataModel.class.getName());
+
+       private final DataModel delegate;
+  private final boolean useSubset;
+
+  /**
+   * @param dataDirectory root directory of Netflix data set, unpacked
+   * @param useSubset if true, will use only a small fraction of the data -- 
may be useful
+   *  for quick experiments
+   */
+       public NetflixDataModel(File dataDirectory, boolean useSubset) throws 
IOException {
+               if (dataDirectory == null) {
+                       throw new IllegalArgumentException("dataDirectory is 
null");
+               }
+               if (!dataDirectory.exists() || !dataDirectory.isDirectory()) {
+                       throw new 
FileNotFoundException(dataDirectory.toString());
+               }
+
+    this.useSubset = useSubset;
+
+               log.info("Creating NetflixDataModel for directory: " + 
dataDirectory);
+
+               log.info("Reading movie data...");
+               List<NetflixMovie> movies = readMovies(dataDirectory);
+
+               log.info("Reading preference data...");
+               List<User> users = readUsers(dataDirectory, movies);
+
+               log.info("Creating delegate DataModel...");
+               delegate = new GenericDataModel(users);
+       }
+
+       private List<User> readUsers(File dataDirectory, List<NetflixMovie> 
movies) throws IOException {
+               Map<Integer, List<Preference>> userIDPrefMap = new 
FastMap<Integer, List<Preference>>();
+
+               int counter = 0;
+               FilenameFilter filenameFilter = new MovieFilenameFilter();
+               for (File movieFile : new File(dataDirectory, 
"training_set").listFiles(filenameFilter)) {
+      Iterator<String> lineIterator = new FileLineIterable(movieFile, 
false).iterator();
+                       String line = lineIterator.next();
+                       if (line == null) {
+                               throw new IOException("Can't read first line of 
file " + movieFile);
+                       }
+                       int movieID = Integer.parseInt(line.substring(0, 
line.length() - 1));
+                       NetflixMovie movie = movies.get(movieID - 1);
+                       if (movie == null) {
+                               throw new IllegalArgumentException("No such 
movie: " + movieID);
+                       }
+                       while (lineIterator.hasNext()) {
+        line = lineIterator.next();
+                               counter++;
+                               if (counter % 100000 == 0) {
+                                       log.info("Processed " + counter + " 
prefs");
+                               }
+                               int firstComma = line.indexOf((int) ',');
+                               Integer userID = 
Integer.valueOf(line.substring(0, firstComma));
+                               int secondComma = line.indexOf((int) ',', 
firstComma + 1);
+                               double rating = 
Double.parseDouble(line.substring(firstComma + 1, secondComma));
+                               List<Preference> userPrefs = 
userIDPrefMap.get(userID);
+                               if (userPrefs == null) {
+                                       userPrefs = new ArrayList<Preference>();
+                                       userIDPrefMap.put(userID, userPrefs);
+                               }
+                               userPrefs.add(new GenericPreference(null, 
movie, rating));
+                       }
+               }
+
+               List<User> users = new ArrayList<User>(userIDPrefMap.size());
+               for (Map.Entry<Integer, List<Preference>> entry : 
userIDPrefMap.entrySet()) {
+                       users.add(new GenericUser<Integer>(entry.getKey(), 
entry.getValue()));
+               }
+               return users;
+       }
+
+       private static List<NetflixMovie> readMovies(File dataDirectory) {
+               List<NetflixMovie> movies = new ArrayList<NetflixMovie>();
+    for (String line : new FileLineIterable(new File(dataDirectory, 
"movie_titles.txt"), false)) {
+                       int firstComma = line.indexOf((int) ',');
+                       Integer id = Integer.valueOf(line.substring(0, 
firstComma));
+                       int secondComma = line.indexOf((int) ',', firstComma + 
1);
+                       String title = line.substring(secondComma + 1);
+                       movies.add(new NetflixMovie(id, title));
+               }
+               return movies;
+       }
+
+       @Override
+  public Iterable<? extends User> getUsers() throws TasteException {
+               return delegate.getUsers();
+       }
+
+       @Override
+  public User getUser(Object id) throws TasteException {
+               return delegate.getUser(id);
+       }
+
+       @Override
+  public Iterable<? extends Item> getItems() throws TasteException {
+               return delegate.getItems();
+       }
+
+       @Override
+  public Item getItem(Object id) throws TasteException {
+               return delegate.getItem(id);
+       }
+
+       @Override
+  public Iterable<? extends Preference> getPreferencesForItem(Object itemID) 
throws TasteException {
+               return delegate.getPreferencesForItem(itemID);
+       }
+
+       @Override
+  public Preference[] getPreferencesForItemAsArray(Object itemID) throws 
TasteException {
+               return delegate.getPreferencesForItemAsArray(itemID);
+       }
+
+       @Override
+  public int getNumItems() throws TasteException {
+               return delegate.getNumItems();
+       }
+
+       @Override
+  public int getNumUsers() throws TasteException {
+               return delegate.getNumUsers();
+       }
+
+  @Override
+  public int getNumUsersWithPreferenceFor(Object... itemIDs) throws 
TasteException {
+    return delegate.getNumUsersWithPreferenceFor(itemIDs);
+  }
+
+  @Override
+  public void setPreference(Object userID, Object itemID, double value) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+  public void removePreference(Object userID, Object itemID) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+  public void refresh(Collection<Refreshable> alreadyRefreshed) {
+               // do nothing
+       }
+
+  private class MovieFilenameFilter implements FilenameFilter {
+    @Override
+      public boolean accept(File dir, String filename) {
+      return filename.startsWith(useSubset ? "mv_0000" : "mv_");
+    }
+  }
+}

Added: 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixMovie.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixMovie.java?rev=734586&view=auto
==============================================================================
--- 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixMovie.java
 (added)
+++ 
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixMovie.java
 Wed Jan 14 16:49:38 2009
@@ -0,0 +1,69 @@
+/**
+ * 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.netflix;
+
+import org.apache.mahout.cf.taste.model.Item;
+
+final class NetflixMovie implements Item {
+
+       private final Integer id;
+       private final String title;
+
+       NetflixMovie(Integer id, String title) {
+               if (id == null || title == null) {
+                       throw new IllegalArgumentException("ID or title is 
null");
+               }
+               this.id = id;
+               this.title = title;
+       }
+
+       @Override
+  public Object getID() {
+               return id;
+       }
+
+       String getTitle() {
+               return title;
+       }
+
+       @Override
+  public boolean isRecommendable() {
+               return true;
+       }
+
+       @Override
+       public int hashCode() {
+               return id.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               return obj instanceof NetflixMovie && ((NetflixMovie) 
obj).id.equals(id);
+       }
+
+       @Override
+  public int compareTo(Item item) {
+               return this.id.compareTo(((NetflixMovie) item).id);
+       }
+
+       @Override
+       public String toString() {
+               return id + ":" + title;
+       }
+
+}


Reply via email to