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 2010/07/31 16:15:11 UTC
svn commit: r981062 - in /mahout/trunk/core/src:
main/java/org/apache/mahout/cf/taste/impl/model/
main/java/org/apache/mahout/cf/taste/impl/recommender/
main/java/org/apache/mahout/cf/taste/impl/recommender/knn/
main/java/org/apache/mahout/cf/taste/imp...
Author: srowen
Date: Sat Jul 31 14:15:10 2010
New Revision: 981062
URL: http://svn.apache.org/viewvc?rev=981062&view=rev
Log:
MAHOUT-445
Added:
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategy.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategy.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategy.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/CandidateItemsStrategy.java
mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategyTest.java
mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategyTest.java
Modified:
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java
Modified: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java?rev=981062&r1=981061&r2=981062&view=diff
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java (original)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArray.java Sat Jul 31 14:15:10 2010
@@ -73,7 +73,7 @@ public final class GenericUserPreference
this.id = id;
this.values = values;
}
-
+
@Override
public int length() {
return ids.length;
Modified: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java?rev=981062&r1=981061&r2=981062&view=diff
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java (original)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AbstractRecommender.java Sat Jul 31 14:15:10 2010
@@ -17,13 +17,12 @@
package org.apache.mahout.cf.taste.impl.recommender;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
import java.util.List;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.FastIDSet;
-import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.model.DataModel;
-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.slf4j.Logger;
@@ -34,14 +33,24 @@ public abstract class AbstractRecommende
private static final Logger log = LoggerFactory.getLogger(AbstractRecommender.class);
private final DataModel dataModel;
+ private final CandidateItemsStrategy candidateItemsStrategy;
- protected AbstractRecommender(DataModel dataModel) {
+ protected AbstractRecommender(DataModel dataModel, CandidateItemsStrategy candidateItemsStrategy) {
if (dataModel == null) {
throw new IllegalArgumentException("dataModel is null");
}
this.dataModel = dataModel;
+ this.candidateItemsStrategy = candidateItemsStrategy;
}
-
+
+ protected AbstractRecommender(DataModel dataModel) {
+ this(dataModel, getDefaultCandidateItemsStrategy());
+ }
+
+ protected static CandidateItemsStrategy getDefaultCandidateItemsStrategy() {
+ return new PreferredItemsNeighborhoodCandidateItemsStrategy();
+ }
+
/**
* <p>
* Default implementation which just calls
@@ -99,19 +108,7 @@ public abstract class AbstractRecommende
* if an error occurs while listing items
*/
protected FastIDSet getAllOtherItems(long theUserID) throws TasteException {
- FastIDSet possibleItemsIDs = new FastIDSet();
- FastIDSet itemIDs = dataModel.getItemIDsFromUser(theUserID);
- LongPrimitiveIterator itemIDIterator = itemIDs.iterator();
- while (itemIDIterator.hasNext()) {
- long itemID = itemIDIterator.next();
- PreferenceArray prefs2 = dataModel.getPreferencesForItem(itemID);
- int size2 = prefs2.length();
- for (int j = 0; j < size2; j++) {
- possibleItemsIDs.addAll(dataModel.getItemIDsFromUser(prefs2.getUserID(j)));
- }
- }
- possibleItemsIDs.removeAll(itemIDs);
- return possibleItemsIDs;
+ return candidateItemsStrategy.getCandidateItems(theUserID, dataModel);
}
}
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategy.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategy.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategy.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategy.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,42 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.model.DataModel;
+
+/**
+ * returns all items the user has not rated yet
+ */
+public final class AllUnknownItemsCandidateItemsStrategy implements CandidateItemsStrategy {
+
+ @Override
+ public FastIDSet getCandidateItems(long userID, DataModel dataModel) throws TasteException {
+ FastIDSet possibleItemIDs = new FastIDSet(dataModel.getNumItems());
+ LongPrimitiveIterator allItemIDs = dataModel.getItemIDs();
+ while (allItemIDs.hasNext()) {
+ possibleItemIDs.add(allItemIDs.nextLong());
+ }
+ possibleItemIDs.removeAll(dataModel.getItemIDsFromUser(userID));
+ return possibleItemIDs;
+ }
+
+}
Modified: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java?rev=981062&r1=981061&r2=981062&view=diff
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java (original)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommender.java Sat Jul 31 14:15:10 2010
@@ -17,6 +17,7 @@
package org.apache.mahout.cf.taste.impl.recommender;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -69,8 +70,10 @@ public class GenericItemBasedRecommender
private final RefreshHelper refreshHelper;
private EstimatedPreferenceCapper capper;
- public GenericItemBasedRecommender(DataModel dataModel, ItemSimilarity similarity) {
- super(dataModel);
+ public GenericItemBasedRecommender(DataModel dataModel,
+ ItemSimilarity similarity,
+ CandidateItemsStrategy candidateItemsStrategy) {
+ super(dataModel, candidateItemsStrategy);
if (similarity == null) {
throw new IllegalArgumentException("similarity is null");
}
@@ -80,7 +83,12 @@ public class GenericItemBasedRecommender
refreshHelper.addDependency(similarity);
capper = buildCapper();
}
-
+
+ public GenericItemBasedRecommender(DataModel dataModel,
+ ItemSimilarity similarity) {
+ this(dataModel, similarity, AbstractRecommender.getDefaultCandidateItemsStrategy());
+ }
+
public ItemSimilarity getSimilarity() {
return similarity;
}
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategy.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategy.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategy.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategy.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,50 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+
+/**
+ * returns all items that have not been rated by the user and that were preferred by another user
+ * that has preferred at least one item that the current user has preferred too
+ */
+public final class PreferredItemsNeighborhoodCandidateItemsStrategy implements CandidateItemsStrategy {
+
+ @Override
+ public FastIDSet getCandidateItems(long userID, DataModel dataModel) throws TasteException {
+ FastIDSet possibleItemsIDs = new FastIDSet();
+ FastIDSet itemIDs = dataModel.getItemIDsFromUser(userID);
+ LongPrimitiveIterator itemIDIterator = itemIDs.iterator();
+ while (itemIDIterator.hasNext()) {
+ long itemID = itemIDIterator.next();
+ PreferenceArray prefs2 = dataModel.getPreferencesForItem(itemID);
+ int size2 = prefs2.length();
+ for (int j = 0; j < size2; j++) {
+ possibleItemsIDs.addAll(dataModel.getItemIDsFromUser(prefs2.getUserID(j)));
+ }
+ }
+ possibleItemsIDs.removeAll(itemIDs);
+ return possibleItemsIDs;
+ }
+
+}
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategy.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategy.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategy.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategy.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,89 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.apache.mahout.common.iterator.FixedSizeSamplingIterator;
+
+import java.util.Iterator;
+
+/**
+ * <p>returns all items that have not been rated by the user and that were preferred by another user
+ * that has preferred at least one item that the current user has preferred too</p>
+ *
+ * <p>this strategy uses sampling in a way that only a certain amount of preferences per item is considered
+ * <pre>
+ * max(defaultMaxPrefsPerItemConsidered, userItemCountFactor * log(max(N_users, N_items)))
+ * </pre></p>
+ */
+public class SamplingCandidateItemsStrategy implements CandidateItemsStrategy {
+
+ private final int defaultMaxPrefsPerItemConsidered;
+ private final int userItemCountMultiplier;
+
+ /**
+ * uses defaultMaxPrefsPerItemConsidered = 100 and userItemCountMultiplier = 20 as default values
+ *
+ * @see SamplingCandidateItemsStrategy#SamplingCandidateItemsStrategy(int, int)
+ */
+ public SamplingCandidateItemsStrategy() {
+ this(100, 20);
+ }
+
+ /**
+ * <p>the maximum number of prefs considered per item will be computed like this:
+ * <pre>
+ * max(defaultMaxPrefsPerItemConsidered, userItemCountFactor * log(max(N_users, N_items)))
+ * </pre>
+ * </p>
+ *
+ * @param defaultMaxPrefsPerItemConsidered
+ * @param userItemCountMultiplier
+ */
+ public SamplingCandidateItemsStrategy(int defaultMaxPrefsPerItemConsidered, int userItemCountMultiplier) {
+ this.defaultMaxPrefsPerItemConsidered = defaultMaxPrefsPerItemConsidered;
+ this.userItemCountMultiplier = userItemCountMultiplier;
+ }
+
+ @Override
+ public FastIDSet getCandidateItems(long userID, DataModel dataModel) throws TasteException {
+ int maxPrefsPerItemConsidered = (int) Math.max(defaultMaxPrefsPerItemConsidered,
+ userItemCountMultiplier * Math.log(Math.max(dataModel.getNumUsers(), dataModel.getNumItems())));
+ FastIDSet possibleItemsIDs = new FastIDSet();
+ FastIDSet itemIDs = dataModel.getItemIDsFromUser(userID);
+ LongPrimitiveIterator itemIDIterator = itemIDs.iterator();
+ while (itemIDIterator.hasNext()) {
+ long itemID = itemIDIterator.next();
+ PreferenceArray prefs = dataModel.getPreferencesForItem(itemID);
+ int prefsConsidered = Math.min(prefs.length(), maxPrefsPerItemConsidered);
+ Iterator<Preference> sampledPrefs = new FixedSizeSamplingIterator(prefsConsidered, prefs.iterator());
+ while (sampledPrefs.hasNext()) {
+ possibleItemsIDs.addAll(dataModel.getItemIDsFromUser(sampledPrefs.next().getUserID()));
+ }
+ }
+ possibleItemsIDs.removeAll(itemIDs);
+ return possibleItemsIDs;
+ }
+
+}
Modified: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java?rev=981062&r1=981061&r2=981062&view=diff
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java (original)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/knn/KnnItemBasedRecommender.java Sat Jul 31 14:15:10 2010
@@ -26,6 +26,7 @@ import org.apache.mahout.cf.taste.impl.r
import org.apache.mahout.cf.taste.impl.recommender.TopItems;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Rescorer;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
@@ -45,11 +46,19 @@ public final class KnnItemBasedRecommend
public KnnItemBasedRecommender(DataModel dataModel,
ItemSimilarity similarity,
Optimizer optimizer,
+ CandidateItemsStrategy candidateItemsStrategy,
int neighborhoodSize) {
- super(dataModel, similarity);
+ super(dataModel, similarity, candidateItemsStrategy);
this.optimizer = optimizer;
this.neighborhoodSize = neighborhoodSize;
}
+
+ public KnnItemBasedRecommender(DataModel dataModel,
+ ItemSimilarity similarity,
+ Optimizer optimizer,
+ int neighborhoodSize) {
+ this(dataModel, similarity, optimizer, getDefaultCandidateItemsStrategy(), neighborhoodSize);
+ }
private List<RecommendedItem> mostSimilarItems(long itemID,
LongPrimitiveIterator possibleItemIDs,
Modified: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java?rev=981062&r1=981061&r2=981062&view=diff
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java (original)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd/SVDRecommender.java Sat Jul 31 14:15:10 2010
@@ -38,6 +38,7 @@ import org.apache.mahout.cf.taste.impl.r
import org.apache.mahout.cf.taste.impl.recommender.TopItems;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
import org.apache.mahout.cf.taste.recommender.IDRescorer;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.common.RandomUtils;
@@ -70,8 +71,11 @@ public final class SVDRecommender extend
* @param initialSteps
* number of initial training steps
*/
- public SVDRecommender(DataModel dataModel, int numFeatures, int initialSteps) throws TasteException {
- super(dataModel);
+ public SVDRecommender(DataModel dataModel,
+ CandidateItemsStrategy candidateItemsStrategy,
+ int numFeatures,
+ int initialSteps) throws TasteException {
+ super(dataModel, candidateItemsStrategy);
this.numFeatures = numFeatures;
@@ -112,6 +116,12 @@ public final class SVDRecommender extend
train(initialSteps);
}
+
+ public SVDRecommender(DataModel dataModel,
+ int numFeatures,
+ int initialSteps) throws TasteException {
+ this(dataModel, getDefaultCandidateItemsStrategy(), numFeatures, initialSteps);
+ }
private void recachePreferences() throws TasteException {
cachedPreferences.clear();
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/CandidateItemsStrategy.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/CandidateItemsStrategy.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/CandidateItemsStrategy.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/CandidateItemsStrategy.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,34 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.model.DataModel;
+
+/**
+ * Used to retrieve all items that could possibly be recommended to the user
+ */
+public interface CandidateItemsStrategy {
+
+ /**
+ * #return IDs of all items that could be recommended to the user
+ */
+ FastIDSet getCandidateItems(long userID, DataModel dataModel) throws TasteException;
+
+}
Added: mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java (added)
+++ mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,56 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Tests {@link AllUnknownItemsCandidateItemsStrategyTest}
+ */
+public final class AllUnknownItemsCandidateItemsStrategyTest extends TasteTestCase {
+
+ public void testStrategy() throws TasteException {
+ FastIDSet allItemIDs = new FastIDSet();
+ allItemIDs.addAll(new long[] { 1L, 2L, 3L });
+
+ FastIDSet preferredItemIDs = new FastIDSet(1);
+ preferredItemIDs.add(2L);
+
+ DataModel dataModel = EasyMock.createMock(DataModel.class);
+ EasyMock.expect(dataModel.getNumItems()).andReturn(3);
+ EasyMock.expect(dataModel.getItemIDs()).andReturn(allItemIDs.iterator());
+ EasyMock.expect(dataModel.getItemIDsFromUser(123L)).andReturn(preferredItemIDs);
+
+ CandidateItemsStrategy strategy = new AllUnknownItemsCandidateItemsStrategy();
+
+ EasyMock.replay(dataModel);
+
+ FastIDSet candidateItems = strategy.getCandidateItems(123L, dataModel);
+ assertEquals(2, candidateItems.size());
+ assertTrue(candidateItems.contains(1L));
+ assertTrue(candidateItems.contains(3L));
+
+ EasyMock.verify(dataModel);
+ }
+
+}
Added: mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategyTest.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategyTest.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategyTest.java (added)
+++ mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/PreferredItemsNeighborhoodCandidateItemsStrategyTest.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,68 @@
+/**
+ * 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.recommender;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.model.GenericItemPreferenceArray;
+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.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.easymock.EasyMock;
+
+/**
+ * Tests {@link PreferredItemsNeighborhoodCandidateItemsStrategy}
+ */
+public final class PreferredItemsNeighborhoodCandidateItemsStrategyTest extends TasteTestCase {
+
+ public void testStrategy() throws TasteException {
+ FastIDSet itemIDsFromUser123 = new FastIDSet();
+ itemIDsFromUser123.add(1L);
+
+ FastIDSet itemIDsFromUser456 = new FastIDSet();
+ itemIDsFromUser456.add(1L);
+ itemIDsFromUser456.add(2L);
+
+ List<Preference> prefs = new ArrayList<Preference>();
+ prefs.add(new GenericPreference(123L, 1L, 1.0f));
+ prefs.add(new GenericPreference(456L, 1L, 1.0f));
+ PreferenceArray preferencesForItem1 = new GenericItemPreferenceArray(prefs);
+
+ DataModel dataModel = EasyMock.createMock(DataModel.class);
+ EasyMock.expect(dataModel.getItemIDsFromUser(123L)).andReturn(itemIDsFromUser123);
+ EasyMock.expect(dataModel.getPreferencesForItem(1L)).andReturn(preferencesForItem1);
+ EasyMock.expect(dataModel.getItemIDsFromUser(123L)).andReturn(itemIDsFromUser123);
+ EasyMock.expect(dataModel.getItemIDsFromUser(456L)).andReturn(itemIDsFromUser456);
+
+ CandidateItemsStrategy strategy = new PreferredItemsNeighborhoodCandidateItemsStrategy();
+
+ EasyMock.replay(dataModel);
+
+ FastIDSet candidateItems = strategy.getCandidateItems(123L, dataModel);
+ assertEquals(1, candidateItems.size());
+ assertTrue(candidateItems.contains(2L));
+
+ EasyMock.verify(dataModel);
+ }
+
+}
Added: mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategyTest.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategyTest.java?rev=981062&view=auto
==============================================================================
--- mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategyTest.java (added)
+++ mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/SamplingCandidateItemsStrategyTest.java Sat Jul 31 14:15:10 2010
@@ -0,0 +1,66 @@
+/**
+ * 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.recommender;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+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.GenericUserPreferenceArray;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests {@link SamplingCandidateItemsStrategy}
+ */
+public final class SamplingCandidateItemsStrategyTest extends TasteTestCase {
+
+ public void testStrategy() throws TasteException {
+ List<Preference> prefsOfUser123 = new ArrayList<Preference>();
+ prefsOfUser123.add(new GenericPreference(123L, 1L, 1.0f));
+
+ List<Preference> prefsOfUser456 = new ArrayList<Preference>();
+ prefsOfUser456.add(new GenericPreference(456L, 1L, 1.0f));
+ prefsOfUser456.add(new GenericPreference(456L, 2L, 1.0f));
+
+ List<Preference> prefsOfUser789 = new ArrayList<Preference>();
+ prefsOfUser456.add(new GenericPreference(789L, 1L, 0.5f));
+ prefsOfUser456.add(new GenericPreference(789L, 3L, 1.0f));
+
+ FastByIDMap<PreferenceArray> userData = new FastByIDMap<PreferenceArray>();
+ userData.put(123L, new GenericUserPreferenceArray(prefsOfUser123));
+ userData.put(456L, new GenericUserPreferenceArray(prefsOfUser456));
+ userData.put(789L, new GenericUserPreferenceArray(prefsOfUser789));
+
+ DataModel dataModel = new GenericDataModel(userData);
+
+ CandidateItemsStrategy strategy = new SamplingCandidateItemsStrategy(1, 1);
+
+ FastIDSet candidateItems = strategy.getCandidateItems(123L, dataModel);
+ /* result can be either item2 or item3 or empty */
+ assertTrue(candidateItems.size() <= 1);
+ assertFalse(candidateItems.contains(1L));
+ }
+}