You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by sr...@apache.org on 2009/08/04 02:06:50 UTC
svn commit: r800634 [5/7] - in /lucene/mahout/trunk:
core/src/main/java/org/apache/mahout/cf/taste/hadoop/
core/src/main/java/org/apache/mahout/cf/taste/impl/common/
core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/
core/src/main/java/org...
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java Tue Aug 4 00:06:46 2009
@@ -20,143 +20,102 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
-import org.apache.mahout.cf.taste.impl.model.ByItemPreferenceComparator;
-import org.apache.mahout.cf.taste.impl.model.ByValuePreferenceComparator;
-import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
-import java.util.Arrays;
import java.util.Collection;
/**
* <p>Like {@link PearsonCorrelationSimilarity}, but compares relative ranking of preference values instead of
- * preference values themselves. That is, each {@link User}'s preferences are sorted and then assign a rank as their
- * preference value, with 1 being assigned to the least preferred item. Then the Pearson correlation of these rank
- * values is computed.</p>
+ * preference values themselves. That is, each user's preferences are sorted and then assign a rank as their
+ * preference value, with 1 being assigned to the least preferred item.</p>
*/
public final class SpearmanCorrelationSimilarity implements UserSimilarity {
- private final UserSimilarity rankingUserSimilarity;
+ private final DataModel dataModel;
public SpearmanCorrelationSimilarity(DataModel dataModel) throws TasteException {
if (dataModel == null) {
throw new IllegalArgumentException("dataModel is null");
}
- this.rankingUserSimilarity = new PearsonCorrelationSimilarity(dataModel);
- }
-
- public SpearmanCorrelationSimilarity(UserSimilarity rankingUserSimilarity) {
- if (rankingUserSimilarity == null) {
- throw new IllegalArgumentException("rankingUserSimilarity is null");
- }
- this.rankingUserSimilarity = rankingUserSimilarity;
- }
-
- @Override
- public double userSimilarity(User user1, User user2) throws TasteException {
- if (user1 == null || user2 == null) {
- throw new IllegalArgumentException("user1 or user2 is null");
- }
- return rankingUserSimilarity.userSimilarity(new RankedPreferenceUser(user1),
- new RankedPreferenceUser(user2));
- }
-
- @Override
- public void setPreferenceInferrer(PreferenceInferrer inferrer) {
- rankingUserSimilarity.setPreferenceInferrer(inferrer);
+ this.dataModel = dataModel;
}
@Override
- public void refresh(Collection<Refreshable> alreadyRefreshed) {
- alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
- RefreshHelper.maybeRefresh(alreadyRefreshed, rankingUserSimilarity);
- }
+ public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
-
- /**
- * <p>A simple {@link User} decorator which will always return the underlying {@link User}'s preferences in order by
- * value.</p>
- */
- private static final class RankedPreferenceUser implements User {
-
- private final User delegate;
-
- private RankedPreferenceUser(User delegate) {
- this.delegate = delegate;
+ if (userID1 == null || userID2 == null) {
+ throw new IllegalArgumentException("userID1 or userID2 is null");
}
- @Override
- public Comparable<?> getID() {
- return delegate.getID();
- }
+ PreferenceArray xPrefs = dataModel.getPreferencesFromUser(userID1);
+ PreferenceArray yPrefs = dataModel.getPreferencesFromUser(userID2);
+ int xLength = xPrefs.length();
+ int yLength = yPrefs.length();
- /**
- * @throws UnsupportedOperationException
- */
- @Override
- public Preference getPreferenceFor(Comparable<?> itemID) {
- throw new UnsupportedOperationException();
+ if (xLength <= 1 || yLength <= 1) {
+ return Double.NaN;
}
- /**
- * @throws UnsupportedOperationException
- */
- @Override
- public void setPreference(Comparable<?> itemID, double value) {
- throw new UnsupportedOperationException();
- }
+ xPrefs = xPrefs.clone();
+ yPrefs = yPrefs.clone();
+
+ xPrefs.sortByValue();
+ yPrefs.sortByValue();
- /**
- * @throws UnsupportedOperationException
- */
- @Override
- public void removePreference(Comparable<?> itemID) {
- throw new UnsupportedOperationException();
+ for (int i = 0; i < xLength; i++) {
+ xPrefs.setValue(i, i);
}
-
- @Override
- public Iterable<Preference> getPreferences() {
- return Arrays.asList(getPreferencesAsArray());
+ for (int i = 0; i < yLength; i++) {
+ yPrefs.setValue(i, i);
}
- @Override
- public Preference[] getPreferencesAsArray() {
- Preference[] source = delegate.getPreferencesAsArray();
- int length = source.length;
- Preference[] sortedPrefs = new Preference[length];
- System.arraycopy(source, 0, sortedPrefs, 0, length);
- Arrays.sort(sortedPrefs, ByValuePreferenceComparator.getInstance());
- for (int i = 0; i < length; i++) {
- sortedPrefs[i] = new GenericPreference(this, sortedPrefs[i].getItemID(), (double) (i + 1));
- }
- Arrays.sort(sortedPrefs, ByItemPreferenceComparator.getInstance());
- return sortedPrefs;
- }
+ xPrefs.sortByItem();
+ yPrefs.sortByItem();
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
+ Comparable<?> xIndex = xPrefs.getItemID(0);
+ Comparable<?> yIndex = yPrefs.getItemID(0);
+ int xPrefIndex = 0;
+ int yPrefIndex = 0;
- @Override
- public boolean equals(Object o) {
- return o instanceof RankedPreferenceUser && delegate.equals(((RankedPreferenceUser) o).delegate);
- }
+ double sumXYRankDiff2 = 0.0;
+ int count = 0;
- @Override
- public int compareTo(User user) {
- return delegate.compareTo(user);
+ while (true) {
+ int compare = ((Comparable<Object>) xIndex).compareTo(yIndex);
+ if (compare == 0) {
+ double diff = xPrefs.getValue(xPrefIndex) - yPrefs.getValue(yPrefIndex);
+ sumXYRankDiff2 += diff * diff;
+ count++;
+ }
+ if (compare <= 0) {
+ if (++xPrefIndex >= xLength) {
+ break;
+ }
+ xIndex = xPrefs.getItemID(xPrefIndex);
+ }
+ if (compare >= 0) {
+ if (++yPrefIndex >= yLength) {
+ break;
+ }
+ yIndex = yPrefs.getItemID(yPrefIndex);
+ }
}
- @Override
- public String toString() {
- return "RankedPreferenceUser[user:" + delegate + ']';
- }
+ return 1.0 - (6.0 * sumXYRankDiff2 / count / (count*count - 1));
+ }
+ @Override
+ public void setPreferenceInferrer(PreferenceInferrer inferrer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void refresh(Collection<Refreshable> alreadyRefreshed) {
+ alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
+ RefreshHelper.maybeRefresh(alreadyRefreshed, dataModel);
}
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java Tue Aug 4 00:06:46 2009
@@ -19,10 +19,9 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
@@ -57,25 +56,25 @@
}
@Override
- public double userSimilarity(User user1, User user2) {
+ public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
- if (user1 == null || user2 == null) {
- throw new IllegalArgumentException("user1 or user2 is null");
+ if (userID1 == null || userID2 == null) {
+ throw new IllegalArgumentException("userID1 or userID2 is null");
}
- Preference[] xPrefs = user1.getPreferencesAsArray();
- Preference[] yPrefs = user2.getPreferencesAsArray();
+ FastSet<Comparable<?>> xPrefs = dataModel.getItemIDsFromUser(userID1);
+ FastSet<Comparable<?>> yPrefs = dataModel.getItemIDsFromUser(userID2);
- if (xPrefs.length == 0 && yPrefs.length == 0) {
+ if (xPrefs.isEmpty() && yPrefs.isEmpty()) {
return Double.NaN;
}
- if (xPrefs.length == 0 || yPrefs.length == 0) {
+ if (xPrefs.isEmpty() || yPrefs.isEmpty()) {
return 0.0;
}
- int intersectionSize = LogLikelihoodSimilarity.findIntersectionSize(xPrefs, yPrefs);
+ int intersectionSize = xPrefs.intersectionSize(yPrefs);
- int unionSize = xPrefs.length + yPrefs.length - intersectionSize;
+ int unionSize = xPrefs.size() + yPrefs.size() - intersectionSize;
return (double) intersectionSize / (double) unionSize;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java Tue Aug 4 00:06:46 2009
@@ -17,22 +17,22 @@
package org.apache.mahout.cf.taste.impl.similarity.jdbc;
-import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
-import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.NoSuchItemException;
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.IOUtils;
import org.apache.mahout.cf.taste.impl.common.jdbc.AbstractJDBCComponent;
import org.apache.mahout.cf.taste.impl.model.jdbc.ConnectionPoolDataSource;
+import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
-import java.util.Collection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Collection;
/**
* An {@link ItemSimilarity} which draws pre-computed item-item similarities from
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java Tue Aug 4 00:06:46 2009
@@ -39,8 +39,8 @@
*
* <pre>
* CREATE TABLE taste_item_similarity (
- * item_id_a VARCHAR(10) NOT NULL,
- * item_id_b VARCHAR(10) NOT NULL,
+ * item_id_a INT NOT NULL,
+ * item_id_b INT NOT NULL,
* similarity FLOAT NOT NULL,
* PRIMARY KEY (item_id_a, item_id_b),
* )
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java Tue Aug 4 00:06:46 2009
@@ -20,16 +20,16 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.FastMap;
+import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.transforms.PreferenceTransform;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -48,9 +48,8 @@
*/
public final class InverseUserFrequency implements PreferenceTransform {
- private static final Logger log = LoggerFactory.getLogger(InverseUserFrequency.class);
-
private final DataModel dataModel;
+ private final RefreshHelper refreshHelper;
private final double logBase;
private final AtomicReference<Map<Comparable<?>, Double>> iufFactors;
@@ -71,6 +70,14 @@
this.dataModel = dataModel;
this.logBase = logBase;
this.iufFactors = new AtomicReference<Map<Comparable<?>, Double>>(new FastMap<Comparable<?>, Double>());
+ this.refreshHelper = new RefreshHelper(new Callable<Object>() {
+ @Override
+ public Object call() throws TasteException {
+ recompute();
+ return null;
+ }
+ });
+ this.refreshHelper.addDependency(this.dataModel);
recompute();
}
@@ -80,30 +87,27 @@
}
@Override
- public double getTransformedValue(Preference pref) {
+ public float getTransformedValue(Preference pref) {
Double factor = iufFactors.get().get(pref.getItemID());
if (factor != null) {
- return pref.getValue() * factor;
+ return (float) (pref.getValue() * factor);
}
return pref.getValue();
}
@Override
public void refresh(Collection<Refreshable> alreadyRefreshed) {
- try {
- recompute();
- } catch (TasteException te) {
- log.warn("Unable to refresh", te);
- }
+ refreshHelper.refresh(alreadyRefreshed);
}
private synchronized void recompute() throws TasteException {
Counters<Comparable<?>> itemPreferenceCounts = new Counters<Comparable<?>>();
int numUsers = 0;
- for (User user : dataModel.getUsers()) {
- Preference[] prefs = user.getPreferencesAsArray();
- for (Preference pref : prefs) {
- itemPreferenceCounts.increment(pref.getItemID());
+ for (Comparable<?> userID : dataModel.getUserIDs()) {
+ PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+ int size = prefs.length();
+ for (int i = 0; i < size; i++) {
+ itemPreferenceCounts.increment(prefs.getItemID(i));
}
numUsers++;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java Tue Aug 4 00:06:46 2009
@@ -21,16 +21,18 @@
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.Cache;
import org.apache.mahout.cf.taste.impl.common.FullRunningAverageAndStdDev;
+import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
import org.apache.mahout.cf.taste.impl.common.Retriever;
import org.apache.mahout.cf.taste.impl.common.RunningAverageAndStdDev;
+import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.transforms.PreferenceTransform;
import java.util.Collection;
/**
- * <p>Normalizes preference values for a {@link User} by converting them to <a href="http://mathworld.wolfram.com/z-Score.html">"z-scores"</a>.
+ * <p>Normalizes preference values for a user by converting them to <a href="http://mathworld.wolfram.com/z-Score.html">"z-scores"</a>.
* This process normalizes preference values to adjust for variation in mean and variance of a user's preferences.</p>
*
* <p>Imagine two users, one who tends to rate every movie he/she sees four or five stars, and another who uses the full
@@ -39,28 +41,32 @@
*/
public final class ZScore implements PreferenceTransform {
- private final Cache<User, RunningAverageAndStdDev> meanAndStdevs;
+ private final DataModel dataModel;
+ private final Cache<Comparable<?>, RunningAverageAndStdDev> meanAndStdevs;
- public ZScore() {
- this.meanAndStdevs = new Cache<User, RunningAverageAndStdDev>(new MeanStdevRetriever());
+ public ZScore(DataModel dataModel) {
+ this.dataModel = dataModel;
+ this.meanAndStdevs = new Cache<Comparable<?>, RunningAverageAndStdDev>(new MeanStdevRetriever());
refresh(null);
}
@Override
- public double getTransformedValue(Preference pref) throws TasteException {
- RunningAverageAndStdDev meanAndStdev = meanAndStdevs.get(pref.getUser());
+ public float getTransformedValue(Preference pref) throws TasteException {
+ RunningAverageAndStdDev meanAndStdev = meanAndStdevs.get(pref.getUserID());
if (meanAndStdev.getCount() > 1) {
double stdev = meanAndStdev.getStandardDeviation();
if (stdev > 0.0) {
- return (pref.getValue() - meanAndStdev.getAverage()) / stdev;
+ return (float) ((pref.getValue() - meanAndStdev.getAverage()) / stdev);
}
}
- return 0.0;
+ return 0.0f;
}
@Override
public void refresh(Collection<Refreshable> alreadyRefreshed) {
- // do nothing
+ meanAndStdevs.clear();
+ alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
+ RefreshHelper.maybeRefresh(alreadyRefreshed, dataModel);
}
@Override
@@ -68,14 +74,15 @@
return "ZScore";
}
- private static class MeanStdevRetriever implements Retriever<User, RunningAverageAndStdDev> {
+ private class MeanStdevRetriever implements Retriever<Comparable<?>, RunningAverageAndStdDev> {
@Override
- public RunningAverageAndStdDev get(User user) throws TasteException {
+ public RunningAverageAndStdDev get(Comparable<?> userID) throws TasteException {
RunningAverageAndStdDev running = new FullRunningAverageAndStdDev();
- Preference[] prefs = user.getPreferencesAsArray();
- for (Preference pref : prefs) {
- running.addDatum(pref.getValue());
+ PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+ int size = prefs.length();
+ for (int i = 0; i < size; i++) {
+ running.addDatum(prefs.getValue(i));
}
return running;
}
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=800634&r1=800633&r2=800634&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 Tue Aug 4 00:06:46 2009
@@ -17,31 +17,41 @@
package org.apache.mahout.cf.taste.model;
+import org.apache.mahout.cf.taste.common.NoSuchItemException;
+import org.apache.mahout.cf.taste.common.NoSuchUserException;
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
import java.util.List;
/**
- * <p>Implementations represent a repository of information about {@link User}s and their associated {@link Preference}s
+ * <p>Implementations represent a repository of information about users and their associated {@link Preference}s
* for items.</p>
*/
public interface DataModel extends Refreshable {
/**
- * @return a {@link List} of all {@link User}s in the model, ordered by {@link User}
+ * @return a {@link List} of all user IDs in the model, in order
* @throws TasteException if an error occurs while accessing the data
*/
- Iterable<? extends User> getUsers() throws TasteException;
+ Iterable<Comparable<?>> getUserIDs() throws TasteException;
/**
- * @param id user ID
- * @return {@link User} who has that ID
+ * @param userID ID of user to get prefs for
+ * @return user's preferences
+ * @throws NoSuchUserException if the user does not exist
* @throws TasteException if an error occurs while accessing the data
- * @throws org.apache.mahout.cf.taste.common.NoSuchUserException
- * if there is no such {@link User}
*/
- User getUser(Comparable<?> id) throws TasteException;
+ PreferenceArray getPreferencesFromUser(Comparable<?> userID) throws TasteException;
+
+ /**
+ * @param userID ID of user to get prefs for
+ * @return IDs of items user expresses a preference for
+ * @throws NoSuchUserException if the user does not exist
+ * @throws TasteException if an error occurs while accessing the data
+ */
+ FastSet<Comparable<?>> getItemIDsFromUser(Comparable<?> userID) throws TasteException;
/**
* @return a {@link List} of all item IDs in the model, in order
@@ -51,27 +61,32 @@
/**
* @param itemID item ID
- * @return all existing {@link Preference}s expressed for that item, ordered by {@link User}
+ * @return all existing {@link Preference}s expressed for that item, ordered by user ID, as an array
+ * @throws NoSuchItemException if the item does not exist
* @throws TasteException if an error occurs while accessing the data
*/
- Iterable<? extends Preference> getPreferencesForItem(Comparable<?> itemID) throws TasteException;
+ PreferenceArray getPreferencesForItem(Comparable<?> itemID) throws TasteException;
/**
- * @param itemID item ID
- * @return all existing {@link Preference}s expressed for that item, ordered by {@link User}, as an array
+ * Retrieves the preference value for a single user and item.
+ *
+ * @param userID user ID to get pref value from
+ * @param itemID item ID to get pref value for
+ * @return preference value from the given user for the given item or null if none exists
+ * @throws NoSuchUserException if the user does not exist
* @throws TasteException if an error occurs while accessing the data
*/
- Preference[] getPreferencesForItemAsArray(Comparable<?> itemID) throws TasteException;
+ Float getPreferenceValue(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
/**
* @return total number of items known to the model. This is generally the union of all items
- * preferred by at least one {@link User} but could include more.
+ * preferred by at least one user but could include more.
* @throws TasteException if an error occurs while accessing the data
*/
int getNumItems() throws TasteException;
/**
- * @return total number of {@link User}s known to the model.
+ * @return total number of users known to the model.
* @throws TasteException if an error occurs while accessing the data
*/
int getNumUsers() throws TasteException;
@@ -82,6 +97,7 @@
* @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
+ * @throws NoSuchItemException if an item does not exist
*/
int getNumUsersWithPreferenceFor(Comparable<?>... itemIDs) throws TasteException;
@@ -91,15 +107,19 @@
* @param userID user to set preference for
* @param itemID item to set preference for
* @param value preference value
+ * @throws NoSuchItemException if the item does not exist
+ * @throws NoSuchUserException if the user does not exist
* @throws TasteException if an error occurs while accessing the data
*/
- void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) throws TasteException;
+ void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) throws TasteException;
/**
* <p>Removes a particular preference for a user.</p>
*
* @param userID user from which to remove preference
* @param itemID item to remove preference for
+ * @throws NoSuchItemException if the item does not exist
+ * @throws NoSuchUserException if the user does not exist
* @throws TasteException if an error occurs while accessing the data
*/
void removePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java Tue Aug 4 00:06:46 2009
@@ -17,10 +17,27 @@
package org.apache.mahout.cf.taste.model;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
+
import javax.sql.DataSource;
+import java.util.Map;
public interface JDBCDataModel extends DataModel {
+ /**
+ * @return {@link DataSource} underlying this model
+ */
DataSource getDataSource();
+ /**
+ * Hmm, should this exist elsewhere? seems like most relevant for a DB
+ * implementation, which is not in memory, which might want to export to memory.
+ *
+ * @return all user preference data
+ */
+ Map<Comparable<?>, PreferenceArray> exportWithPrefs() throws TasteException;
+
+ Map<Comparable<?>, FastSet<Comparable<?>>> exportWithIDsOnly() throws TasteException;
+
}
\ No newline at end of file
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java Tue Aug 4 00:06:46 2009
@@ -19,12 +19,12 @@
/**
* <p>A {@link Preference} encapsulates an item and a preference value, which indicates the strength of the
- * preference for it. {@link Preference}s are associated to {@link User}s.</p>
+ * preference for it. {@link Preference}s are associated to users.</p>
*/
public interface Preference {
- /** @return {@link User} who prefers the item */
- User getUser();
+ /** @return ID of user who prefers the item */
+ Comparable<?> getUserID();
/** @return item ID that is preferred */
Comparable<?> getItemID();
@@ -33,13 +33,13 @@
* @return strength of the preference for that item. Zero should indicate "no preference either way"; positive values
* indicate preference and negative values indicate dislike
*/
- double getValue();
+ float getValue();
/**
* Sets the strength of the preference for this item
*
* @param value new preference
*/
- void setValue(double value);
+ void setValue(float value);
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java Tue Aug 4 00:06:46 2009
@@ -17,26 +17,40 @@
package org.apache.mahout.cf.taste.model;
+import java.io.Serializable;
+
/**
* An alternate representation of an array of {@link Preference}. Implementations, in theory, can produce a more
* memory-efficient representation. This is not used yet.
*/
-public interface PreferenceArray {
+public interface PreferenceArray extends Cloneable, Serializable, Iterable<Preference> {
+ int length();
+
Preference get(int i);
void set(int i, Preference pref);
- User getUser(int i);
+ Comparable<?> getUserID(int i);
- void setUser(int i, User user);
+ void setUserID(int i, Comparable<?> userID);
Comparable<?> getItemID(int i);
void setItemID(int i, Comparable<?> itemID);
- double getValue(int i);
+ float getValue(int i);
+
+ void setValue(int i, float value);
+
+ PreferenceArray clone();
+
+ void sortByUser();
+
+ void sortByItem();
+
+ void sortByValue();
- void setValue(int i, double value);
+ void sortByValueReversed();
}
\ No newline at end of file
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java Tue Aug 4 00:06:46 2009
@@ -19,22 +19,21 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
import java.util.Collection;
/**
- * <p>Implementations of this interface compute a "neighborhood" of {@link User}s like a given {@link User}. This
+ * <p>Implementations of this interface compute a "neighborhood" of users like a given user. This
* neighborhood can be used to compute recommendations then.</p>
*/
public interface UserNeighborhood extends Refreshable {
/**
* @param userID ID of user for which a neighborhood will be computed
- * @return {@link Collection} of {@link User}s in the neighborhood
+ * @return {@link Collection} of IDs of users in the neighborhood
* @throws org.apache.mahout.cf.taste.common.TasteException
* if an error occurs while accessing data
*/
- Collection<User> getUserNeighborhood(Comparable<?> userID) throws TasteException;
+ Collection<Comparable<?>> getUserNeighborhood(Comparable<?> userID) throws TasteException;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java Tue Aug 4 00:06:46 2009
@@ -18,7 +18,6 @@
package org.apache.mahout.cf.taste.recommender;
import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
import java.util.Collection;
@@ -26,20 +25,20 @@
public interface ClusteringRecommender extends Recommender {
/**
- * <p>Returns the cluster of users to which the given {@link User}, denoted by user ID, belongs.</p>
+ * <p>Returns the cluster of users to which the given user, denoted by user ID, belongs.</p>
*
* @param userID user ID for which to find a cluster
- * @return {@link Collection} of {@link User}s in the requested user's cluster
+ * @return {@link Collection} of IDs of users in the requested user's cluster
* @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
*/
- Collection<User> getCluster(Comparable<?> userID) throws TasteException;
+ Collection<Comparable<?>> getCluster(Comparable<?> userID) throws TasteException;
/**
* <p>Returns all clusters of users.</p>
*
- * @return {@link Collection} of {@link Collection}s of {@link User}s
+ * @return {@link Collection} of {@link Collection}s of user IDs
* @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
*/
- Collection<Collection<User>> getClusters() throws TasteException;
+ Collection<Collection<Comparable<?>>> getClusters() throws TasteException;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java Tue Aug 4 00:06:46 2009
@@ -75,7 +75,7 @@
* an item and value. The value here does not necessarily have a consistent interpretation or expected range;
* it will be higher the more influential the item was in the recommendation.</p>
*
- * @param userID ID of {@link org.apache.mahout.cf.taste.model.User} who was recommended the item
+ * @param userID ID of user who was recommended the item
* @param itemID ID of item that was recommended
* @param howMany maximum number of items to return
* @return {@link List} of {@link RecommendedItem}, ordered from most influential in recommended the
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java Tue Aug 4 00:06:46 2009
@@ -32,6 +32,6 @@
*
* @return strength of the preference
*/
- double getValue();
+ float getValue();
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java Tue Aug 4 00:06:46 2009
@@ -24,7 +24,7 @@
import java.util.List;
/**
- * <p>Implementations of this interface can recommend items for a {@link org.apache.mahout.cf.taste.model.User}.
+ * <p>Implementations of this interface can recommend items for a user.
* Implementations will likely take advantage of several classes in other packages here to compute this.</p>
*/
public interface Recommender extends Refreshable {
@@ -33,7 +33,7 @@
* @param userID user for which recommendations are to be computed
* @param howMany desired number of recommendations
* @return {@link List} of recommended {@link RecommendedItem}s, ordered from most strongly recommend to least
- * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+ * @throws TasteException if an error occurs while accessing the {@link DataModel}
*/
List<RecommendedItem> recommend(Comparable<?> userID, int howMany) throws TasteException;
@@ -42,7 +42,7 @@
* @param howMany desired number of recommendations
* @param rescorer rescoring function to apply before final list of recommendations is determined
* @return {@link List} of recommended {@link RecommendedItem}s, ordered from most strongly recommend to least
- * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+ * @throws TasteException if an error occurs while accessing the {@link DataModel}
*/
List<RecommendedItem> recommend(Comparable<?> userID, int howMany, Rescorer<Comparable<?>> rescorer)
throws TasteException;
@@ -52,22 +52,22 @@
* @param itemID item ID to estimate preference for
* @return an estimated preference if the user has not expressed a preference for the item, or else the user's actual
* preference for the item. If a preference cannot be estimated, returns {@link Double#NaN}
- * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+ * @throws TasteException if an error occurs while accessing the {@link DataModel}
*/
- double estimatePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
+ float estimatePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
/**
* @param userID user to set preference for
* @param itemID item to set preference for
* @param value preference value
- * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+ * @throws TasteException if an error occurs while accessing the {@link DataModel}
*/
- void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) throws TasteException;
+ void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) throws TasteException;
/**
* @param userID user from which to remove preference
* @param itemID item for which to remove preference
- * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+ * @throws TasteException if an error occurs while accessing the {@link DataModel}
*/
void removePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java Tue Aug 4 00:06:46 2009
@@ -18,8 +18,8 @@
package org.apache.mahout.cf.taste.recommender;
/**
- * <p>A {@link Rescorer} simply assigns a new "score" to a thing like an {@link org.apache.mahout.cf.taste.model.Item}
- * or {@link org.apache.mahout.cf.taste.model.User} which a {@link Recommender} is considering returning as a top
+ * <p>A {@link Rescorer} simply assigns a new "score" to a thing like an ID of an item
+ * or user which a {@link Recommender} is considering returning as a top
* recommendation. It may be used to arbitrarily re-rank the results according to application-specific logic before
* returning recommendations. For example, an application may want to boost the score of items in a certain category
* just for one request.</p>
@@ -30,8 +30,7 @@
public interface Rescorer<T> {
/**
- * @param thing thing ({@link org.apache.mahout.cf.taste.model.Item} or {@link org.apache.mahout.cf.taste.model.User}
- * really) to rescore
+ * @param thing thing to rescore
* @param originalScore original score
* @return modified score, or {@link Double#NaN} to indicate that this should be excluded entirely
*/
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java Tue Aug 4 00:06:46 2009
@@ -18,7 +18,6 @@
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.Pair;
-import org.apache.mahout.cf.taste.model.User;
import java.util.List;
@@ -26,22 +25,24 @@
public interface UserBasedRecommender extends Recommender {
/**
- * @param userID ID of {@link User} for which to find most similar other {@link User}s
- * @param howMany desired number of most similar {@link User}s to find
- * @return {@link User}s most similar to the given user
+ * @param userID ID of user for which to find most similar other users
+ * @param howMany desired number of most similar users to find
+ * @return users most similar to the given user
* @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
*/
- List<User> mostSimilarUsers(Comparable<?> userID, int howMany) throws TasteException;
+ List<Comparable<?>> mostSimilarUserIDs(Comparable<?> userID, int howMany) throws TasteException;
/**
- * @param userID ID of {@link User} for which to find most similar other {@link User}s
- * @param howMany desired number of most similar {@link User}s to find
+ * @param userID ID of user for which to find most similar other users
+ * @param howMany desired number of most similar users to find
* @param rescorer {@link Rescorer} which can adjust user-user similarity estimates used to determine most similar
* users
- * @return {@link User}s most similar to the given user
+ * @return IDs of users most similar to the given user
* @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
*/
- List<User> mostSimilarUsers(Comparable<?> userID, int howMany, Rescorer<Pair<User, User>> rescorer)
- throws TasteException;
+ List<Comparable<?>> mostSimilarUserIDs(Comparable<?> userID,
+ int howMany,
+ Rescorer<Pair<Comparable<?>,
+ Comparable<?>>> rescorer) throws TasteException;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java Tue Aug 4 00:06:46 2009
@@ -20,7 +20,7 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.RunningAverage;
-import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import java.util.List;
import java.util.Set;
@@ -47,7 +47,7 @@
* @param prefs user's preferendces
* @return {@link List} of {@link RunningAverage} for that user's item-item diffs
*/
- RunningAverage[] getDiffs(Comparable<?> userID, Comparable<?> itemID, Preference[] prefs) throws TasteException;
+ RunningAverage[] getDiffs(Comparable<?> userID, Comparable<?> itemID, PreferenceArray prefs) throws TasteException;
/** @return {@link RunningAverage} encapsulating the average preference for the given item */
RunningAverage getAverageItemPref(Comparable<?> itemID) throws TasteException;
@@ -59,7 +59,7 @@
* @param prefDelta amount by which preference value changed (or its old value, if being removed
* @param remove if <code>true</code>, operation reflects a removal rather than change of preference
*/
- void updateItemPref(Comparable<?> itemID, double prefDelta, boolean remove) throws TasteException;
+ void updateItemPref(Comparable<?> itemID, float prefDelta, boolean remove) throws TasteException;
/**
* @return item IDs that may possibly be recommended to the given user, which may not be all items since
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java Tue Aug 4 00:06:46 2009
@@ -29,8 +29,8 @@
public interface ItemSimilarity extends Refreshable {
/**
- * <p>Returns the degree of similarity, of two items, based on the preferences that {@link
- * org.apache.mahout.cf.taste.model.User}s have expressed for the items.</p>
+ * <p>Returns the degree of similarity, of two items, based on the preferences that
+ * users have expressed for the items.</p>
*
* @param itemID1 first item ID
* @param itemID2 second item ID
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java Tue Aug 4 00:06:46 2009
@@ -19,23 +19,22 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
/**
- * <p>Implementations of this interface compute an inferred preference for a {@link User} and an item that the
+ * <p>Implementations of this interface compute an inferred preference for a user and an item that the
* user has not expressed any preference for. This might be an average of other preferences scores from that user, for
* example. This technique is sometimes called "default voting".</p>
*/
public interface PreferenceInferrer extends Refreshable {
/**
- * <p>Infers the given {@link User}'s preference value for an item.</p>
+ * <p>Infers the given user's preference value for an item.</p>
*
- * @param user {@link User} to infer preference for
+ * @param userID ID of user to infer preference for
* @param itemID item ID to infer preference for
* @return inferred preference
* @throws TasteException if an error occurs while inferring
*/
- double inferPreference(User user, Comparable<?> itemID) throws TasteException;
+ float inferPreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java Tue Aug 4 00:06:46 2009
@@ -19,10 +19,9 @@
import org.apache.mahout.cf.taste.common.Refreshable;
import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
/**
- * <p>Implementations of this interface define a notion of similarity between two {@link User}s. Implementations should
+ * <p>Implementations of this interface define a notion of similarity between two users. Implementations should
* return values in the range -1.0 to 1.0, with 1.0 representing perfect similarity.</p>
*
* @see ItemSimilarity
@@ -30,14 +29,14 @@
public interface UserSimilarity extends Refreshable {
/**
- * <p>Returns the degree of similarity, of two {@link User}s, based on the their preferences.</p>
+ * <p>Returns the degree of similarity, of two users, based on the their preferences.</p>
*
- * @param user1 first user
- * @param user2 second user
+ * @param userID1 first user ID
+ * @param userID2 second user ID
* @return similarity between the two users, in [-1,1]
* @throws TasteException if an error occurs while accessing the data
*/
- double userSimilarity(User user1, User user2) throws TasteException;
+ double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException;
/**
* <p>Attaches a {@link PreferenceInferrer} to the {@link UserSimilarity} implementation.</p>
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java Tue Aug 4 00:06:46 2009
@@ -29,6 +29,6 @@
*/
public interface PreferenceTransform extends Refreshable {
- double getTransformedValue(Preference pref) throws TasteException;
+ float getTransformedValue(Preference pref) throws TasteException;
}
\ No newline at end of file
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java Tue Aug 4 00:06:46 2009
@@ -21,8 +21,7 @@
/**
* <p>Implementations encapsulate some transformation on similarity values between two things, where things might be
- * {@link org.apache.mahout.cf.taste.model.User}s or {@link org.apache.mahout.cf.taste.model.Item}s or something
- * else.</p>
+ * IDs of users or items or something else.</p>
*/
public interface SimilarityTransform<T> extends Refreshable {
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java Tue Aug 4 00:06:46 2009
@@ -16,8 +16,6 @@
*/
package org.apache.mahout.clustering.kmeans;
-import java.io.IOException;
-
import org.apache.commons.cli2.CommandLine;
import org.apache.commons.cli2.Group;
import org.apache.commons.cli2.Option;
@@ -46,6 +44,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+
public class KMeansDriver {
/** The name of the directory used to output final results. */
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java Tue Aug 4 00:06:46 2009
@@ -19,10 +19,11 @@
import junit.textui.TestRunner;
import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
import org.apache.mahout.cf.taste.impl.common.RandomUtils;
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.model.GenericUserPreferenceArray;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
@@ -30,8 +31,7 @@
import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
@@ -42,6 +42,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@@ -90,24 +91,22 @@
}
private DataModel createModel() {
-
List<Comparable<?>> itemIDs = new ArrayList<Comparable<?>>(NUM_ITEMS);
for (int i = 0; i < NUM_ITEMS; i++) {
itemIDs.add(String.valueOf(i));
}
-
- List<User> users = new ArrayList<User>(NUM_USERS);
+ Map<Comparable<?>, PreferenceArray> data = new FastMap<Comparable<?>, PreferenceArray>(NUM_USERS);
for (int i = 0; i < NUM_USERS; i++) {
+ String userID = String.valueOf(i);
+
int numPrefs = random.nextInt(NUM_PREFS) + 1;
- List<Preference> prefs = new ArrayList<Preference>(numPrefs);
+ PreferenceArray prefs = new GenericUserPreferenceArray(numPrefs);
for (int j = 0; j < numPrefs; j++) {
- prefs.add(new GenericPreference(null, itemIDs.get(random.nextInt(NUM_ITEMS)), random.nextDouble()));
+ prefs.set(j, new GenericPreference(userID, itemIDs.get(random.nextInt(NUM_ITEMS)), random.nextFloat()));
}
- GenericUser user = new GenericUser(String.valueOf(i), prefs);
- users.add(user);
+ data.put(userID, prefs);
}
-
- return new GenericDataModel(users);
+ return new GenericDataModel(data);
}
private void doTestLoad(Recommender recommender, int allowedTimeSec)
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java Tue Aug 4 00:06:46 2009
@@ -18,17 +18,18 @@
package org.apache.mahout.cf.taste.impl;
import junit.framework.TestCase;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
import org.apache.mahout.cf.taste.impl.common.RandomUtils;
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.model.GenericUserPreferenceArray;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
+import java.util.Map;
public abstract class TasteTestCase extends TestCase {
@@ -41,33 +42,31 @@
RandomUtils.useTestSeed();
}
- public static User getUser(String userID, Double... values) {
- List<Preference> prefs = new ArrayList<Preference>(values.length);
- int i = 0;
- for (Double value : values) {
- if (value != null) {
- prefs.add(new GenericPreference(null, String.valueOf(i), value));
+ public static DataModel getDataModel(Comparable<?>[] userIDs, Double[][] prefValues) {
+ Map<Comparable<?>, PreferenceArray> result = new FastMap<Comparable<?>, PreferenceArray>();
+ for (int i = 0; i < userIDs.length; i++) {
+ List<Preference> prefsList = new ArrayList<Preference>();
+ for (int j = 0; j < prefValues[i].length; j++) {
+ if (prefValues[i][j] != null) {
+ prefsList.add(new GenericPreference(userIDs[i], String.valueOf(j), prefValues[i][j].floatValue()));
+ }
+ }
+ if (!prefsList.isEmpty()) {
+ result.put(userIDs[i], new GenericUserPreferenceArray(prefsList));
}
- i++;
}
- return new GenericUser(userID, prefs);
- }
-
- public static DataModel getDataModel(User... users) {
- return new GenericDataModel(Arrays.asList(users));
+ return new GenericDataModel(result);
}
public static DataModel getDataModel() {
- return new GenericDataModel(getMockUsers());
- }
-
- public static List<User> getMockUsers() {
- List<User> users = new ArrayList<User>(4);
- users.add(getUser("test1", 0.1, 0.3));
- users.add(getUser("test2", 0.2, 0.3, 0.3));
- users.add(getUser("test3", 0.4, 0.3, 0.5));
- users.add(getUser("test4", 0.7, 0.3, 0.8));
- return users;
+ return getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+ new Double[][] {
+ {0.1, 0.3},
+ {0.2, 0.3, 0.3},
+ {0.4, 0.3, 0.5},
+ {0.7, 0.3, 0.8},
+ });
}
}
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=800634&r1=800633&r2=800634&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 Tue Aug 4 00:06:46 2009
@@ -24,7 +24,7 @@
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
@@ -100,11 +100,11 @@
public void testTranspose() throws Exception {
FileDataModel tModel = new FileDataModel(testFile, true);
- User user = tModel.getUser("456");
- assertNotNull("user is null and it shouldn't be", user);
- Preference[] pref = tModel.getPreferencesForItemAsArray("A123");
+ PreferenceArray userPrefs = tModel.getPreferencesFromUser("456");
+ assertNotNull("user prefs are null and it shouldn't be", userPrefs);
+ PreferenceArray pref = tModel.getPreferencesForItem("A123");
assertNotNull("pref is null and it shouldn't be", pref);
- assertEquals("pref Size: " + pref.length + " is not: " + 3, 3, pref.length);
+ assertEquals("pref Size: " + pref.length() + " is not: " + 3, 3, pref.length());
}
public void testGetItems() throws Exception {
@@ -132,25 +132,15 @@
}
public void testPreferencesForItem() throws Exception {
- Iterable<? extends Preference> prefs = model.getPreferencesForItem("456");
+ PreferenceArray prefs = model.getPreferencesForItem("456");
assertNotNull(prefs);
- Iterator<? extends Preference> it = prefs.iterator();
- assertNotNull(it);
- assertTrue(it.hasNext());
- Preference pref1 = it.next();
- assertEquals("A123", pref1.getUser().getID());
+ Preference pref1 = prefs.get(0);
+ assertEquals("A123", pref1.getUserID());
assertEquals("456", pref1.getItemID());
- assertTrue(it.hasNext());
- Preference pref2 = it.next();
- assertEquals("D456", pref2.getUser().getID());
+ Preference pref2 = prefs.get(1);
+ assertEquals("D456", pref2.getUserID());
assertEquals("456", pref2.getItemID());
- assertFalse(it.hasNext());
- try {
- it.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException nsee) {
- // good
- }
+ assertEquals(2, prefs.length());
}
public void testGetNumUsers() throws Exception {
@@ -164,16 +154,6 @@
assertEquals(2, model.getNumUsersWithPreferenceFor("123", "234"));
}
- public void testSetPreference() throws Exception {
- model.setPreference("A123", "456", 0.2);
- assertEquals(0.2, model.getUser("A123").getPreferenceFor("456").getValue());
- }
-
- public void testRemovePreference() throws Exception {
- model.removePreference("A123", "456");
- assertNull(model.getUser("A123").getPreferenceFor("456"));
- }
-
public void testRefresh() throws Exception {
final AtomicBoolean initialized = new AtomicBoolean(false);
Runnable initializer = new Runnable() {
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java Tue Aug 4 00:06:46 2009
@@ -18,7 +18,8 @@
package org.apache.mahout.cf.taste.impl.neighborhood;
import org.apache.mahout.cf.taste.common.Refreshable;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
@@ -27,10 +28,16 @@
final class DummySimilarity implements UserSimilarity, ItemSimilarity {
+ private final DataModel dataModel;
+
+ DummySimilarity(DataModel dataModel) {
+ this.dataModel = dataModel;
+ }
+
@Override
- public double userSimilarity(User user1, User user2) {
- return 1.0 / Math.abs(user1.getPreferencesAsArray()[0].getValue() -
- user2.getPreferencesAsArray()[0].getValue());
+ public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
+ return 1.0 / Math.abs(dataModel.getPreferencesFromUser(userID1).get(0).getValue() -
+ dataModel.getPreferencesFromUser(userID2).get(0).getValue());
}
@Override
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java Tue Aug 4 00:06:46 2009
@@ -18,49 +18,38 @@
package org.apache.mahout.cf.taste.impl.neighborhood;
import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
/** <p>Tests {@link NearestNUserNeighborhood}.</p> */
public final class NearestNNeighborhoodTest extends TasteTestCase {
public void testNeighborhood() throws Exception {
- List<User> users = getMockUsers();
- DataModel dataModel = new GenericDataModel(users);
+ DataModel dataModel = getDataModel();
- Collection<User> neighborhood =
- new NearestNUserNeighborhood(1, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+ Collection<Comparable<?>> neighborhood =
+ new NearestNUserNeighborhood(1, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
assertNotNull(neighborhood);
assertEquals(1, neighborhood.size());
- assertTrue(neighborhood.contains(users.get(1)));
+ assertTrue(neighborhood.contains("test2"));
- Collection<User> neighborhood2 =
- new NearestNUserNeighborhood(2, new DummySimilarity(), dataModel).getUserNeighborhood("test2");
+ Collection<Comparable<?>> neighborhood2 =
+ new NearestNUserNeighborhood(2, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test2");
assertNotNull(neighborhood2);
assertEquals(2, neighborhood2.size());
- assertTrue(neighborhood2.contains(users.get(0)));
- assertTrue(neighborhood2.contains(users.get(2)));
+ assertTrue(neighborhood2.contains("test1"));
+ assertTrue(neighborhood2.contains("test3"));
- Collection<User> neighborhood3 =
- new NearestNUserNeighborhood(4, new DummySimilarity(), dataModel).getUserNeighborhood("test4");
+ Collection<Comparable<?>> neighborhood3 =
+ new NearestNUserNeighborhood(4, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test4");
assertNotNull(neighborhood3);
assertEquals(3, neighborhood3.size());
- assertTrue(neighborhood3.contains(users.get(0)));
- assertTrue(neighborhood3.contains(users.get(1)));
- assertTrue(neighborhood3.contains(users.get(2)));
+ assertTrue(neighborhood3.contains("test1"));
+ assertTrue(neighborhood3.contains("test2"));
+ assertTrue(neighborhood3.contains("test3"));
}
- public void testRefresh() throws Exception {
- // Make sure this doesn't throw an exception
- DataModel dataModel = new GenericDataModel(Collections.singletonList(getUser("test1", 0.1)));
- new NearestNUserNeighborhood(1, new DummySimilarity(), dataModel).refresh(null);
- }
-
}
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java Tue Aug 4 00:06:46 2009
@@ -18,47 +18,36 @@
package org.apache.mahout.cf.taste.impl.neighborhood;
import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
/** <p>Tests {@link ThresholdUserNeighborhood}.</p> */
public final class ThresholdNeighborhoodTest extends TasteTestCase {
public void testNeighborhood() throws Exception {
- List<User> users = getMockUsers();
- DataModel dataModel = new GenericDataModel(users);
+ DataModel dataModel = getDataModel();
- Collection<User> neighborhood =
- new ThresholdUserNeighborhood(20.0, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+ Collection<Comparable<?>> neighborhood =
+ new ThresholdUserNeighborhood(19.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
assertNotNull(neighborhood);
assertTrue(neighborhood.isEmpty());
- Collection<User> neighborhood2 =
- new ThresholdUserNeighborhood(10.0, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+ Collection<Comparable<?>> neighborhood2 =
+ new ThresholdUserNeighborhood(9.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
assertNotNull(neighborhood2);
assertEquals(1, neighborhood2.size());
- assertTrue(neighborhood2.contains(users.get(1)));
+ assertTrue(neighborhood2.contains("test2"));
- Collection<User> neighborhood3 =
- new ThresholdUserNeighborhood(1.0, new DummySimilarity(), dataModel).getUserNeighborhood("test2");
+ Collection<Comparable<?>> neighborhood3 =
+ new ThresholdUserNeighborhood(0.9, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test2");
assertNotNull(neighborhood3);
assertEquals(3, neighborhood3.size());
- assertTrue(neighborhood3.contains(users.get(0)));
- assertTrue(neighborhood3.contains(users.get(2)));
- assertTrue(neighborhood3.contains(users.get(3)));
+ assertTrue(neighborhood3.contains("test1"));
+ assertTrue(neighborhood3.contains("test3"));
+ assertTrue(neighborhood3.contains("test4"));
}
- public void testRefresh() throws Exception {
- // Make sure this doesn't throw an exception
- DataModel dataModel = new GenericDataModel(Collections.singletonList(getUser("test1", 0.1)));
- new ThresholdUserNeighborhood(20.0, new DummySimilarity(), dataModel).refresh(null);
- }
-
}
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java Tue Aug 4 00:06:46 2009
@@ -18,10 +18,8 @@
package org.apache.mahout.cf.taste.impl.recommender;
import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.similarity.GenericItemSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
import org.apache.mahout.cf.taste.recommender.ItemBasedRecommender;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
@@ -48,13 +46,17 @@
}
public void testHowMany() throws Exception {
- List<User> users = new ArrayList<User>(3);
- users.add(getUser("test1", 0.1, 0.2));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
- users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
- users.add(getUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
- users.add(getUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
- DataModel dataModel = new GenericDataModel(users);
+
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3", "test4", "test5"},
+ new Double[][] {
+ {0.1, 0.2},
+ {0.2, 0.3, 0.3, 0.6},
+ {0.4, 0.4, 0.5, 0.9},
+ {0.1, 0.4, 0.5, 0.8, 0.9, 1.0},
+ {0.2, 0.3, 0.6, 0.7, 0.1, 0.2},
+ });
+
Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(6);
for (int i = 0; i < 6; i++) {
@@ -79,11 +81,15 @@
}
public void testRescorer() throws Exception {
- List<User> users = new ArrayList<User>(3);
- users.add(getUser("test1", 0.1, 0.2));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
- users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
- DataModel dataModel = new GenericDataModel(users);
+
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3"},
+ new Double[][] {
+ {0.1, 0.2},
+ {0.2, 0.3, 0.3, 0.6},
+ {0.4, 0.4, 0.5, 0.9},
+ });
+
Comparable<?> item1 = "0";
Comparable<?> item2 = "1";
Comparable<?> item3 = "2";
@@ -175,7 +181,7 @@
}
private static ItemBasedRecommender buildRecommender() {
- DataModel dataModel = new GenericDataModel(getMockUsers());
+ DataModel dataModel = getDataModel();
Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(2);
Comparable<?> item1 = "0";
@@ -188,12 +194,16 @@
}
private static ItemBasedRecommender buildRecommender2() {
- List<User> users = new ArrayList<User>(4);
- users.add(getUser("test1", 0.1, 0.3, 0.9, 0.8));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.4));
- users.add(getUser("test3", 0.4, 0.3, 0.5, 0.1, 0.1));
- users.add(getUser("test4", 0.7, 0.3, 0.8, 0.5, 0.6));
- DataModel dataModel = new GenericDataModel(users);
+
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+ new Double[][] {
+ {0.1, 0.3, 0.9, 0.8},
+ {0.2, 0.3, 0.3, 0.4},
+ {0.4, 0.3, 0.5, 0.1, 0.1},
+ {0.7, 0.3, 0.8, 0.5, 0.6},
+ });
+
Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(10);
Comparable<?> item1 = "0";
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java Tue Aug 4 00:06:46 2009
@@ -18,18 +18,15 @@
package org.apache.mahout.cf.taste.impl.recommender;
import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
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.User;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.recommender.UserBasedRecommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -43,20 +40,22 @@
assertEquals(1, recommended.size());
RecommendedItem firstRecommended = recommended.get(0);
assertEquals("2", firstRecommended.getItemID());
- assertEquals(0.3, firstRecommended.getValue());
+ assertEquals(0.3f, firstRecommended.getValue());
recommender.refresh(null);
assertEquals("2", firstRecommended.getItemID());
- assertEquals(0.3, firstRecommended.getValue());
+ assertEquals(0.3f, firstRecommended.getValue());
}
public void testHowMany() throws Exception {
- List<User> users = new ArrayList<User>(3);
- users.add(getUser("test1", 0.1, 0.2));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
- users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
- users.add(getUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
- users.add(getUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
- DataModel dataModel = new GenericDataModel(users);
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3", "test4", "test5"},
+ new Double[][] {
+ {0.1, 0.2},
+ {0.2, 0.3, 0.3, 0.6},
+ {0.4, 0.4, 0.5, 0.9},
+ {0.1, 0.4, 0.5, 0.8, 0.9, 1.0},
+ {0.2, 0.3, 0.6, 0.7, 0.1, 0.2},
+ });
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
@@ -72,11 +71,13 @@
}
public void testRescorer() throws Exception {
- List<User> users = new ArrayList<User>(3);
- users.add(getUser("test1", 0.1, 0.2));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
- users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
- DataModel dataModel = new GenericDataModel(users);
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3"},
+ new Double[][] {
+ {0.1, 0.2},
+ {0.2, 0.3, 0.3, 0.6},
+ {0.4, 0.4, 0.5, 0.9},
+ });
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, similarity, dataModel);
Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
@@ -93,7 +94,7 @@
public void testEstimatePref() throws Exception {
Recommender recommender = buildRecommender();
- assertEquals(0.3, recommender.estimatePreference("test1", "2"));
+ assertEquals(0.3f, recommender.estimatePreference("test1", "2"));
}
public void testBestRating() throws Exception {
@@ -104,37 +105,37 @@
RecommendedItem firstRecommended = recommended.get(0);
// item one should be recommended because it has a greater rating/score
assertEquals("2", firstRecommended.getItemID());
- assertEquals(0.3, firstRecommended.getValue(), EPSILON);
+ assertEquals(0.3f, firstRecommended.getValue(), EPSILON);
}
public void testMostSimilar() throws Exception {
UserBasedRecommender recommender = buildRecommender();
- List<User> similar = recommender.mostSimilarUsers("test1", 2);
+ List<Comparable<?>> similar = recommender.mostSimilarUserIDs("test1", 2);
assertNotNull(similar);
assertEquals(2, similar.size());
- User first = similar.get(0);
- User second = similar.get(1);
- assertEquals("test2", first.getID());
- assertEquals("test3", second.getID());
+ assertEquals("test2", similar.get(0));
+ assertEquals("test4", similar.get(1));
}
public void testIsolatedUser() throws Exception {
- List<User> users = new ArrayList<User>(3);
- users.add(getUser("test1", 0.1, 0.2));
- users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
- users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
- users.add(getUser("test4"));
- DataModel dataModel = new GenericDataModel(users);
+ DataModel dataModel = getDataModel(
+ new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+ new Double[][] {
+ {0.1, 0.2},
+ {0.2, 0.3, 0.3, 0.6},
+ {0.4, 0.4, 0.5, 0.9},
+ {null, null, null, null, 1.0},
+ });
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, similarity, dataModel);
UserBasedRecommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
- Collection<User> mostSimilar = recommender.mostSimilarUsers("test4", 3);
+ Collection<Comparable<?>> mostSimilar = recommender.mostSimilarUserIDs("test4", 3);
assertNotNull(mostSimilar);
assertEquals(0, mostSimilar.size());
}
private static UserBasedRecommender buildRecommender() throws Exception {
- DataModel dataModel = new GenericDataModel(getMockUsers());
+ DataModel dataModel = getDataModel();
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, similarity, dataModel);
return new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java Tue Aug 4 00:06:46 2009
@@ -18,16 +18,12 @@
package org.apache.mahout.cf.taste.impl.recommender;
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.GenericUser;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
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 java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -46,7 +42,7 @@
public List<RecommendedItem> recommend(Comparable<?> userID, int howMany) {
recommendCount.incrementAndGet();
return Collections.<RecommendedItem>singletonList(
- new GenericRecommendedItem("1", 1.0));
+ new GenericRecommendedItem("1", 1.0f));
}
@Override
@@ -57,13 +53,13 @@
}
@Override
- public double estimatePreference(Comparable<?> userID, Comparable<?> itemID) {
+ public float estimatePreference(Comparable<?> userID, Comparable<?> itemID) {
recommendCount.incrementAndGet();
- return 0.0;
+ return 0.0f;
}
@Override
- public void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) {
+ public void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) {
// do nothing
}
@@ -74,14 +70,9 @@
@Override
public DataModel getDataModel() {
- User user1 = new GenericUser("1", Collections.<Preference>emptyList());
- User user2 = new GenericUser("2", Collections.<Preference>emptyList());
- User user3 = new GenericUser("3", Collections.<Preference>emptyList());
- List<User> users = new ArrayList<User>(3);
- users.add(user1);
- users.add(user2);
- users.add(user3);
- return new GenericDataModel(users);
+ return TasteTestCase.getDataModel(
+ new Comparable<?>[] {"1","2","3"},
+ new Double[][]{{1.0},{2.0},{3.0}});
}
@Override