Author: srowen
Date: Sat May 31 16:13:29 2008
New Revision: 662104

URL: http://svn.apache.org/viewvc?rev=662104&view=rev
Log:
Added new DataModel methods to retrieve number of users preferring item(s) in 
anticipation of implementing Ted's log-likelihood-based approaches

Modified:
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericDataModel.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModel.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/AbstractJDBCDataModel.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/GenericJDBCDataModel.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/MySQLJDBCDataModel.java
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
    
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericDataModel.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericDataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericDataModel.java
 Sat May 31 16:13:29 2008
@@ -33,6 +33,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.HashSet;
 
 /**
  * <p>A simple [EMAIL PROTECTED] DataModel} which uses a given [EMAIL 
PROTECTED] List} of [EMAIL PROTECTED] User}s as
@@ -161,6 +163,36 @@
     return users.size();
   }
 
+  public int getNumUsersWithPreferenceFor(Object... itemIDs) throws 
TasteException {
+    if (itemIDs == null) {
+      throw new IllegalArgumentException("itemIDs is null");
+    }
+    int length = itemIDs.length;
+    if (length == 0 || length > 2) {
+      throw new IllegalArgumentException("Illegal number of item IDs: " + 
length);
+    }
+    if (length == 1) {
+      Preference[] prefs = preferenceForItems.get(itemIDs[0]);
+      return prefs == null ? 0 : prefs.length;
+    } else {
+      Preference[] prefs1 = preferenceForItems.get(itemIDs[0]);
+      Preference[] prefs2 = preferenceForItems.get(itemIDs[1]);
+      if (prefs1 == null || prefs2 == null) {
+        return 0;
+      }
+      Set<Object> users1 = new HashSet<Object>(prefs1.length);
+      for (int i = 0; i < prefs1.length; i++) {
+        users1.add(prefs1[i].getUser().getID());
+      }
+      Set<Object> users2 = new HashSet<Object>(prefs2.length);
+      for (int i = 0; i < prefs2.length; i++) {
+        users2.add(prefs2[i].getUser().getID());
+      }
+      users1.retainAll(users2);
+      return users1.size();
+    }
+  }
+
   /**
    * @throws UnsupportedOperationException
    */

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=662104&r1=662103&r2=662104&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 May 31 16:13:29 2008
@@ -204,6 +204,11 @@
     return delegate.getNumUsers();
   }
 
+  public int getNumUsersWithPreferenceFor(Object... itemIDs) throws 
TasteException {
+    checkLoaded();
+    return delegate.getNumUsersWithPreferenceFor(itemIDs);
+  }
+
   /**
    * @throws UnsupportedOperationException
    */

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/AbstractJDBCDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/AbstractJDBCDataModel.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/AbstractJDBCDataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/AbstractJDBCDataModel.java
 Sat May 31 16:13:29 2008
@@ -87,6 +87,8 @@
   private final String getItemsSQL;
   private final String getItemSQL;
   private final String getPrefsForItemSQL;
+  private final String getNumPreferenceForItemSQL;
+  private final String getNumPreferenceForItemsSQL;
 
   protected AbstractJDBCDataModel(DataSource dataSource,
                                   String getUserSQL,
@@ -98,7 +100,8 @@
                                   String getItemsSQL,
                                   String getItemSQL,
                                   String getPrefsForItemSQL,
-                                  String getUsersPreferringItemSQL) {
+                                  String getNumPreferenceForItemSQL,
+                                  String getNumPreferenceForItemsSQL) {
 
     log.debug("Creating AbstractJDBCModel...");
     checkNotNullAndLog("dataSource", dataSource);
@@ -111,7 +114,8 @@
     checkNotNullAndLog("getItemsSQL", getItemsSQL);
     checkNotNullAndLog("getItemSQL", getItemSQL);
     checkNotNullAndLog("getPrefsForItemSQL", getPrefsForItemSQL);
-    checkNotNullAndLog("getUsersPreferringItemSQL", getUsersPreferringItemSQL);
+    checkNotNullAndLog("getNumPreferenceForItemSQL", 
getNumPreferenceForItemSQL);
+    checkNotNullAndLog("getgetNumPreferenceForItemsSQL", 
getNumPreferenceForItemsSQL);
 
     if (!(dataSource instanceof ConnectionPoolDataSource)) {
       log.warn("You are not using ConnectionPoolDataSource. Make sure your 
DataSource pools connections " +
@@ -128,6 +132,8 @@
     this.getItemsSQL = getItemsSQL;
     this.getItemSQL = getItemSQL;
     this.getPrefsForItemSQL = getPrefsForItemSQL;
+    this.getNumPreferenceForItemSQL = getNumPreferenceForItemSQL;
+    this.getNumPreferenceForItemsSQL = getNumPreferenceForItemsSQL;
   }
 
   private static void checkNotNullAndLog(String argName, Object value) {
@@ -303,16 +309,37 @@
     return getNumThings("users", getNumUsersSQL);
   }
 
-  private int getNumThings(String name, String sql) throws TasteException {
+  public final int getNumUsersWithPreferenceFor(Object... itemIDs) throws 
TasteException {
+    if (itemIDs == null) {
+      throw new IllegalArgumentException("itemIDs is null");
+    }
+    int length = itemIDs.length;
+    if (length == 0 || length > 2) {
+      throw new IllegalArgumentException("Illegal number of item IDs: " + 
length);
+    }
+    if (length == 1) {
+      return getNumThings("user preferring item", getNumPreferenceForItemSQL, 
itemIDs);
+    } else {
+      return getNumThings("user preferring items", 
getNumPreferenceForItemsSQL, itemIDs);
+    }
+  }
+
+
+  private int getNumThings(String name, String sql, Object... args) throws 
TasteException {
     log.debug("Retrieving number of {} in model", name);
     Connection conn = null;
-    Statement stmt = null;
+    PreparedStatement stmt = null;
     ResultSet rs = null;
     try {
       conn = dataSource.getConnection();
-      stmt = conn.createStatement();
+      stmt = conn.prepareStatement(sql);
+      if (args != null) {
+        for (int i = 1; i <= args.length; i++) {
+          stmt.setObject(i, args[i - 1]);
+        }
+      }
       log.debug("Executing SQL query: {}", sql);
-      rs = stmt.executeQuery(sql);
+      rs = stmt.executeQuery();
       rs.next();
       return rs.getInt(1);
     } catch (SQLException sqle) {

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/GenericJDBCDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/GenericJDBCDataModel.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/GenericJDBCDataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/GenericJDBCDataModel.java
 Sat May 31 16:13:29 2008
@@ -35,7 +35,7 @@
  * If you are using this class to support a major database, consider 
contributing a specialized implementation
  * of [EMAIL PROTECTED] AbstractJDBCDataModel} to the project for this 
database.</p>
  */
-public class GenericJDBCDataModel extends AbstractJDBCDataModel {
+public final class GenericJDBCDataModel extends AbstractJDBCDataModel {
 
   public static final String DATA_SOURCE_KEY = "dataSource";
   public static final String GET_USER_SQL_KEY = "getUserSQL";
@@ -47,7 +47,8 @@
   public static final String GET_ITEMS_SQL_KEY = "getItemsSQL";
   public static final String GET_ITEM_SQL_KEY = "getItemSQL";
   public static final String GET_PREFS_FOR_ITEM_SQL_KEY = "getPrefsForItemSQL";
-  public static final String GET_USERS_PREFERRING_ITEM_SQL_KEY = 
"getUsersPreferringItemSQL";
+  public static final String GET_NUM_PREFERENCE_FOR_ITEM_KEY = 
"getNumPreferenceForItemSQL";
+  public static final String GET_NUM_PREFERENCE_FOR_ITEMS_KEY = 
"getNumPreferenceForItemsSQL";
 
   /**
    * <p>Specifies all SQL queries in a [EMAIL PROTECTED] Properties} object. 
See the <code>*_KEY</code>
@@ -68,7 +69,8 @@
           props.getProperty(GET_ITEMS_SQL_KEY),
           props.getProperty(GET_ITEM_SQL_KEY),
           props.getProperty(GET_PREFS_FOR_ITEM_SQL_KEY),
-          props.getProperty(GET_USERS_PREFERRING_ITEM_SQL_KEY));
+          props.getProperty(GET_NUM_PREFERENCE_FOR_ITEM_KEY),
+          props.getProperty(GET_NUM_PREFERENCE_FOR_ITEMS_KEY));
   }
 
   /**

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/MySQLJDBCDataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/MySQLJDBCDataModel.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/MySQLJDBCDataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/MySQLJDBCDataModel.java
 Sat May 31 16:13:29 2008
@@ -76,7 +76,7 @@
  *
  * <p>Thanks to Amila Jayasooriya for contributing MySQL notes above as part 
of Google Summer of Code 2007.</p>
  */
-public class MySQLJDBCDataModel extends AbstractJDBCDataModel {
+public final class MySQLJDBCDataModel extends AbstractJDBCDataModel {
 
   /**
    * <p>Creates a [EMAIL PROTECTED] MySQLJDBCDataModel} using the default 
[EMAIL PROTECTED] DataSource}
@@ -155,9 +155,12 @@
           // getPrefsForItemSQL
           "SELECT " + preferenceColumn + ", " + userIDColumn + " FROM " +
           preferenceTable + " WHERE " + itemIDColumn + "=? ORDER BY " + 
userIDColumn,
-          // getUsersPreferringItemSQL
-          "SELECT DISTINCT " + userIDColumn + " FROM " + preferenceTable + " 
WHERE " + itemIDColumn +
-          "=? ORDER BY " + userIDColumn);
+          // getNumPreferenceForItemSQL
+          "SELECT COUNT(1) FROM " + preferenceTable + " WHERE " + itemIDColumn 
+ "=?",
+          // getNumPreferenceForItemsSQL
+          "SELECT COUNT(1) FROM " + preferenceTable + " tp1 INNER JOIN " + 
preferenceColumn + " tp2 " +
+          "ON (tp1." + userIDColumn + "=tp2." + userIDColumn + ") " +
+          "WHERE tp1." + itemIDColumn + "=? and tp2." + itemIDColumn + "=?");
   }
 
 }

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
 Sat May 31 16:13:29 2008
@@ -85,6 +85,15 @@
   int getNumUsers() throws TasteException;
 
   /**
+   * @param itemIDs item IDs to check for
+   * @return the number of users who have expressed a preference for all of 
the items
+   * @throws TasteException if an error occurs while accessing the data
+   * @throws IllegalArgumentException if itemIDs is null, empty, or larger 
than 2 elements
+   *  since currently only queries of up to 2 items are needed and supported
+   */
+  int getNumUsersWithPreferenceFor(Object... itemIDs) throws TasteException;
+
+  /**
    * <p>Sets a particular preference (item plus rating) for a user.</p>
    *
    * @param userID user to set preference for

Modified: 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java?rev=662104&r1=662103&r2=662104&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
 (original)
+++ 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
 Sat May 31 16:13:29 2008
@@ -115,6 +115,13 @@
     assertEquals(4, model.getNumUsers());
   }
 
+  public void testNumUsersPreferring() throws Exception {
+    assertEquals(2, model.getNumUsersWithPreferenceFor("456"));
+    assertEquals(0, model.getNumUsersWithPreferenceFor("111"));
+    assertEquals(0, model.getNumUsersWithPreferenceFor("111", "456"));
+    assertEquals(2, model.getNumUsersWithPreferenceFor("123", "234"));
+  }
+
   public void testSetPreference() throws Exception {
     try {
       model.setPreference(null, null, 0.0);


Reply via email to