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