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 [1/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...
Author: srowen
Date: Tue Aug 4 00:06:46 2009
New Revision: 800634
URL: http://svn.apache.org/viewvc?rev=800634&view=rev
Log:
Remove User/Item abstractions. Preference values are now floats. Lots of API changes to reflect and rationalize these changes. Replace Preference[] with PreferenceArray implementations for memory efficiency.
Added:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArray.java
- copied, changed from r797487, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanPrefDataModel.java
- copied, changed from r797487, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanUserDataModel.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArray.java
- copied, changed from r800080, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java
- copied, changed from r800080, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericBooleanPrefUserBasedRecommender.java
- copied, changed from r797487, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/BooleanUserGenericUserBasedRecommender.java
Removed:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPrefUser.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/ByItemPreferenceComparator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/ByUserPreferenceComparator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/ByValuePreferenceComparator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanUserDataModel.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUser.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/SettableUserPreference.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/BooleanUserGenericUserBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanLogLikelihoodSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/User.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingUser.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/GeoUserSimilarity.java
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemItemWritable.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemPrefWritable.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/RecommendedItemsWritable.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesJob.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesReducer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsJob.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsMapper.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsReducer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastMap.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastSet.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RandomUtils.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshHelper.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/AbstractJDBCComponent.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AbstractDifferenceRecommenderEvaluator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AverageAbsoluteDifferenceRecommenderEvaluator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/RMSRecommenderEvaluator.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPreference.java
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/GenericPreference.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/AbstractBooleanPrefJDBCDataModel.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/ConnectionPoolDataSource.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/MySQLBooleanPrefJDBCDataModel.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/impl/neighborhood/CachingUserNeighborhood.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNUserNeighborhood.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdUserNeighborhood.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/ClusterSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/FarthestNeighborClusterSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericRecommendedItem.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/ItemAverageRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/ItemUserAverageRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/NearestNeighborClusterSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/NullRescorer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SimilarUser.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/TopItems.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/TreeClusteringRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/TreeClusteringRecommender2.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/MemoryDiffStorage.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/SlopeOneRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/jdbc/AbstractJDBCDiffStorage.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/jdbc/MySQLJDBCDiffStorage.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/AbstractSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/AveragingPreferenceInferrer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/CachingUserSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/EuclideanDistanceSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/GenericUserSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/PearsonCorrelationSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/NullRescorerTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/TreeClusteringRecommenderTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/MemoryDiffStorageTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/slopeone/SlopeOneRecommenderTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/AveragingPreferenceInferrerTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/EuclideanDistanceSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/GenericItemSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/PearsonCorrelationSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarityTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequencyTest.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/transforms/TransformTestCase.java
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/transforms/ZScoreTest.java
lucene/mahout/trunk/examples/ (props changed)
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/ejb/RecommenderEJB.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/ejb/RecommenderEJBBean.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/ejb/RecommenderEJBLocal.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingDataModel.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/bookcrossing/BookCrossingRecommender.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensDataModel.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/grouplens/GroupLensRecommender.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/jester/JesterDataModel.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/jester/JesterRecommender.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixDataModel.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixFileDataModel.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixRecommender.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/NetflixRecommenderEvaluatorRunner.java
lucene/mahout/trunk/examples/src/main/java/org/apache/mahout/cf/taste/example/netflix/TransposeToByUser.java
lucene/mahout/trunk/taste-web/src/main/java/org/apache/mahout/cf/taste/web/RecommenderServlet.java
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemItemWritable.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemItemWritable.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemItemWritable.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemItemWritable.java Tue Aug 4 00:06:46 2009
@@ -23,7 +23,7 @@
import java.io.DataOutput;
import java.io.IOException;
-/** A {@link WritableComparable} encapsulating two {@link org.apache.mahout.cf.taste.model.Item}s. */
+/** A {@link WritableComparable} encapsulating two items. */
public final class ItemItemWritable implements WritableComparable<ItemItemWritable> {
private String itemAID;
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemPrefWritable.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemPrefWritable.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemPrefWritable.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/ItemPrefWritable.java Tue Aug 4 00:06:46 2009
@@ -23,17 +23,17 @@
import java.io.DataOutput;
import java.io.IOException;
-/** A {@link Writable} encapsulating a {@link org.apache.mahout.cf.taste.model.Item} and a preference value. */
+/** A {@link Writable} encapsulating an item and a preference value. */
public final class ItemPrefWritable implements Writable {
private String itemID;
- private double prefValue;
+ private float prefValue;
public ItemPrefWritable() {
// do nothing
}
- public ItemPrefWritable(String itemID, double prefValue) {
+ public ItemPrefWritable(String itemID, float prefValue) {
this.itemID = itemID;
this.prefValue = prefValue;
}
@@ -46,20 +46,20 @@
return itemID;
}
- public double getPrefValue() {
+ public float getPrefValue() {
return prefValue;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(itemID);
- out.writeDouble(prefValue);
+ out.writeFloat(prefValue);
}
@Override
public void readFields(DataInput in) throws IOException {
itemID = in.readUTF();
- prefValue = in.readDouble();
+ prefValue = in.readFloat();
}
public static ItemPrefWritable read(DataInput in) throws IOException {
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/RecommendedItemsWritable.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/RecommendedItemsWritable.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/RecommendedItemsWritable.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/RecommendedItemsWritable.java Tue Aug 4 00:06:46 2009
@@ -52,7 +52,7 @@
public void write(DataOutput out) throws IOException {
for (RecommendedItem item : recommended) {
out.writeUTF(item.getItemID().toString());
- out.writeDouble(item.getValue());
+ out.writeFloat(item.getValue());
}
}
@@ -63,7 +63,7 @@
try {
do {
String itemID = in.readUTF();
- double value = in.readDouble();
+ float value = in.readFloat();
RecommendedItem recommendedItem = new GenericRecommendedItem(itemID, value);
recommended.add(recommendedItem);
} while (true);
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesJob.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesJob.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesJob.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesJob.java Tue Aug 4 00:06:46 2009
@@ -20,7 +20,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.mapreduce.InputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
@@ -64,11 +64,11 @@
jobConf.setClass("mapred.mapper.class", Mapper.class, Mapper.class);
jobConf.setClass("mapred.mapoutput.key.class", ItemItemWritable.class, Object.class);
- jobConf.setClass("mapred.mapoutput.value.class", DoubleWritable.class, Object.class);
+ jobConf.setClass("mapred.mapoutput.value.class", FloatWritable.class, Object.class);
jobConf.setClass("mapred.reducer.class", SlopeOneDiffsToAveragesReducer.class, Reducer.class);
jobConf.setClass("mapred.output.key.class", ItemItemWritable.class, Object.class);
- jobConf.setClass("mapred.output.value.class", DoubleWritable.class, Object.class);
+ jobConf.setClass("mapred.output.value.class", FloatWritable.class, Object.class);
jobConf.setClass("mapred.output.format.class", TextOutputFormat.class, OutputFormat.class);
jobConf.set("mapred.output.dir", StringUtils.escapeString(outputPathPath.toString()));
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesReducer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesReducer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesReducer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOneDiffsToAveragesReducer.java Tue Aug 4 00:06:46 2009
@@ -17,24 +17,24 @@
package org.apache.mahout.cf.taste.hadoop;
-import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public final class SlopeOneDiffsToAveragesReducer
- extends Reducer<ItemItemWritable, DoubleWritable, ItemItemWritable, DoubleWritable> {
+ extends Reducer<ItemItemWritable, FloatWritable, ItemItemWritable, FloatWritable> {
@Override
- protected void reduce(ItemItemWritable key, Iterable<DoubleWritable> values, Context context)
+ protected void reduce(ItemItemWritable key, Iterable<FloatWritable> values, Context context)
throws IOException, InterruptedException {
int count = 0;
double total = 0.0;
- for (DoubleWritable value : values) {
+ for (FloatWritable value : values) {
total += value.get();
count++;
}
- context.write(key, new DoubleWritable((total / count)));
+ context.write(key, new FloatWritable((float) (total / count)));
}
}
\ No newline at end of file
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsJob.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsJob.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsJob.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsJob.java Tue Aug 4 00:06:46 2009
@@ -20,7 +20,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputFormat;
import org.apache.hadoop.mapreduce.Job;
@@ -69,7 +69,7 @@
jobConf.setClass("mapred.reducer.class", SlopeOnePrefsToDiffsReducer.class, Reducer.class);
jobConf.setClass("mapred.output.key.class", ItemItemWritable.class, Object.class);
- jobConf.setClass("mapred.output.value.class", DoubleWritable.class, Object.class);
+ jobConf.setClass("mapred.output.value.class", FloatWritable.class, Object.class);
jobConf.setClass("mapred.output.format.class", SequenceFileOutputFormat.class, OutputFormat.class);
jobConf.set("mapred.output.dir", StringUtils.escapeString(outputPathPath.toString()));
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsMapper.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsMapper.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsMapper.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsMapper.java Tue Aug 4 00:06:46 2009
@@ -33,7 +33,7 @@
String[] tokens = line.split(",");
String userID = tokens[0];
String itemID = tokens[1];
- double prefValue = Double.parseDouble(tokens[2]);
+ float prefValue = Float.parseFloat(tokens[2]);
context.write(new Text(userID), new ItemPrefWritable(itemID, prefValue));
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsReducer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsReducer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsReducer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/hadoop/SlopeOnePrefsToDiffsReducer.java Tue Aug 4 00:06:46 2009
@@ -17,7 +17,7 @@
package org.apache.mahout.cf.taste.hadoop;
-import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
@@ -27,7 +27,7 @@
import java.util.List;
public final class SlopeOnePrefsToDiffsReducer
- extends Reducer<Text, ItemPrefWritable, ItemItemWritable, DoubleWritable> {
+ extends Reducer<Text, ItemPrefWritable, ItemItemWritable, FloatWritable> {
@Override
protected void reduce(Text key, Iterable<ItemPrefWritable> values, Context context)
@@ -41,12 +41,12 @@
for (int i = 0; i < size; i++) {
ItemPrefWritable first = prefs.get(i);
String itemAID = first.getItemID();
- double itemAValue = first.getPrefValue();
+ float itemAValue = first.getPrefValue();
for (int j = i + 1; j < size; j++) {
ItemPrefWritable second = prefs.get(j);
String itemBID = second.getItemID();
- double itemBValue = second.getPrefValue();
- context.write(new ItemItemWritable(itemAID, itemBID), new DoubleWritable(itemBValue - itemAValue));
+ float itemBValue = second.getPrefValue();
+ context.write(new ItemItemWritable(itemAID, itemBID), new FloatWritable(itemBValue - itemAValue));
}
}
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastMap.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastMap.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastMap.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastMap.java Tue Aug 4 00:06:46 2009
@@ -42,6 +42,7 @@
public final class FastMap<K, V> implements Map<K, V>, Serializable, Cloneable {
public static final int NO_MAX_SIZE = Integer.MAX_VALUE;
+ private static final double ALLOWED_LOAD_FACTOR = 1.5;
/** Dummy object used to represent a key that has been removed. */
private static final Object REMOVED = new Object();
@@ -63,25 +64,32 @@
this(size, NO_MAX_SIZE);
}
+ public FastMap(Map<K,V> other) {
+ this(other.size());
+ putAll(other);
+ }
+
/**
* Creates a new {@link FastMap} whose capacity can accommodate the given number of entries without rehash.</p>
*
* @param size desired capacity
* @param maxSize max capacity
- * @throws IllegalArgumentException if size is less than 1 or at least half of {@link RandomUtils#MAX_INT_SMALLER_TWIN_PRIME}
+ * @throws IllegalArgumentException if size is less than 0, maxSize is less than 1,
+ * or at least half of {@link RandomUtils#MAX_INT_SMALLER_TWIN_PRIME}
*/
@SuppressWarnings("unchecked")
public FastMap(int size, int maxSize) {
- if (size < 1) {
- throw new IllegalArgumentException("size must be at least 1");
+ if (size < 0) {
+ throw new IllegalArgumentException("size must be at least 0");
}
- if (size >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1) {
- throw new IllegalArgumentException("size must be less than " + (RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1));
+ int max = (int) (RandomUtils.MAX_INT_SMALLER_TWIN_PRIME / ALLOWED_LOAD_FACTOR);
+ if (size >= max) {
+ throw new IllegalArgumentException("size must be less than " + max);
}
if (maxSize < 1) {
throw new IllegalArgumentException("maxSize must be at least 1");
}
- int hashSize = RandomUtils.nextTwinPrime(2 * size);
+ int hashSize = RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * size));
keys = (K[]) new Object[hashSize];
values = (V[]) new Object[hashSize];
this.maxSize = maxSize;
@@ -170,9 +178,9 @@
throw new NullPointerException();
}
// If less than half the slots are open, let's clear it up
- if (numSlotsUsed >= keys.length >> 1) {
+ if (numSlotsUsed * ALLOWED_LOAD_FACTOR >= keys.length) {
// If over half the slots used are actual entries, let's grow
- if (numEntries >= numSlotsUsed >> 1) {
+ if (numEntries * ALLOWED_LOAD_FACTOR >= numSlotsUsed) {
growAndRehash();
} else {
// Otherwise just rehash to clear REMOVED entries and don't grow
@@ -275,14 +283,14 @@
}
public void rehash() {
- rehash(RandomUtils.nextTwinPrime(numEntries << 1));
+ rehash(RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * numEntries)));
}
private void growAndRehash() {
- if (keys.length >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1) {
+ if (keys.length * ALLOWED_LOAD_FACTOR >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME) {
throw new IllegalStateException("Can't grow any more");
}
- rehash(RandomUtils.nextTwinPrime(keys.length << 1));
+ rehash(RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * keys.length)));
}
@SuppressWarnings("unchecked")
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastSet.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastSet.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastSet.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FastSet.java Tue Aug 4 00:06:46 2009
@@ -41,6 +41,8 @@
*/
public final class FastSet<K> implements Set<K>, Serializable, Cloneable {
+ private static final double ALLOWED_LOAD_FACTOR = 1.5;
+
/** Dummy object used to represent a key that has been removed. */
private static final Object REMOVED = new Object();
@@ -60,13 +62,14 @@
@SuppressWarnings("unchecked")
public FastSet(int size) {
- if (size < 1) {
- throw new IllegalArgumentException("size must be at least 1");
+ if (size < 0) {
+ throw new IllegalArgumentException("size must be at least 0");
}
- if (size >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1) {
- throw new IllegalArgumentException("size must be less than " + (RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1));
+ int max = (int) (RandomUtils.MAX_INT_SMALLER_TWIN_PRIME / ALLOWED_LOAD_FACTOR);
+ if (size >= max) {
+ throw new IllegalArgumentException("size must be less than " + max);
}
- int hashSize = RandomUtils.nextTwinPrime(2 * size);
+ int hashSize = RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * size));
keys = (K[]) new Object[hashSize];
}
@@ -118,9 +121,9 @@
throw new NullPointerException();
}
// If less than half the slots are open, let's clear it up
- if (numSlotsUsed >= keys.length >> 1) {
+ if (numSlotsUsed * ALLOWED_LOAD_FACTOR >= keys.length) {
// If over half the slots used are actual entries, let's grow
- if (numEntries >= numSlotsUsed >> 1) {
+ if (numEntries * ALLOWED_LOAD_FACTOR >= numSlotsUsed) {
growAndRehash();
} else {
// Otherwise just rehash to clear REMOVED entries and don't grow
@@ -235,14 +238,14 @@
}
private void growAndRehash() {
- if (keys.length >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME >> 1) {
+ if (keys.length * ALLOWED_LOAD_FACTOR >= RandomUtils.MAX_INT_SMALLER_TWIN_PRIME) {
throw new IllegalStateException("Can't grow any more");
}
- rehash(RandomUtils.nextTwinPrime(keys.length << 1));
+ rehash(RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * keys.length)));
}
public void rehash() {
- rehash(RandomUtils.nextTwinPrime(numEntries << 1));
+ rehash(RandomUtils.nextTwinPrime((int) (ALLOWED_LOAD_FACTOR * numEntries)));
}
@SuppressWarnings("unchecked")
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/FileLineIterator.java Tue Aug 4 00:06:46 2009
@@ -78,6 +78,10 @@
}
}
+ public String peek() {
+ return nextLine;
+ }
+
@Override
public boolean hasNext() {
return nextLine != null;
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RandomUtils.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RandomUtils.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RandomUtils.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RandomUtils.java Tue Aug 4 00:06:46 2009
@@ -51,6 +51,10 @@
return (int) (bits ^ (bits >>> 32));
}
+ public static int hashFloat(float value) {
+ return Float.floatToIntBits(value);
+ }
+
/**
* <p>Finds next-largest "twin primes": numbers p and p+2 such that both are prime. Finds the smallest such p such
* that the smaller twin, p, is greater than or equal to n. Returns p+2, the larger of the two twins.</p>
@@ -59,7 +63,7 @@
if (n > MAX_INT_SMALLER_TWIN_PRIME) {
throw new IllegalArgumentException();
}
- if (n <= 2) {
+ if (n <= 3) {
return 3;
}
int next = nextPrime(n);
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshHelper.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshHelper.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshHelper.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshHelper.java Tue Aug 4 00:06:46 2009
@@ -93,7 +93,7 @@
* @return an empty {@link FastSet} if the method param was <code>null</code> or the unmodified method param.
*/
public static Collection<Refreshable> buildRefreshed(Collection<Refreshable> currentAlreadyRefreshed) {
- return currentAlreadyRefreshed == null ? new FastSet<Refreshable>(3) : currentAlreadyRefreshed;
+ return currentAlreadyRefreshed == null ? new FastSet<Refreshable>(2) : currentAlreadyRefreshed;
}
/**
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/AbstractJDBCComponent.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/AbstractJDBCComponent.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/AbstractJDBCComponent.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/AbstractJDBCComponent.java Tue Aug 4 00:06:46 2009
@@ -17,14 +17,14 @@
package org.apache.mahout.cf.taste.impl.common.jdbc;
+import org.apache.mahout.cf.taste.common.TasteException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.mahout.cf.taste.common.TasteException;
-import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
+import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AbstractDifferenceRecommenderEvaluator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AbstractDifferenceRecommenderEvaluator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AbstractDifferenceRecommenderEvaluator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AbstractDifferenceRecommenderEvaluator.java Tue Aug 4 00:06:46 2009
@@ -24,10 +24,9 @@
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.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.recommender.Recommender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,17 +70,18 @@
log.info("Beginning evaluation using " + trainingPercentage + " of " + dataModel);
int numUsers = dataModel.getNumUsers();
- Collection<User> trainingUsers = new ArrayList<User>(1 + (int) (trainingPercentage * (double) numUsers));
- Map<User, Collection<Preference>> testUserPrefs =
- new FastMap<User, Collection<Preference>>(1 + (int) ((1.0 - trainingPercentage) * (double) numUsers));
+ Map<Comparable<?>, Collection<Preference>> trainingUsers =
+ new FastMap<Comparable<?>, Collection<Preference>>(1 + (int) (trainingPercentage * (double) numUsers));
+ Map<Comparable<?>, Collection<Preference>> testUserPrefs =
+ new FastMap<Comparable<?>, Collection<Preference>>(1 + (int) ((1.0 - trainingPercentage) * (double) numUsers));
- for (User user : dataModel.getUsers()) {
+ for (Comparable<?> userID : dataModel.getUserIDs()) {
if (random.nextDouble() < evaluationPercentage) {
- processOneUser(trainingPercentage, trainingUsers, testUserPrefs, user);
+ processOneUser(trainingPercentage, trainingUsers, testUserPrefs, userID, dataModel);
}
}
- DataModel trainingModel = new GenericDataModel(trainingUsers);
+ DataModel trainingModel = new GenericDataModel(GenericDataModel.toPrefArrayValues(trainingUsers, true));
Recommender recommender = recommenderBuilder.buildRecommender(trainingModel);
@@ -91,14 +91,16 @@
}
private void processOneUser(double trainingPercentage,
- Collection<User> trainingUsers,
- Map<User, Collection<Preference>> testUserPrefs,
- User user) {
+ Map<Comparable<?>, Collection<Preference>> trainingUsers,
+ Map<Comparable<?>, Collection<Preference>> testUserPrefs,
+ Comparable<?> userID,
+ DataModel dataModel) throws TasteException {
List<Preference> trainingPrefs = new ArrayList<Preference>();
List<Preference> testPrefs = new ArrayList<Preference>();
- Preference[] prefs = user.getPreferencesAsArray();
- for (Preference pref : prefs) {
- Preference newPref = new GenericPreference(null, pref.getItemID(), pref.getValue());
+ PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+ int size = prefs.length();
+ for (int i = 0; i < size; i++) {
+ Preference newPref = new GenericPreference(userID, prefs.getItemID(i), prefs.getValue(i));
if (random.nextDouble() < trainingPercentage) {
trainingPrefs.add(newPref);
} else {
@@ -108,16 +110,14 @@
log.debug("Training against {} preferences", trainingPrefs.size());
log.debug("Evaluating accuracy of {} preferences", testPrefs.size());
if (!trainingPrefs.isEmpty()) {
- Comparable<?> id = user.getID();
- User trainingUser = new GenericUser(id, trainingPrefs);
- trainingUsers.add(trainingUser);
+ trainingUsers.put(userID, trainingPrefs);
if (!testPrefs.isEmpty()) {
- testUserPrefs.put(trainingUser, testPrefs);
+ testUserPrefs.put(userID, testPrefs);
}
}
}
- abstract double getEvaluation(Map<User, Collection<Preference>> testUserPrefs, Recommender recommender)
+ abstract double getEvaluation(Map<Comparable<?>, Collection<Preference>> testUserPrefs, Recommender recommender)
throws TasteException;
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AverageAbsoluteDifferenceRecommenderEvaluator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AverageAbsoluteDifferenceRecommenderEvaluator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AverageAbsoluteDifferenceRecommenderEvaluator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/AverageAbsoluteDifferenceRecommenderEvaluator.java Tue Aug 4 00:06:46 2009
@@ -23,7 +23,6 @@
import org.apache.mahout.cf.taste.impl.common.FullRunningAverage;
import org.apache.mahout.cf.taste.impl.common.RunningAverage;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,23 +41,23 @@
private static final Logger log = LoggerFactory.getLogger(AverageAbsoluteDifferenceRecommenderEvaluator.class);
@Override
- double getEvaluation(Map<User, Collection<Preference>> testUserPrefs,
+ double getEvaluation(Map<Comparable<?>, Collection<Preference>> testUserPrefs,
Recommender recommender)
throws TasteException {
RunningAverage average = new FullRunningAverage();
- for (Map.Entry<User, Collection<Preference>> entry : testUserPrefs.entrySet()) {
+ for (Map.Entry<Comparable<?>, Collection<Preference>> entry : testUserPrefs.entrySet()) {
for (Preference realPref : entry.getValue()) {
- User testUser = entry.getKey();
+ Comparable<?> testUserID = entry.getKey();
try {
- double estimatedPreference =
- recommender.estimatePreference(testUser.getID(), realPref.getItemID());
- if (!Double.isNaN(estimatedPreference)) {
+ float estimatedPreference =
+ recommender.estimatePreference(testUserID, realPref.getItemID());
+ if (!Float.isNaN(estimatedPreference)) {
average.addDatum(Math.abs(realPref.getValue() - estimatedPreference));
}
} catch (NoSuchUserException nsue) {
// It's possible that an item exists in the test data but not training data in which case
// NSEE will be thrown. Just ignore it and move on.
- log.debug("User exists in test data but not training data: {}", testUser.getID(), nsue);
+ log.debug("User exists in test data but not training data: {}", testUserID, nsue);
} catch (NoSuchItemException nsie) {
log.debug("Item exists in test data but not training data: {}", realPref.getItemID(), nsie);
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluator.java Tue Aug 4 00:06:46 2009
@@ -22,20 +22,17 @@
import org.apache.mahout.cf.taste.eval.IRStatistics;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
import org.apache.mahout.cf.taste.impl.common.FastSet;
import org.apache.mahout.cf.taste.impl.common.FullRunningAverage;
import org.apache.mahout.cf.taste.impl.common.FullRunningAverageAndStdDev;
import org.apache.mahout.cf.taste.impl.common.RandomUtils;
import org.apache.mahout.cf.taste.impl.common.RunningAverage;
import org.apache.mahout.cf.taste.impl.common.RunningAverageAndStdDev;
-import org.apache.mahout.cf.taste.impl.model.BooleanPrefUser;
-import org.apache.mahout.cf.taste.impl.model.ByValuePreferenceComparator;
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.model.GenericBooleanUserDataModel;
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.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.recommender.Rescorer;
@@ -43,17 +40,17 @@
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Random;
/**
- * <p>For each {@link User}, these implementation determine the top <code>n</code> preferences, then evaluate the IR
+ * <p>For each user, these implementation determine the top <code>n</code> preferences, then evaluate the IR
* statistics based on a {@link DataModel} that does not have these values. This number <code>n</code> is the "at"
* value, as in "precision at 5". For example, this would mean precision evaluated by removing the top 5 preferences for
- * a {@link User} and then finding the percentage of those 5 items included in the top 5 recommendations for
+ * a user and then finding the percentage of those 5 items included in the top 5 recommendations for
* that user.</p>
*/
public final class GenericRecommenderIRStatsEvaluator implements RecommenderIRStatsEvaluator {
@@ -100,49 +97,44 @@
RunningAverage precision = new FullRunningAverage();
RunningAverage recall = new FullRunningAverage();
RunningAverage fallOut = new FullRunningAverage();
- for (User user : dataModel.getUsers()) {
+ for (Comparable<?> userID : dataModel.getUserIDs()) {
if (random.nextDouble() < evaluationPercentage) {
long start = System.currentTimeMillis();
- Comparable<?> id = user.getID();
Collection<Comparable<?>> relevantItemIDs = new FastSet<Comparable<?>>(at);
- Preference[] prefs = user.getPreferencesAsArray();
- if (prefs.length < 2 * at) {
+ PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+ int size = prefs.length();
+ if (size < 2 * at) {
// Really not enough prefs to meaningfully evaluate this user
continue;
}
// List some most-preferred items that would count as (most) "relevant" results
double theRelevanceThreshold = Double.isNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold;
- Arrays.sort(prefs, Collections.reverseOrder(ByValuePreferenceComparator.getInstance()));
- for (int i = 0; i < prefs.length && relevantItemIDs.size() < at; i++) {
- Preference pref = prefs[i];
- if (pref.getValue() >= theRelevanceThreshold) {
- relevantItemIDs.add(pref.getItemID());
+ prefs.sortByValueReversed();
+ for (int i = 0; i < size && relevantItemIDs.size() < at; i++) {
+ if (prefs.getValue(i) >= theRelevanceThreshold) {
+ relevantItemIDs.add(prefs.getItemID(i));
}
}
int numRelevantItems = relevantItemIDs.size();
if (numRelevantItems > 0) {
- List<User> trainingUsers = new ArrayList<User>(dataModel.getNumUsers());
- for (User user2 : dataModel.getUsers()) {
- processOtherUser(id, relevantItemIDs, trainingUsers, user2);
+ Map<Comparable<?>, Collection<Preference>> trainingUsers =
+ new FastMap<Comparable<?>, Collection<Preference>>(dataModel.getNumUsers());
+ for (Comparable userID2 : dataModel.getUserIDs()) {
+ processOtherUser(userID, relevantItemIDs, trainingUsers, userID2, dataModel);
}
- DataModel trainingModel;
- if (trainingUsers.get(0) instanceof BooleanPrefUser) {
- trainingModel = new GenericBooleanUserDataModel(trainingUsers);
- } else {
- trainingModel = new GenericDataModel(trainingUsers);
- }
+ DataModel trainingModel = new GenericDataModel(GenericDataModel.toPrefArrayValues(trainingUsers, true));
Recommender recommender = recommenderBuilder.buildRecommender(trainingModel);
try {
- trainingModel.getUser(id);
+ trainingModel.getPreferencesFromUser(userID);
} catch (NoSuchUserException nsee) {
continue; // Oops we excluded all prefs for the user -- just move on
}
int intersectionSize = 0;
- List<RecommendedItem> recommendedItems = recommender.recommend(id, at, rescorer);
+ List<RecommendedItem> recommendedItems = recommender.recommend(userID, at, rescorer);
for (RecommendedItem recommendedItem : recommendedItems) {
if (relevantItemIDs.contains(recommendedItem.getItemID())) {
intersectionSize++;
@@ -153,13 +145,13 @@
precision.addDatum((double) intersectionSize / (double) numRecommendedItems);
}
recall.addDatum((double) intersectionSize / (double) numRelevantItems);
- if (numRelevantItems < prefs.length) {
+ if (numRelevantItems < size) {
fallOut.addDatum((double) (numRecommendedItems - intersectionSize) /
(double) (numItems - numRelevantItems));
}
long end = System.currentTimeMillis();
- log.info("Evaluated with user " + user + " in " + (end - start) + "ms");
+ log.info("Evaluated with user " + userID + " in " + (end - start) + "ms");
log.info("Precision/recall/fall-out: {} / {} / {}", new Object[]{
precision.getAverage(), recall.getAverage(), fallOut.getAverage()
});
@@ -172,43 +164,34 @@
private static void processOtherUser(Comparable<?> id,
Collection<Comparable<?>> relevantItemIDs,
- Collection<User> trainingUsers,
- User user2) {
- if (id.equals(user2.getID())) {
- List<Preference> trainingPrefs = new ArrayList<Preference>();
- Preference[] prefs2 = user2.getPreferencesAsArray();
- for (Preference pref : prefs2) {
- if (!relevantItemIDs.contains(pref.getItemID())) {
- trainingPrefs.add(pref);
- }
- }
- if (!trainingPrefs.isEmpty()) {
- // TODO hack
- User trainingUser;
- if (user2 instanceof BooleanPrefUser) {
- FastSet<Comparable<?>> itemIDs = new FastSet<Comparable<?>>();
- for (Preference pref : trainingPrefs) {
- itemIDs.add(pref.getItemID());
- }
- trainingUser = new BooleanPrefUser(id, itemIDs);
- } else {
- trainingUser = new GenericUser(id, trainingPrefs);
+ Map<Comparable<?>, Collection<Preference>> trainingUsers,
+ Comparable<?> userID2,
+ DataModel dataModel) throws TasteException {
+ PreferenceArray prefs2Array = dataModel.getPreferencesFromUser(userID2);
+ List<Preference> prefs2 = new ArrayList<Preference>(prefs2Array.length());
+ for (Preference pref : prefs2Array) {
+ prefs2.add(pref);
+ }
+ if (id.equals(userID2)) {
+ for (Iterator<Preference> iterator = prefs2.iterator(); iterator.hasNext();) {
+ Preference pref = iterator.next();
+ if (relevantItemIDs.contains(pref.getItemID())) {
+ iterator.remove();
}
- trainingUsers.add(trainingUser);
}
- } else {
- trainingUsers.add(user2);
}
+ trainingUsers.put(userID2, prefs2);
}
- private static double computeThreshold(Preference[] prefs) {
- if (prefs.length < 2) {
+ private static double computeThreshold(PreferenceArray prefs) {
+ if (prefs.length() < 2) {
// Not enough data points -- return a threshold that allows everything
return Double.NEGATIVE_INFINITY;
}
RunningAverageAndStdDev stdDev = new FullRunningAverageAndStdDev();
- for (Preference pref : prefs) {
- stdDev.addDatum(pref.getValue());
+ int size = prefs.length();
+ for (int i = 0; i < size; i++) {
+ stdDev.addDatum(prefs.getValue(i));
}
return stdDev.getAverage() + stdDev.getStandardDeviation();
}
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluator.java Tue Aug 4 00:06:46 2009
@@ -22,7 +22,6 @@
import org.apache.mahout.cf.taste.impl.common.RunningAverageAndStdDev;
import org.apache.mahout.cf.taste.impl.common.SamplingIterable;
import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,12 +35,13 @@
DataModel dataModel = recommender.getDataModel();
int numUsers = dataModel.getNumUsers();
double sampleRate = 1000.0 / numUsers;
- SamplingIterable<User> userSampler = new SamplingIterable<User>(dataModel.getUsers(), sampleRate);
+ SamplingIterable<Comparable<?>> userSampler =
+ new SamplingIterable<Comparable<?>>(dataModel.getUserIDs(), sampleRate);
RunningAverageAndStdDev recommendationTime = new FullRunningAverageAndStdDev();
int count = 0;
- for (User user : userSampler) {
+ for (Comparable<?> userID : userSampler) {
long start = System.currentTimeMillis();
- recommender.recommend(user.getID(), 10);
+ recommender.recommend(userID, 10);
long end = System.currentTimeMillis();
if (count > 0) { // Ignore first as a warmup
recommendationTime.addDatum(end - start);
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/RMSRecommenderEvaluator.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/RMSRecommenderEvaluator.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/RMSRecommenderEvaluator.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/eval/RMSRecommenderEvaluator.java Tue Aug 4 00:06:46 2009
@@ -22,7 +22,6 @@
import org.apache.mahout.cf.taste.impl.common.FullRunningAverage;
import org.apache.mahout.cf.taste.impl.common.RunningAverage;
import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,24 +39,24 @@
private static final Logger log = LoggerFactory.getLogger(RMSRecommenderEvaluator.class);
@Override
- double getEvaluation(Map<User, Collection<Preference>> testUserPrefs,
+ double getEvaluation(Map<Comparable<?>, Collection<Preference>> testUserPrefs,
Recommender recommender)
throws TasteException {
RunningAverage average = new FullRunningAverage();
- for (Map.Entry<User, Collection<Preference>> entry : testUserPrefs.entrySet()) {
+ for (Map.Entry<Comparable<?>, Collection<Preference>> entry : testUserPrefs.entrySet()) {
for (Preference realPref : entry.getValue()) {
- User testUser = entry.getKey();
+ Comparable<?> testUserID = entry.getKey();
try {
- double estimatedPreference =
- recommender.estimatePreference(testUser.getID(), realPref.getItemID());
- if (!Double.isNaN(estimatedPreference)) {
+ float estimatedPreference =
+ recommender.estimatePreference(testUserID, realPref.getItemID());
+ if (!Float.isNaN(estimatedPreference)) {
double diff = realPref.getValue() - estimatedPreference;
average.addDatum(diff * diff);
}
} catch (NoSuchUserException nsee) {
// It's possible that an item exists in the test data but not training data in which case
// NSEE will be thrown. Just ignore it and move on.
- log.info("Element exists in test data but not training data: {}", testUser.getID(), nsee);
+ log.info("Element exists in test data but not training data: {}", testUserID, nsee);
}
}
}
Copied: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArray.java (from r797487, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArray.java?p2=lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArray.java&p1=lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java&r1=797487&r2=800634&rev=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericPreferenceArray.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArray.java Tue Aug 4 00:06:46 2009
@@ -19,70 +19,177 @@
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.cf.taste.model.PreferenceArray;
-import org.apache.mahout.cf.taste.model.User;
import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
/**
- * This implementation maintains three parallel arrays, of {@link User}s, items, and values. The idea is to save
- * allocating {@link Preference} objects themselves. On a 64-bit virtual machine, this should save 12 bytes per element
- * (the overhead of an enclosing {@link Preference} object reference and object header).
+ * <p>Like {@link BooleanUserPreferenceArray} but stores preferences for one item (all item IDs the same)
+ * rather than one user.</p>
*
- * This is not used yet.
+ * @see BooleanPreference
+ * @see BooleanUserPreferenceArray
+ * @see GenericItemPreferenceArray
*/
-public final class GenericPreferenceArray implements PreferenceArray, Serializable {
+public final class BooleanItemPreferenceArray implements PreferenceArray, Serializable {
- private final User[] users;
- private final Comparable<?>[] itemIDs;
- private final double[] values;
-
- public GenericPreferenceArray(int size) {
- users = new User[size];
- itemIDs = new Comparable<?>[size];
- values = new double[size];
+ private final Comparable<?>[] IDs;
+ private Comparable<?> id;
+
+ public BooleanItemPreferenceArray(int size) {
+ if (size < 1) {
+ throw new IllegalArgumentException("size is less than 1");
+ }
+ this.IDs = new Comparable<?>[size];
+ }
+
+ public int length() {
+ return IDs.length;
+ }
+
+ public BooleanItemPreferenceArray(List<Preference> prefs, boolean forOneUser) {
+ this(prefs.size());
+ for (int i = 0; i < prefs.size(); i++) {
+ Preference pref = prefs.get(i);
+ IDs[i] = forOneUser ? pref.getItemID() : pref.getUserID();
+ }
+ id = forOneUser ? prefs.get(0).getUserID() : prefs.get(0).getItemID();
}
@Override
public Preference get(int i) {
- return new GenericPreference(users[i], itemIDs[i], values[i]);
+ return new PreferenceView(i);
}
@Override
public void set(int i, Preference pref) {
- users[i] = pref.getUser();
- itemIDs[i] = pref.getItemID();
- values[i] = pref.getValue();
+ id = pref.getItemID();
+ IDs[i] = pref.getUserID();
}
@Override
- public User getUser(int i) {
- return users[i];
+ public Comparable<?> getUserID(int i) {
+ return IDs[i];
}
@Override
- public void setUser(int i, User user) {
- users[i] = user;
+ public void setUserID(int i, Comparable<?> userID) {
+ IDs[i] = userID;
}
@Override
public Comparable<?> getItemID(int i) {
- return itemIDs[i];
+ return id;
}
@Override
public void setItemID(int i, Comparable<?> itemID) {
- itemIDs[i] = itemID;
+ id = itemID;
+ }
+
+ @Override
+ public float getValue(int i) {
+ return 1.0f;
+ }
+
+ @Override
+ public void setValue(int i, float value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void sortByUser() {
+ selectionSort();
+ }
+
+ @Override
+ public void sortByItem() {
}
+ @Override
+ public void sortByValue() {
+ }
@Override
- public double getValue(int i) {
- return values[i];
+ public void sortByValueReversed() {
+ }
+
+ private void selectionSort() {
+ // I think this sort will prove to be too dumb, but, it's in place and OK for tiny, mostly sorted data
+ int max = length();
+ for (int i = 0; i < max; i++) {
+ int min = i;
+ for (int j = i + 1; j < max; j++) {
+ if (((Comparable<Object>) IDs[i]).compareTo(IDs[j]) < 0) {
+ min = j;
+ }
+ }
+ if (i != min) {
+ Comparable<?> temp1 = IDs[i];
+ IDs[i] = IDs[min];
+ IDs[min] = temp1;
+ }
+ }
+ }
+
+ public GenericItemPreferenceArray clone() {
+ try {
+ return (GenericItemPreferenceArray) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new AssertionError();
+ }
}
@Override
- public void setValue(int i, double value) {
- values[i] = value;
+ public Iterator<Preference> iterator() {
+ return new PreferenceArrayIterator();
+ }
+
+ private final class PreferenceArrayIterator implements Iterator<Preference> {
+ private int i = 0;
+ @Override
+ public boolean hasNext() {
+ return i < length();
+ }
+ @Override
+ public Preference next() {
+ return new PreferenceView(i++);
+ }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final class PreferenceView implements Preference {
+
+ private final int i;
+
+ private PreferenceView(int i) {
+ this.i = i;
+ }
+
+ @Override
+ public Comparable<?> getUserID() {
+ return BooleanItemPreferenceArray.this.getUserID(i);
+ }
+
+ @Override
+ public Comparable<?> getItemID() {
+ return BooleanItemPreferenceArray.this.getItemID(i);
+ }
+
+ @Override
+ public float getValue() {
+ return 1.0f;
+ }
+
+ @Override
+ public void setValue(float value) {
+ throw new UnsupportedOperationException();
+ }
+
}
-}
+}
\ No newline at end of file
Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPreference.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPreference.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPreference.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanPreference.java Tue Aug 4 00:06:46 2009
@@ -17,7 +17,7 @@
package org.apache.mahout.cf.taste.impl.model;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.Preference;
import java.io.Serializable;
@@ -26,33 +26,22 @@
* appropriate in situations where users conceptually have only a general "yes" preference for items, rather than a
* spectrum of preference values.
*/
-public final class BooleanPreference implements SettableUserPreference, Serializable {
+public final class BooleanPreference implements Preference, Serializable {
- private User user;
+ private final Comparable<?> userID;
private final Comparable<?> itemID;
- public BooleanPreference(User user, Comparable<?> itemID) {
- if (itemID == null) {
+ public BooleanPreference(Comparable<?> userID, Comparable<?> itemID) {
+ if (userID == null || itemID == null) {
throw new IllegalArgumentException("itemID is null");
}
- this.user = user;
+ this.userID = userID;
this.itemID = itemID;
}
@Override
- public User getUser() {
- if (user == null) {
- throw new IllegalStateException("User was never set");
- }
- return user;
- }
-
- @Override
- public void setUser(User user) {
- if (user == null) {
- throw new IllegalArgumentException("user is null");
- }
- this.user = user;
+ public Comparable<?> getUserID() {
+ return userID;
}
@Override
@@ -61,18 +50,18 @@
}
@Override
- public double getValue() {
- return 1.0;
+ public float getValue() {
+ return 1.0f;
}
@Override
- public void setValue(double value) {
+ public void setValue(float value) {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
- return "BooleanPreference[user: " + user + ", itemID:" + itemID + ']';
+ return "BooleanPreference[userID: " + userID + ", itemID:" + itemID + ']';
}
}
\ No newline at end of file
Added: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArray.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArray.java?rev=800634&view=auto
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArray.java (added)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArray.java Tue Aug 4 00:06:46 2009
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * <p>Like {@link GenericUserPreferenceArray} but stores, conceptually, {@link BooleanPreference} objects
+ * which have no associated preference value.</p>
+ *
+ * @see BooleanPreference
+ * @see BooleanItemPreferenceArray
+ * @see GenericUserPreferenceArray
+ */
+public final class BooleanUserPreferenceArray implements PreferenceArray, Serializable {
+
+ private final Comparable<?>[] IDs;
+ private Comparable<?> id;
+
+ public BooleanUserPreferenceArray(int size) {
+ if (size < 1) {
+ throw new IllegalArgumentException("size is less than 1");
+ }
+ this.IDs = new Comparable<?>[size];
+ }
+
+ public int length() {
+ return IDs.length;
+ }
+
+ public BooleanUserPreferenceArray(List<Preference> prefs) {
+ this(prefs.size());
+ for (int i = 0; i < prefs.size(); i++) {
+ Preference pref = prefs.get(i);
+ IDs[i] = pref.getItemID();
+ }
+ id = prefs.get(0).getUserID();
+ }
+
+ @Override
+ public Preference get(int i) {
+ return new PreferenceView(i);
+ }
+
+ @Override
+ public void set(int i, Preference pref) {
+ id = pref.getUserID();
+ IDs[i] = pref.getItemID();
+ }
+
+ @Override
+ public Comparable<?> getUserID(int i) {
+ return id;
+ }
+
+ @Override
+ public void setUserID(int i, Comparable<?> userID) {
+ id = userID;
+ }
+
+ @Override
+ public Comparable<?> getItemID(int i) {
+ return IDs[i];
+ }
+
+ @Override
+ public void setItemID(int i, Comparable<?> itemID) {
+ IDs[i] = itemID;
+ }
+
+ @Override
+ public float getValue(int i) {
+ return 1.0f;
+ }
+
+ @Override
+ public void setValue(int i, float value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void sortByUser() {
+ }
+
+ @Override
+ public void sortByItem() {
+ selectionSort();
+ }
+
+ @Override
+ public void sortByValue() {
+ }
+
+ @Override
+ public void sortByValueReversed() {
+ }
+
+ private void selectionSort() {
+ // I think this sort will prove to be too dumb, but, it's in place and OK for tiny, mostly sorted data
+ int max = length();
+ for (int i = 0; i < max; i++) {
+ int min = i;
+ for (int j = i + 1; j < max; j++) {
+ if (((Comparable<Object>) IDs[i]).compareTo(IDs[j]) < 0) {
+ min = j;
+ }
+ }
+ if (i != min) {
+ Comparable<?> temp1 = IDs[i];
+ IDs[i] = IDs[min];
+ IDs[min] = temp1;
+ }
+ }
+ }
+
+ public GenericItemPreferenceArray clone() {
+ try {
+ return (GenericItemPreferenceArray) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public Iterator<Preference> iterator() {
+ return new PreferenceArrayIterator();
+ }
+
+ private final class PreferenceArrayIterator implements Iterator<Preference> {
+ private int i = 0;
+ @Override
+ public boolean hasNext() {
+ return i < length();
+ }
+ @Override
+ public Preference next() {
+ return new PreferenceView(i++);
+ }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final class PreferenceView implements Preference {
+
+ private final int i;
+
+ private PreferenceView(int i) {
+ this.i = i;
+ }
+
+ @Override
+ public Comparable<?> getUserID() {
+ return BooleanUserPreferenceArray.this.getUserID(i);
+ }
+
+ @Override
+ public Comparable<?> getItemID() {
+ return BooleanUserPreferenceArray.this.getItemID(i);
+ }
+
+ @Override
+ public float getValue() {
+ return 1.0f;
+ }
+
+ @Override
+ public void setValue(float value) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
\ No newline at end of file
Copied: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanPrefDataModel.java (from r797487, lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanUserDataModel.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanPrefDataModel.java?p2=lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanPrefDataModel.java&p1=lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanUserDataModel.java&r1=797487&r2=800634&rev=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanUserDataModel.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericBooleanPrefDataModel.java Tue Aug 4 00:06:46 2009
@@ -24,112 +24,188 @@
import org.apache.mahout.cf.taste.impl.common.FastMap;
import org.apache.mahout.cf.taste.impl.common.FastSet;
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.io.Serializable;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
/**
- * TODO many methods here have not been implemented properly yet
+ * <p>A simple {@link DataModel} which uses a given {@link List} of users as its data source. This
+ * implementation is mostly useful for small experiments and is not recommended for contexts where performance is
+ * important.</p>
*/
-public final class GenericBooleanUserDataModel implements DataModel, Serializable {
+public final class GenericBooleanPrefDataModel implements DataModel, Serializable {
- private final List<User> users;
- private final FastMap<Comparable<?>, User> userMap;
- private final Object[] itemIDs;
-
- public GenericBooleanUserDataModel(Iterable<? extends User> users) {
- if (users == null) {
- throw new IllegalArgumentException("users is null");
- }
- this.users = new ArrayList<User>(1003);
- this.userMap = new FastMap<Comparable<?>, User>(1003);
- Set<Comparable<?>> itemIDs = new FastSet<Comparable<?>>(1003);
- for (User user : users) {
- if (!(user instanceof BooleanPrefUser)) {
- throw new IllegalArgumentException("Must use a source of BooleanPrefUsers");
+ private final List<Comparable<?>> userIDs;
+ private final Map<Comparable<?>, FastSet<Comparable<?>>> preferenceFromUsers;
+ private final List<Comparable<?>> itemIDs;
+ private final Map<Comparable<?>, FastSet<Comparable<?>>> preferenceForItems;
+
+ /**
+ * <p>Creates a new {@link GenericDataModel} from the given users (and their preferences). This {@link
+ * DataModel} retains all this information in memory and is effectively immutable.</p>
+ *
+ * @param userData users to include
+ */
+ @SuppressWarnings("unchecked")
+ public GenericBooleanPrefDataModel(Map<Comparable<?>, FastSet<Comparable<?>>> userData) {
+ if (userData == null) {
+ throw new IllegalArgumentException("userData is null");
+ }
+
+ this.preferenceFromUsers = userData;
+ this.preferenceForItems = new FastMap<Comparable<?>, FastSet<Comparable<?>>>();
+ FastSet<Comparable<?>> itemIDSet = new FastSet<Comparable<?>>();
+ for (Map.Entry<Comparable<?>, FastSet<Comparable<?>>> entry : preferenceFromUsers.entrySet()) {
+ Comparable<?> userID = entry.getKey();
+ FastSet<Comparable<?>> itemIDs = entry.getValue();
+ itemIDSet.addAll(itemIDs);
+ for (Comparable<?> itemID : itemIDs) {
+ FastSet<Comparable<?>> userIDs = preferenceForItems.get(itemID);
+ if (userIDs == null) {
+ userIDs = new FastSet<Comparable<?>>(2);
+ preferenceForItems.put(itemID, userIDs);
+ }
+ userIDs.add(userID);
}
- this.users.add(user);
- userMap.put(user.getID(), user);
- itemIDs.addAll(((BooleanPrefUser) user).getItemIDs());
}
- userMap.rehash();
- Collections.sort(this.users);
- this.itemIDs = itemIDs.toArray();
- itemIDs = null;
- Arrays.sort(this.itemIDs);
+ this.itemIDs = new ArrayList<Comparable<?>>(itemIDSet);
+ itemIDSet = null;
+ Collections.sort((List<? extends Comparable>) this.itemIDs);
+
+ this.userIDs = new ArrayList(userData.keySet());
+ Collections.sort((List<? extends Comparable>) userIDs);
+
}
- public GenericBooleanUserDataModel(DataModel dataModel) throws TasteException {
- this(dataModel.getUsers());
+ /**
+ * <p>Creates a new {@link GenericDataModel} containing an immutable copy of the data from another given {@link
+ * DataModel}.</p>
+ *
+ * @param dataModel {@link DataModel} to copy
+ * @throws TasteException if an error occurs while retrieving the other {@link DataModel}'s users
+ */
+ public GenericBooleanPrefDataModel(DataModel dataModel) throws TasteException {
+ this(toDataMap(dataModel));
+ }
+
+ private static Map<Comparable<?>, FastSet<Comparable<?>>> toDataMap(DataModel dataModel) throws TasteException {
+ Map<Comparable<?>, FastSet<Comparable<?>>> data =
+ new FastMap<Comparable<?>, FastSet<Comparable<?>>>(dataModel.getNumUsers());
+ for (Comparable<?> userID : dataModel.getUserIDs()) {
+ data.put(userID, dataModel.getItemIDsFromUser(userID));
+ }
+ return data;
+ }
+
+ @Override
+ public Iterable<Comparable<?>> getUserIDs() {
+ return userIDs;
}
+ /** @throws NoSuchUserException if there is no such user */
@Override
- public Iterable<? extends User> getUsers() {
- return users;
+ public PreferenceArray getPreferencesFromUser(Comparable<?> userID) throws NoSuchUserException {
+ FastSet<Comparable<?>> itemIDs = preferenceFromUsers.get(userID);
+ if (itemIDs == null) {
+ throw new NoSuchUserException();
+ }
+ PreferenceArray prefArray = new BooleanUserPreferenceArray(itemIDs.size());
+ int i = 0;
+ for (Comparable<?> itemID : itemIDs) {
+ prefArray.setUserID(i, userID);
+ prefArray.setItemID(i, itemID);
+ i++;
+ }
+ return prefArray;
}
@Override
- public User getUser(Comparable<?> id) throws NoSuchUserException {
- User user = userMap.get(id);
- if (user == null) {
+ public FastSet<Comparable<?>> getItemIDsFromUser(Comparable<?> userID) throws TasteException {
+ FastSet<Comparable<?>> itemIDs = preferenceFromUsers.get(userID);
+ if (itemIDs == null) {
throw new NoSuchUserException();
}
- return user;
+ return itemIDs;
}
@Override
public Iterable<Comparable<?>> getItemIDs() {
- throw new UnsupportedOperationException();
+ return itemIDs;
}
@Override
- public Iterable<? extends Preference> getPreferencesForItem(Comparable<?> itemID) {
- throw new UnsupportedOperationException();
+ public PreferenceArray getPreferencesForItem(Comparable<?> itemID) throws NoSuchItemException {
+ FastSet<Comparable<?>> userIDs = preferenceForItems.get(itemID);
+ if (userIDs == null) {
+ throw new NoSuchItemException();
+ }
+ PreferenceArray prefArray = new BooleanItemPreferenceArray(userIDs.size());
+ int i = 0;
+ for (Comparable<?> userID : userIDs) {
+ prefArray.setUserID(i, userID);
+ prefArray.setItemID(i, itemID);
+ i++;
+ }
+ return prefArray;
}
@Override
- public Preference[] getPreferencesForItemAsArray(Comparable<?> itemID) {
- throw new UnsupportedOperationException();
+ public Float getPreferenceValue(Comparable<?> userID, Comparable<?> itemID) throws NoSuchUserException, NoSuchItemException {
+ FastSet<Comparable<?>> itemIDs = preferenceFromUsers.get(userID);
+ if (itemIDs == null) {
+ throw new NoSuchUserException();
+ }
+ if (itemIDs.contains(itemID)) {
+ return 1.0f;
+ }
+ return null;
}
@Override
public int getNumItems() {
- return itemIDs.length;
+ return itemIDs.size();
}
@Override
public int getNumUsers() {
- return users.size();
+ return userIDs.size();
}
@Override
- public int getNumUsersWithPreferenceFor(Comparable<?>... itemIDs) {
- if (itemIDs == null) {
- throw new IllegalArgumentException("itemIDs is null");
+ public int getNumUsersWithPreferenceFor(Comparable<?>... itemIDs) throws NoSuchItemException {
+ if (itemIDs.length == 0) {
+ return 0;
}
- int length = itemIDs.length;
- if (length == 0 || length > 2) {
- throw new IllegalArgumentException("Illegal number of item IDs: " + length);
+ FastSet<Comparable<?>> intersection = new FastSet<Comparable<?>>();
+ FastSet<Comparable<?>> userIDs = preferenceForItems.get(itemIDs[0]);
+ if (userIDs == null) {
+ throw new NoSuchItemException();
}
- throw new UnsupportedOperationException();
+ intersection.addAll(userIDs);
+ int i = 1;
+ while (!intersection.isEmpty() && i < itemIDs.length) {
+ userIDs = preferenceForItems.get(itemIDs[i]);
+ if (userIDs == null) {
+ throw new NoSuchItemException();
+ }
+ intersection.retainAll(userIDs);
+ }
+ return intersection.size();
}
@Override
- public void setPreference(Comparable<?> userID, Comparable<?> itemID, double value)
- throws NoSuchUserException, NoSuchItemException {
+ public void removePreference(Comparable<?> userID, Comparable<?> itemID) throws NoSuchUserException {
throw new UnsupportedOperationException();
}
@Override
- public void removePreference(Comparable<?> userID, Comparable<?> itemID) throws NoSuchUserException {
+ public void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) throws NoSuchUserException {
throw new UnsupportedOperationException();
}
@@ -140,7 +216,7 @@
@Override
public String toString() {
- return "GenericBooleanUserDataModel[users:" + (users.size() > 3 ? users.subList(0, 3) + "..." : users) + ']';
+ return "GenericBooleanPrefDataModel[users:" + (userIDs.size() > 3 ? userIDs.subList(0, 3) + "..." : userIDs) + ']';
}
-}
\ No newline at end of file
+}