You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by ra...@apache.org on 2018/06/04 14:29:13 UTC
[11/53] [abbrv] [partial] mahout git commit: end of day 6-2-2018
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
new file mode 100644
index 0000000..16c8dff
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
@@ -0,0 +1,107 @@
+/**
+ * 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.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.common.RandomUtils;
+import org.junit.Test;
+
+import java.util.Random;
+
+public final class RunningAverageAndStdDevTest extends TasteTestCase {
+
+ private static final double SMALL_EPSILON = 1.0;
+
+ @Test
+ public void testFull() {
+ RunningAverageAndStdDev average = new FullRunningAverageAndStdDev();
+
+ assertEquals(0, average.getCount());
+ assertTrue(Double.isNaN(average.getAverage()));
+ assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+ average.addDatum(6.0);
+ assertEquals(1, average.getCount());
+ assertEquals(6.0, average.getAverage(), EPSILON);
+ assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+ average.addDatum(6.0);
+ assertEquals(2, average.getCount());
+ assertEquals(6.0, average.getAverage(), EPSILON);
+ assertEquals(0.0, average.getStandardDeviation(), EPSILON);
+
+ average.removeDatum(6.0);
+ assertEquals(1, average.getCount());
+ assertEquals(6.0, average.getAverage(), EPSILON);
+ assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+ average.addDatum(-4.0);
+ assertEquals(2, average.getCount());
+ assertEquals(1.0, average.getAverage(), EPSILON);
+ assertEquals(5.0 * 1.4142135623730951, average.getStandardDeviation(), EPSILON);
+
+ average.removeDatum(4.0);
+ assertEquals(1, average.getCount());
+ assertEquals(-2.0, average.getAverage(), EPSILON);
+ assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+ }
+
+ @Test
+ public void testFullBig() {
+ RunningAverageAndStdDev average = new FullRunningAverageAndStdDev();
+
+ Random r = RandomUtils.getRandom();
+ for (int i = 0; i < 100000; i++) {
+ average.addDatum(r.nextDouble() * 1000.0);
+ }
+ assertEquals(500.0, average.getAverage(), SMALL_EPSILON);
+ assertEquals(1000.0 / Math.sqrt(12.0), average.getStandardDeviation(), SMALL_EPSILON);
+
+ }
+
+ @Test
+ public void testStddev() {
+
+ RunningAverageAndStdDev runningAverage = new FullRunningAverageAndStdDev();
+
+ assertEquals(0, runningAverage.getCount());
+ assertTrue(Double.isNaN(runningAverage.getAverage()));
+ runningAverage.addDatum(1.0);
+ assertEquals(1, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+ runningAverage.addDatum(1.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(0.0, runningAverage.getStandardDeviation(), EPSILON);
+
+ runningAverage.addDatum(7.0);
+ assertEquals(3, runningAverage.getCount());
+ assertEquals(3.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(3.464101552963257, runningAverage.getStandardDeviation(), EPSILON);
+
+ runningAverage.addDatum(5.0);
+ assertEquals(4, runningAverage.getCount());
+ assertEquals(3.5, runningAverage.getAverage(), EPSILON);
+ assertEquals(3.0, runningAverage.getStandardDeviation(), EPSILON);
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
new file mode 100644
index 0000000..6b891c5
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/** <p>Tests {@link FullRunningAverage}.</p> */
+public final class RunningAverageTest extends TasteTestCase {
+
+ @Test
+ public void testFull() {
+ RunningAverage runningAverage = new FullRunningAverage();
+
+ assertEquals(0, runningAverage.getCount());
+ assertTrue(Double.isNaN(runningAverage.getAverage()));
+ runningAverage.addDatum(1.0);
+ assertEquals(1, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(1.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(4.0);
+ assertEquals(3, runningAverage.getCount());
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(-4.0);
+ assertEquals(4, runningAverage.getCount());
+ assertEquals(0.5, runningAverage.getAverage(), EPSILON);
+
+ runningAverage.removeDatum(-4.0);
+ assertEquals(3, runningAverage.getCount());
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.removeDatum(4.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+
+ runningAverage.changeDatum(0.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.changeDatum(2.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ }
+
+ @Test
+ public void testCopyConstructor() {
+ RunningAverage runningAverage = new FullRunningAverage();
+
+ runningAverage.addDatum(1.0);
+ runningAverage.addDatum(1.0);
+ assertEquals(2, runningAverage.getCount());
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+
+ RunningAverage copy = new FullRunningAverage(runningAverage.getCount(), runningAverage.getAverage());
+ assertEquals(2, copy.getCount());
+ assertEquals(1.0, copy.getAverage(), EPSILON);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
new file mode 100644
index 0000000..a5b91ff
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+public final class SamplingLongPrimitiveIteratorTest extends TasteTestCase {
+
+ @Test
+ public void testEmptyCase() {
+ assertFalse(new SamplingLongPrimitiveIterator(
+ countingIterator(0), 0.9999).hasNext());
+ assertFalse(new SamplingLongPrimitiveIterator(
+ countingIterator(0), 1).hasNext());
+ }
+
+ @Test
+ public void testSmallInput() {
+ SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(
+ countingIterator(1), 0.9999);
+ assertTrue(t.hasNext());
+ assertEquals(0L, t.nextLong());
+ assertFalse(t.hasNext());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadRate1() {
+ new SamplingLongPrimitiveIterator(countingIterator(1), 0.0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadRate2() {
+ new SamplingLongPrimitiveIterator(countingIterator(1), 1.1);
+ }
+
+ @Test
+ public void testExactSizeMatch() {
+ SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(
+ countingIterator(10), 1);
+ for (int i = 0; i < 10; i++) {
+ assertTrue(t.hasNext());
+ assertEquals(i, t.next().intValue());
+ }
+ assertFalse(t.hasNext());
+ }
+
+ @Test
+ public void testSample() {
+ double p = 0.1;
+ int n = 1000;
+ double sd = Math.sqrt(n * p * (1.0 - p));
+ for (int i = 0; i < 1000; i++) {
+ SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(countingIterator(n), p);
+ int k = 0;
+ while (t.hasNext()) {
+ long v = t.nextLong();
+ k++;
+ assertTrue(v >= 0L);
+ assertTrue(v < 1000L);
+ }
+ // Should be +/- 5 standard deviations except in about 1 out of 1.7M cases
+ assertTrue(k >= 100 - 5 * sd);
+ assertTrue(k <= 100 + 5 * sd);
+ }
+ }
+
+ private static LongPrimitiveArrayIterator countingIterator(int to) {
+ long[] data = new long[to];
+ for (int i = 0; i < to; i++) {
+ data[i] = i;
+ }
+ return new LongPrimitiveArrayIterator(data);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
new file mode 100644
index 0000000..daa56e8
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/**
+ * <p>Tests {@link WeightedRunningAverage} and {@link WeightedRunningAverageAndStdDev}.</p>
+ */
+public final class WeightedRunningAverageTest extends TasteTestCase {
+
+ @Test
+ public void testWeighted() {
+
+ WeightedRunningAverage runningAverage = new WeightedRunningAverage();
+
+ assertEquals(0, runningAverage.getCount());
+ assertTrue(Double.isNaN(runningAverage.getAverage()));
+ runningAverage.addDatum(1.0, 2.0);
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(1.0);
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(8.0, 0.5);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.addDatum(-4.0);
+ assertEquals(2.0/3.0, runningAverage.getAverage(), EPSILON);
+
+ runningAverage.removeDatum(-4.0);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.removeDatum(2.0, 2.0);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+
+ runningAverage.changeDatum(0.0);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ runningAverage.changeDatum(4.0, 0.5);
+ assertEquals(5.0/1.5, runningAverage.getAverage(), EPSILON);
+ }
+
+ @Test
+ public void testWeightedAndStdDev() {
+
+ WeightedRunningAverageAndStdDev runningAverage = new WeightedRunningAverageAndStdDev();
+
+ assertEquals(0, runningAverage.getCount());
+ assertTrue(Double.isNaN(runningAverage.getAverage()));
+ assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+
+ runningAverage.addDatum(1.0);
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+ runningAverage.addDatum(1.0, 2.0);
+ assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(0.0, runningAverage.getStandardDeviation(), EPSILON);
+ runningAverage.addDatum(8.0, 0.5);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(Math.sqrt(10.5), runningAverage.getStandardDeviation(), EPSILON);
+ runningAverage.addDatum(-4.0);
+ assertEquals(2.0/3.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(Math.sqrt(15.75), runningAverage.getStandardDeviation(), EPSILON);
+
+ runningAverage.removeDatum(-4.0);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(Math.sqrt(10.5), runningAverage.getStandardDeviation(), EPSILON);
+ runningAverage.removeDatum(2.0, 2.0);
+ assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+ assertEquals(Math.sqrt(31.5), runningAverage.getStandardDeviation(), EPSILON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
new file mode 100644
index 0000000..a47327d
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.eval;
+
+import org.apache.mahout.cf.taste.eval.DataModelBuilder;
+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.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
+import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefItemBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.LogLikelihoodSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.junit.Test;
+
+public final class GenericRecommenderIRStatsEvaluatorImplTest extends TasteTestCase {
+
+ @Test
+ public void testBoolean() throws Exception {
+ DataModel model = getBooleanDataModel();
+ RecommenderBuilder builder = new RecommenderBuilder() {
+ @Override
+ public Recommender buildRecommender(DataModel dataModel) {
+ return new GenericBooleanPrefItemBasedRecommender(dataModel, new LogLikelihoodSimilarity(dataModel));
+ }
+ };
+ DataModelBuilder dataModelBuilder = new DataModelBuilder() {
+ @Override
+ public DataModel buildDataModel(FastByIDMap<PreferenceArray> trainingData) {
+ return new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(trainingData));
+ }
+ };
+ RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
+ IRStatistics stats = evaluator.evaluate(
+ builder, dataModelBuilder, model, null, 1, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
+
+ assertNotNull(stats);
+ assertEquals(0.666666666, stats.getPrecision(), EPSILON);
+ assertEquals(0.666666666, stats.getRecall(), EPSILON);
+ assertEquals(0.666666666, stats.getF1Measure(), EPSILON);
+ assertEquals(0.666666666, stats.getFNMeasure(2.0), EPSILON);
+ assertEquals(0.666666666, stats.getNormalizedDiscountedCumulativeGain(), EPSILON);
+ }
+
+ @Test
+ public void testIRStats() {
+ IRStatistics stats = new IRStatisticsImpl(0.3, 0.1, 0.2, 0.05, 0.15);
+ assertEquals(0.3, stats.getPrecision(), EPSILON);
+ assertEquals(0.1, stats.getRecall(), EPSILON);
+ assertEquals(0.15, stats.getF1Measure(), EPSILON);
+ assertEquals(0.11538461538462, stats.getFNMeasure(2.0), EPSILON);
+ assertEquals(0.05, stats.getNormalizedDiscountedCumulativeGain(), EPSILON);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
new file mode 100644
index 0000000..852b3e0
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
@@ -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.eval;
+
+import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
+import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
+import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
+import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+
+import java.io.File;
+
+public final class LoadEvaluationRunner {
+
+ private static final int LOOPS = 10;
+
+ private LoadEvaluationRunner() {
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ DataModel model = new FileDataModel(new File(args[0]));
+
+ int howMany = 10;
+ if (args.length > 1) {
+ howMany = Integer.parseInt(args[1]);
+ }
+
+ System.out.println("Run Items");
+ ItemSimilarity similarity = new EuclideanDistanceSimilarity(model);
+ Recommender recommender = new GenericItemBasedRecommender(model, similarity); // Use an item-item recommender
+ for (int i = 0; i < LOOPS; i++) {
+ LoadStatistics loadStats = LoadEvaluator.runLoad(recommender, howMany);
+ System.out.println(loadStats);
+ }
+
+ System.out.println("Run Users");
+ UserSimilarity userSim = new EuclideanDistanceSimilarity(model);
+ UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, userSim, model);
+ recommender = new GenericUserBasedRecommender(model, neighborhood, userSim);
+ for (int i = 0; i < LOOPS; i++) {
+ LoadStatistics loadStats = LoadEvaluator.runLoad(recommender, howMany);
+ System.out.println(loadStats);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
new file mode 100644
index 0000000..384b120
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
@@ -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.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class BooleanItemPreferenceArrayTest extends TasteTestCase {
+
+ @Test
+ public void testUserID() {
+ PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setItemID(0, 1L);
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ assertEquals(1L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testItemID() {
+ PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setUserID(0, 1L);
+ prefs.setUserID(1, 2L);
+ prefs.setUserID(2, 3L);
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(2L, prefs.getUserID(1));
+ assertEquals(3L, prefs.getUserID(2));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testSetValue() {
+ PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ assertEquals(1.0f, prefs.getValue(2), EPSILON);
+ prefs.setValue(0, 1.0f);
+ }
+
+ @Test
+ public void testHasPref() {
+ PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ assertTrue(prefs.hasPrefWithItemID(3L));
+ assertTrue(prefs.hasPrefWithUserID(1L));
+ assertFalse(prefs.hasPrefWithItemID(2L));
+ assertFalse(prefs.hasPrefWithUserID(2L));
+ }
+
+ @Test
+ public void testSort() {
+ PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+ prefs.set(2, new GenericPreference(2L, 1L, 5.0f));
+ prefs.sortByUser();
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(2L, prefs.getUserID(1));
+ assertEquals(3L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testClone() {
+ BooleanItemPreferenceArray prefs = new BooleanItemPreferenceArray(3);
+ prefs.set(0, new BooleanPreference(3L, 1L));
+ prefs.set(1, new BooleanPreference(1L, 1L));
+ prefs.set(2, new BooleanPreference(2L, 1L));
+ prefs = prefs.clone();
+ assertEquals(3L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
new file mode 100644
index 0000000..fa1f88c
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
@@ -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.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class BooleanUserPreferenceArrayTest extends TasteTestCase {
+
+ @Test
+ public void testUserID() {
+ PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setUserID(0, 1L);
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ assertEquals(1L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testItemID() {
+ PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setItemID(0, 1L);
+ prefs.setItemID(1, 2L);
+ prefs.setItemID(2, 3L);
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(2L, prefs.getItemID(1));
+ assertEquals(3L, prefs.getItemID(2));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testSetValue() {
+ PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ assertEquals(1.0f, prefs.getValue(2), EPSILON);
+ assertEquals(3, prefs.length());
+ prefs.setValue(0, 1.0f);
+ }
+
+ @Test
+ public void testHasPref() {
+ PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ assertTrue(prefs.hasPrefWithItemID(3L));
+ assertTrue(prefs.hasPrefWithUserID(1L));
+ assertFalse(prefs.hasPrefWithItemID(2L));
+ assertFalse(prefs.hasPrefWithUserID(2L));
+ }
+
+ @Test
+ public void testSort() {
+ PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ prefs.set(0, new BooleanPreference(1L, 3L));
+ prefs.set(1, new BooleanPreference(1L, 1L));
+ prefs.set(2, new BooleanPreference(1L, 2L));
+ prefs.sortByItem();
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(2L, prefs.getItemID(1));
+ assertEquals(3L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testClone() {
+ BooleanUserPreferenceArray prefs = new BooleanUserPreferenceArray(3);
+ prefs.set(0, new BooleanPreference(1L, 3L));
+ prefs.set(1, new BooleanPreference(1L, 1L));
+ prefs.set(2, new BooleanPreference(1L, 2L));
+ prefs = prefs.clone();
+ assertEquals(3L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
new file mode 100644
index 0000000..75bf070
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/**
+ * Tests {@link GenericDataModel}.
+ */
+public final class GenericDataModelTest extends TasteTestCase {
+
+ @Test
+ public void testSerialization() throws Exception {
+ GenericDataModel model = (GenericDataModel) getDataModel();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ out.writeObject(model);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ GenericDataModel newModel = (GenericDataModel) in.readObject();
+ assertEquals(model.getNumItems(), newModel.getNumItems());
+ assertEquals(model.getNumUsers(), newModel.getNumUsers());
+ assertEquals(model.getPreferencesFromUser(1L), newModel.getPreferencesFromUser(1L));
+ assertEquals(model.getPreferencesForItem(1L), newModel.getPreferencesForItem(1L));
+ assertEquals(model.getRawUserData(), newModel.getRawUserData());
+ }
+
+ // Lots of other stuff should be tested but is kind of covered by FileDataModelTest
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
new file mode 100644
index 0000000..5d77d0e
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class GenericItemPreferenceArrayTest extends TasteTestCase {
+
+ @Test
+ public void testUserID() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setItemID(0, 1L);
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ assertEquals(1L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testItemID() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setUserID(0, 1L);
+ prefs.setUserID(1, 2L);
+ prefs.setUserID(2, 3L);
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(2L, prefs.getUserID(1));
+ assertEquals(3L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testSetValue() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setValue(0, 1.0f);
+ prefs.setValue(1, 2.0f);
+ prefs.setValue(2, 3.0f);
+ assertEquals(1.0f, prefs.getValue(0), EPSILON);
+ assertEquals(2.0f, prefs.getValue(1), EPSILON);
+ assertEquals(3.0f, prefs.getValue(2), EPSILON);
+ }
+
+ @Test
+ public void testHasPref() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ assertTrue(prefs.hasPrefWithItemID(3L));
+ assertTrue(prefs.hasPrefWithUserID(1L));
+ assertFalse(prefs.hasPrefWithItemID(2L));
+ assertFalse(prefs.hasPrefWithUserID(2L));
+ }
+
+ @Test
+ public void testSort() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+ prefs.set(2, new GenericPreference(2L, 1L, 5.0f));
+ prefs.sortByUser();
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(2L, prefs.getUserID(1));
+ assertEquals(3L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testSortValue() {
+ PreferenceArray prefs = new GenericItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+ prefs.set(2, new GenericPreference(2L, 1L, 3.0f));
+ prefs.sortByValue();
+ assertEquals(2L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ assertEquals(3L, prefs.getUserID(2));
+ prefs.sortByValueReversed();
+ assertEquals(3L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ assertEquals(2L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testClone() {
+ GenericItemPreferenceArray prefs = new GenericItemPreferenceArray(3);
+ prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+ prefs.set(2, new GenericPreference(2L, 1L, 3.0f));
+ prefs = prefs.clone();
+ assertEquals(3L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ assertEquals(3.0f, prefs.getValue(2), EPSILON);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
new file mode 100644
index 0000000..2bde8cc
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class GenericUserPreferenceArrayTest extends TasteTestCase {
+
+ @Test
+ public void testUserID() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setUserID(0, 1L);
+ assertEquals(1L, prefs.getUserID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ assertEquals(1L, prefs.getUserID(2));
+ }
+
+ @Test
+ public void testItemID() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setItemID(0, 1L);
+ prefs.setItemID(1, 2L);
+ prefs.setItemID(2, 3L);
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(2L, prefs.getItemID(1));
+ assertEquals(3L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testSetValue() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ assertEquals(3, prefs.length());
+ prefs.setValue(0, 1.0f);
+ prefs.setValue(1, 2.0f);
+ prefs.setValue(2, 3.0f);
+ assertEquals(1.0f, prefs.getValue(0), EPSILON);
+ assertEquals(2.0f, prefs.getValue(1), EPSILON);
+ assertEquals(3.0f, prefs.getValue(2), EPSILON);
+ }
+
+ @Test
+ public void testHasPref() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ assertTrue(prefs.hasPrefWithItemID(3L));
+ assertTrue(prefs.hasPrefWithUserID(1L));
+ assertFalse(prefs.hasPrefWithItemID(2L));
+ assertFalse(prefs.hasPrefWithUserID(2L));
+ }
+
+ @Test
+ public void testSort() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+ prefs.set(2, new GenericPreference(1L, 2L, 5.0f));
+ prefs.sortByItem();
+ assertEquals(1L, prefs.getItemID(0));
+ assertEquals(2L, prefs.getItemID(1));
+ assertEquals(3L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testSortValue() {
+ PreferenceArray prefs = new GenericUserPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+ prefs.set(2, new GenericPreference(1L, 2L, 3.0f));
+ prefs.sortByValue();
+ assertEquals(2L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ assertEquals(3L, prefs.getItemID(2));
+ prefs.sortByValueReversed();
+ assertEquals(3L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getItemID(1));
+ assertEquals(2L, prefs.getItemID(2));
+ }
+
+ @Test
+ public void testClone() {
+ GenericUserPreferenceArray prefs = new GenericUserPreferenceArray(3);
+ prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+ prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+ prefs.set(2, new GenericPreference(1L, 2L, 3.0f));
+ prefs = prefs.clone();
+ assertEquals(3L, prefs.getItemID(0));
+ assertEquals(1L, prefs.getUserID(1));
+ assertEquals(3.0f, prefs.getValue(2), EPSILON);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
new file mode 100644
index 0000000..c8c673b
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.IDMigrator;
+
+import java.util.Collections;
+import org.apache.mahout.cf.taste.model.UpdatableIDMigrator;
+import org.junit.Test;
+
+public final class MemoryIDMigratorTest extends TasteTestCase {
+
+ private static final String DUMMY_STRING = "Mahout";
+ private static final long DUMMY_ID = -6311185995763544451L;
+
+ @Test
+ public void testToLong() {
+ IDMigrator migrator = new MemoryIDMigrator();
+ long id = migrator.toLongID(DUMMY_STRING);
+ assertEquals(DUMMY_ID, id);
+ }
+
+ @Test
+ public void testStore() throws Exception {
+ UpdatableIDMigrator migrator = new MemoryIDMigrator();
+ long id = migrator.toLongID(DUMMY_STRING);
+ assertNull(migrator.toStringID(id));
+ migrator.storeMapping(id, DUMMY_STRING);
+ assertEquals(DUMMY_STRING, migrator.toStringID(id));
+ }
+
+ @Test
+ public void testInitialize() throws Exception {
+ UpdatableIDMigrator migrator = new MemoryIDMigrator();
+ long id = migrator.toLongID(DUMMY_STRING);
+ assertNull(migrator.toStringID(id));
+ migrator.initialize(Collections.singleton(DUMMY_STRING));
+ assertEquals(DUMMY_STRING, migrator.toStringID(id));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
new file mode 100644
index 0000000..f33ba33
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
@@ -0,0 +1,313 @@
+/*
+ * 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 java.util.Iterator;
+import org.apache.mahout.cf.taste.common.NoSuchUserException;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.common.MahoutTestCase;
+import org.junit.Test;
+
+public final class PlusAnonymousConcurrentUserDataModelTest extends MahoutTestCase {
+
+ /**
+ * Prepares a testable object without delegate data
+ */
+ private static PlusAnonymousConcurrentUserDataModel getTestableWithoutDelegateData(int maxConcurrentUsers) {
+ FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+ return new PlusAnonymousConcurrentUserDataModel(new GenericDataModel(delegatePreferences), maxConcurrentUsers);
+ }
+
+ /**
+ * Prepares a testable object with delegate data
+ */
+ private static PlusAnonymousConcurrentUserDataModel getTestableWithDelegateData(
+ int maxConcurrentUsers, FastByIDMap<PreferenceArray> delegatePreferences) {
+ return new PlusAnonymousConcurrentUserDataModel(new GenericDataModel(delegatePreferences), maxConcurrentUsers);
+ }
+
+ /**
+ * Test taking the first available user
+ */
+ @Test
+ public void testTakeFirstAvailableUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ Long expResult = PlusAnonymousUserDataModel.TEMP_USER_ID;
+ Long result = instance.takeAvailableUser();
+ assertEquals(expResult, result);
+ }
+
+ /**
+ * Test taking the next available user
+ */
+ @Test
+ public void testTakeNextAvailableUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ // Skip first user
+ instance.takeAvailableUser();
+ Long result = instance.takeAvailableUser();
+ Long expResult = PlusAnonymousUserDataModel.TEMP_USER_ID + 1;
+ assertEquals(expResult, result);
+ }
+
+ /**
+ * Test taking an unavailable user
+ */
+ @Test
+ public void testTakeUnavailableUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(1);
+ // Take the only available user
+ instance.takeAvailableUser();
+ // There are no more users available
+ assertNull(instance.takeAvailableUser());
+ }
+
+ /**
+ * Test releasing a valid previously taken user
+ */
+ @Test
+ public void testReleaseValidUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ Long takenUserID = instance.takeAvailableUser();
+ assertTrue(instance.releaseUser(takenUserID));
+ }
+
+ /**
+ * Test releasing an invalid user
+ */
+ @Test
+ public void testReleaseInvalidUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ assertFalse(instance.releaseUser(Long.MAX_VALUE));
+ }
+
+ /**
+ * Test releasing a user which had been released earlier
+ */
+ @Test
+ public void testReleasePreviouslyReleasedUser() {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ Long takenUserID = instance.takeAvailableUser();
+ assertTrue(instance.releaseUser(takenUserID));
+ assertFalse(instance.releaseUser(takenUserID));
+ }
+
+ /**
+ * Test setting anonymous user preferences
+ */
+ @Test
+ public void testSetAndGetTempPreferences() throws TasteException {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ Long anonymousUserID = instance.takeAvailableUser();
+ PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+ tempPrefs.setUserID(0, anonymousUserID);
+ tempPrefs.setItemID(0, 1);
+ instance.setTempPrefs(tempPrefs, anonymousUserID);
+ assertEquals(tempPrefs, instance.getPreferencesFromUser(anonymousUserID));
+ instance.releaseUser(anonymousUserID);
+ }
+
+ /**
+ * Test setting and getting preferences from several concurrent anonymous users
+ */
+ @Test
+ public void testSetMultipleTempPreferences() throws TasteException {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+ Long anonymousUserID1 = instance.takeAvailableUser();
+ Long anonymousUserID2 = instance.takeAvailableUser();
+
+ PreferenceArray tempPrefs1 = new GenericUserPreferenceArray(1);
+ tempPrefs1.setUserID(0, anonymousUserID1);
+ tempPrefs1.setItemID(0, 1);
+
+ PreferenceArray tempPrefs2 = new GenericUserPreferenceArray(2);
+ tempPrefs2.setUserID(0, anonymousUserID2);
+ tempPrefs2.setItemID(0, 2);
+ tempPrefs2.setUserID(1, anonymousUserID2);
+ tempPrefs2.setItemID(1, 3);
+
+ instance.setTempPrefs(tempPrefs1, anonymousUserID1);
+ instance.setTempPrefs(tempPrefs2, anonymousUserID2);
+
+ assertEquals(tempPrefs1, instance.getPreferencesFromUser(anonymousUserID1));
+ assertEquals(tempPrefs2, instance.getPreferencesFromUser(anonymousUserID2));
+ }
+
+ /**
+ * Test counting the number of delegate users
+ */
+ @Test
+ public void testGetNumUsersWithDelegateUsersOnly() throws TasteException {
+ PreferenceArray prefs = new GenericUserPreferenceArray(1);
+ long sampleUserID = 1;
+ prefs.setUserID(0, sampleUserID);
+ long sampleItemID = 11;
+ prefs.setItemID(0, sampleItemID);
+
+ FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+ delegatePreferences.put(sampleUserID, prefs);
+
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+ assertEquals(1, instance.getNumUsers());
+ }
+
+ /**
+ * Test counting the number of anonymous users
+ */
+ @Test
+ public void testGetNumAnonymousUsers() throws TasteException {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+ Long anonymousUserID1 = instance.takeAvailableUser();
+
+ PreferenceArray tempPrefs1 = new GenericUserPreferenceArray(1);
+ tempPrefs1.setUserID(0, anonymousUserID1);
+ tempPrefs1.setItemID(0, 1);
+
+ instance.setTempPrefs(tempPrefs1, anonymousUserID1);
+
+ // Anonymous users should not be included into the universe.
+ assertEquals(0, instance.getNumUsers());
+ }
+
+ /**
+ * Test retrieve a single preference value of an anonymous user
+ */
+ @Test
+ public void testGetPreferenceValue() throws TasteException {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+ Long anonymousUserID = instance.takeAvailableUser();
+
+ PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+ tempPrefs.setUserID(0, anonymousUserID);
+ long sampleItemID = 1;
+ tempPrefs.setItemID(0, sampleItemID);
+ tempPrefs.setValue(0, Float.MAX_VALUE);
+
+ instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+ assertEquals(Float.MAX_VALUE, instance.getPreferenceValue(anonymousUserID, sampleItemID), EPSILON);
+ }
+
+ /**
+ * Test retrieve preferences for existing non-anonymous user
+ */
+ @Test
+ public void testGetPreferencesForNonAnonymousUser() throws TasteException {
+ PreferenceArray prefs = new GenericUserPreferenceArray(1);
+ long sampleUserID = 1;
+ prefs.setUserID(0, sampleUserID);
+ long sampleItemID = 11;
+ prefs.setItemID(0, sampleItemID);
+
+ FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+ delegatePreferences.put(sampleUserID, prefs);
+
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+ assertEquals(prefs, instance.getPreferencesFromUser(sampleUserID));
+ }
+
+ /**
+ * Test retrieve preferences for non-anonymous and non-existing user
+ */
+ @Test(expected=NoSuchUserException.class)
+ public void testGetPreferencesForNonExistingUser() throws TasteException {
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+ // Exception is expected since such user does not exist
+ instance.getPreferencesFromUser(1);
+ }
+
+ /**
+ * Test retrieving the user IDs and verifying that anonymous ones are not included
+ */
+ @Test
+ public void testGetUserIDs() throws TasteException {
+ PreferenceArray prefs = new GenericUserPreferenceArray(1);
+ long sampleUserID = 1;
+ prefs.setUserID(0, sampleUserID);
+ long sampleItemID = 11;
+ prefs.setItemID(0, sampleItemID);
+
+ FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+ delegatePreferences.put(sampleUserID, prefs);
+
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+ Long anonymousUserID = instance.takeAvailableUser();
+
+ PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+ tempPrefs.setUserID(0, anonymousUserID);
+ tempPrefs.setItemID(0, 22);
+
+ instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+ Iterator<Long> userIDs = instance.getUserIDs();
+
+ assertSame(sampleUserID, userIDs.next());
+ assertFalse(userIDs.hasNext());
+ }
+
+ /**
+ * Test getting preferences for an item.
+ *
+ * @throws TasteException
+ */
+ @Test
+ public void testGetPreferencesForItem() throws TasteException {
+ PreferenceArray prefs = new GenericUserPreferenceArray(2);
+ long sampleUserID = 4;
+ prefs.setUserID(0, sampleUserID);
+ long sampleItemID = 11;
+ prefs.setItemID(0, sampleItemID);
+ prefs.setUserID(1, sampleUserID);
+ long sampleItemID2 = 22;
+ prefs.setItemID(1, sampleItemID2);
+
+ FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+ delegatePreferences.put(sampleUserID, prefs);
+
+ PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+ Long anonymousUserID = instance.takeAvailableUser();
+
+ PreferenceArray tempPrefs = new GenericUserPreferenceArray(2);
+ tempPrefs.setUserID(0, anonymousUserID);
+ tempPrefs.setItemID(0, sampleItemID);
+ tempPrefs.setUserID(1, anonymousUserID);
+ long sampleItemID3 = 33;
+ tempPrefs.setItemID(1, sampleItemID3);
+
+ instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+ assertEquals(sampleUserID, instance.getPreferencesForItem(sampleItemID).get(0).getUserID());
+ assertEquals(2, instance.getPreferencesForItem(sampleItemID).length());
+ assertEquals(1, instance.getPreferencesForItem(sampleItemID2).length());
+ assertEquals(1, instance.getPreferencesForItem(sampleItemID3).length());
+
+ assertEquals(2, instance.getNumUsersWithPreferenceFor(sampleItemID));
+ assertEquals(1, instance.getNumUsersWithPreferenceFor(sampleItemID, sampleItemID2));
+ assertEquals(1, instance.getNumUsersWithPreferenceFor(sampleItemID, sampleItemID3));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
new file mode 100644
index 0000000..be59eee
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
@@ -0,0 +1,216 @@
+/**
+ * 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.file;
+
+import java.io.File;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
+import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+import org.junit.Before;
+import org.junit.Test;
+
+/** <p>Tests {@link FileDataModel}.</p> */
+public final class FileDataModelTest extends TasteTestCase {
+
+ private static final String[] DATA = {
+ "123,456,0.1",
+ "123,789,0.6",
+ "123,654,0.7",
+ "234,123,0.5",
+ "234,234,1.0",
+ "234,999,0.9",
+ "345,789,0.6",
+ "345,654,0.7",
+ "345,123,1.0",
+ "345,234,0.5",
+ "345,999,0.5",
+ "456,456,0.1",
+ "456,789,0.5",
+ "456,654,0.0",
+ "456,999,0.2",};
+
+ private static final String[] DATA_SPLITTED_WITH_TWO_SPACES = {
+ "123 456 0.1",
+ "123 789 0.6",
+ "123 654 0.7",
+ "234 123 0.5",
+ "234 234 1.0",
+ "234 999 0.9",
+ "345 789 0.6",
+ "345 654 0.7",
+ "345 123 1.0",
+ "345 234 0.5",
+ "345 999 0.5",
+ "456 456 0.1",
+ "456 789 0.5",
+ "456 654 0.0",
+ "456 999 0.2",};
+
+ private DataModel model;
+ private File testFile;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ testFile = getTestTempFile("test.txt");
+ writeLines(testFile, DATA);
+ model = new FileDataModel(testFile);
+ }
+
+ @Test
+ public void testReadRegexSplittedFile() throws Exception {
+ File testFile = getTestTempFile("testRegex.txt");
+ writeLines(testFile, DATA_SPLITTED_WITH_TWO_SPACES);
+ FileDataModel model = new FileDataModel(testFile,"\\s+");
+ assertEquals(model.getItemIDsFromUser(123).size(), 3);
+ assertEquals(model.getItemIDsFromUser(456).size(), 4);
+ }
+
+ @Test
+ public void testFile() throws Exception {
+ UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(model);
+ UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, userSimilarity, model);
+ Recommender recommender = new GenericUserBasedRecommender(model, neighborhood, userSimilarity);
+ assertEquals(1, recommender.recommend(123, 3).size());
+ assertEquals(0, recommender.recommend(234, 3).size());
+ assertEquals(1, recommender.recommend(345, 3).size());
+
+ // Make sure this doesn't throw an exception
+ model.refresh(null);
+ }
+
+ @Test
+ public void testTranspose() throws Exception {
+ FileDataModel tModel = new FileDataModel(testFile, true, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS);
+ PreferenceArray userPrefs = tModel.getPreferencesFromUser(456);
+ assertNotNull("user prefs are null and it shouldn't be", userPrefs);
+ PreferenceArray pref = tModel.getPreferencesForItem(123);
+ assertNotNull("pref is null and it shouldn't be", pref);
+ assertEquals("pref Size: " + pref.length() + " is not: " + 3, 3, pref.length());
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testGetItems() throws Exception {
+ LongPrimitiveIterator it = model.getItemIDs();
+ assertNotNull(it);
+ assertTrue(it.hasNext());
+ assertEquals(123, it.nextLong());
+ assertTrue(it.hasNext());
+ assertEquals(234, it.nextLong());
+ assertTrue(it.hasNext());
+ assertEquals(456, it.nextLong());
+ assertTrue(it.hasNext());
+ assertEquals(654, it.nextLong());
+ assertTrue(it.hasNext());
+ assertEquals(789, it.nextLong());
+ assertTrue(it.hasNext());
+ assertEquals(999, it.nextLong());
+ assertFalse(it.hasNext());
+ it.next();
+ }
+
+ @Test
+ public void testPreferencesForItem() throws Exception {
+ PreferenceArray prefs = model.getPreferencesForItem(456);
+ assertNotNull(prefs);
+ Preference pref1 = prefs.get(0);
+ assertEquals(123, pref1.getUserID());
+ assertEquals(456, pref1.getItemID());
+ Preference pref2 = prefs.get(1);
+ assertEquals(456, pref2.getUserID());
+ assertEquals(456, pref2.getItemID());
+ assertEquals(2, prefs.length());
+ }
+
+ @Test
+ public void testGetNumUsers() throws Exception {
+ assertEquals(4, model.getNumUsers());
+ }
+
+ @Test
+ public void testNumUsersPreferring() throws Exception {
+ assertEquals(2, model.getNumUsersWithPreferenceFor(456));
+ assertEquals(0, model.getNumUsersWithPreferenceFor(111));
+ assertEquals(0, model.getNumUsersWithPreferenceFor(111, 456));
+ assertEquals(2, model.getNumUsersWithPreferenceFor(123, 234));
+ }
+
+ @Test
+ public void testRefresh() throws Exception {
+ final MutableBoolean initialized = new MutableBoolean(false);
+ Runnable initializer = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ model.getNumUsers();
+ initialized.setValue(true);
+ } catch (TasteException te) {
+ // oops
+ }
+ }
+ };
+ new Thread(initializer).start();
+ Thread.sleep(1000L); // wait a second for thread to start and call getNumUsers()
+ model.getNumUsers(); // should block
+ assertTrue(initialized.booleanValue());
+ assertEquals(4, model.getNumUsers());
+ }
+
+ @Test
+ public void testExplicitRefreshAfterCompleteFileUpdate() throws Exception {
+ File file = getTestTempFile("refresh");
+ writeLines(file, "123,456,3.0");
+
+ /* create a FileDataModel that always reloads when the underlying file has changed */
+ FileDataModel dataModel = new FileDataModel(file, false, 0L);
+ assertEquals(3.0f, dataModel.getPreferenceValue(123L, 456L), EPSILON);
+
+ /* change the underlying file,
+ * we have to wait at least a second to see the change in the file's lastModified timestamp */
+ Thread.sleep(2000L);
+ writeLines(file, "123,456,5.0");
+ dataModel.refresh(null);
+
+ assertEquals(5.0f, dataModel.getPreferenceValue(123L, 456L), EPSILON);
+ }
+
+ @Test
+ public void testToString() {
+ assertFalse(model.toString().isEmpty());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmptyFile() throws Exception {
+ File file = getTestTempFile("empty");
+ writeLines(file); //required to create file.
+ new FileDataModel(file);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
new file mode 100644
index 0000000..0a73315
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.file;
+
+import java.io.File;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.IDMigrator;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link FileIDMigrator}
+ */
+public final class FileIDMigratorTest extends TasteTestCase {
+
+ private static final String[] STRING_IDS = {
+ "dog",
+ "cow" };
+
+ private static final String[] UPDATED_STRING_IDS = {
+ "dog",
+ "cow",
+ "donkey" };
+
+ private File testFile;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ testFile = getTestTempFile("test.txt");
+ writeLines(testFile, STRING_IDS);
+ }
+
+ @Test
+ public void testLoadFromFile() throws Exception {
+ IDMigrator migrator = new FileIDMigrator(testFile);
+ long dogAsLong = migrator.toLongID("dog");
+ long cowAsLong = migrator.toLongID("cow");
+ long donkeyAsLong = migrator.toLongID("donkey");
+ assertEquals("dog", migrator.toStringID(dogAsLong));
+ assertEquals("cow", migrator.toStringID(cowAsLong));
+ assertNull(migrator.toStringID(donkeyAsLong));
+ }
+
+ @Test
+ public void testNoRefreshAfterFileUpdate() throws Exception {
+ IDMigrator migrator = new FileIDMigrator(testFile, 0L);
+
+ /* call a method to make sure the original file is loaded */
+ long dogAsLong = migrator.toLongID("dog");
+ migrator.toStringID(dogAsLong);
+
+ /* change the underlying file,
+ * we have to wait at least a second to see the change in the file's lastModified timestamp */
+ Thread.sleep(2000L);
+ writeLines(testFile, UPDATED_STRING_IDS);
+
+ /* we shouldn't see any changes in the data as we have not yet refreshed */
+ long cowAsLong = migrator.toLongID("cow");
+ long donkeyAsLong = migrator.toLongID("donkey");
+ assertEquals("dog", migrator.toStringID(dogAsLong));
+ assertEquals("cow", migrator.toStringID(cowAsLong));
+ assertNull(migrator.toStringID(donkeyAsLong));
+ }
+
+ @Test
+ public void testRefreshAfterFileUpdate() throws Exception {
+ IDMigrator migrator = new FileIDMigrator(testFile, 0L);
+
+ /* call a method to make sure the original file is loaded */
+ long dogAsLong = migrator.toLongID("dog");
+ migrator.toStringID(dogAsLong);
+
+ /* change the underlying file,
+ * we have to wait at least a second to see the change in the file's lastModified timestamp */
+ Thread.sleep(2000L);
+ writeLines(testFile, UPDATED_STRING_IDS);
+
+ migrator.refresh(null);
+
+ long cowAsLong = migrator.toLongID("cow");
+ long donkeyAsLong = migrator.toLongID("donkey");
+ assertEquals("dog", migrator.toStringID(dogAsLong));
+ assertEquals("cow", migrator.toStringID(cowAsLong));
+ assertEquals("donkey", migrator.toStringID(donkeyAsLong));
+ }
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
new file mode 100644
index 0000000..b057e5b
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
@@ -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.neighborhood;
+
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.similarity.AbstractItemSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+
+import java.util.Collection;
+
+final class DummySimilarity extends AbstractItemSimilarity implements UserSimilarity {
+
+ DummySimilarity(DataModel dataModel) {
+ super(dataModel);
+ }
+
+ @Override
+ public double userSimilarity(long userID1, long userID2) throws TasteException {
+ DataModel dataModel = getDataModel();
+ return 1.0 / (1.0 + Math.abs(dataModel.getPreferencesFromUser(userID1).get(0).getValue()
+ - dataModel.getPreferencesFromUser(userID2).get(0).getValue()));
+ }
+
+ @Override
+ public double itemSimilarity(long itemID1, long itemID2) {
+ // Make up something wacky
+ return 1.0 / (1.0 + Math.abs(itemID1 - itemID2));
+ }
+
+ @Override
+ public double[] itemSimilarities(long itemID1, long[] itemID2s) {
+ int length = itemID2s.length;
+ double[] result = new double[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = itemSimilarity(itemID1, itemID2s[i]);
+ }
+ return result;
+ }
+
+ @Override
+ public void setPreferenceInferrer(PreferenceInferrer inferrer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void refresh(Collection<Refreshable> alreadyRefreshed) {
+ // do nothing
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
new file mode 100644
index 0000000..729dc9a
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
@@ -0,0 +1,53 @@
+/**
+ * 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.neighborhood;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.junit.Test;
+
+/** <p>Tests {@link NearestNUserNeighborhood}.</p> */
+public final class NearestNNeighborhoodTest extends TasteTestCase {
+
+ @Test
+ public void testNeighborhood() throws Exception {
+ DataModel dataModel = getDataModel();
+
+ long[] neighborhood =
+ new NearestNUserNeighborhood(1, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+ assertNotNull(neighborhood);
+ assertEquals(1, neighborhood.length);
+ assertTrue(arrayContains(neighborhood, 2));
+
+ long[] neighborhood2 =
+ new NearestNUserNeighborhood(2, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(2);
+ assertNotNull(neighborhood2);
+ assertEquals(2, neighborhood2.length);
+ assertTrue(arrayContains(neighborhood2, 1));
+ assertTrue(arrayContains(neighborhood2, 3));
+
+ long[] neighborhood3 =
+ new NearestNUserNeighborhood(4, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(4);
+ assertNotNull(neighborhood3);
+ assertEquals(3, neighborhood3.length);
+ assertTrue(arrayContains(neighborhood3, 1));
+ assertTrue(arrayContains(neighborhood3, 2));
+ assertTrue(arrayContains(neighborhood3, 3));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
new file mode 100644
index 0000000..c3005a9
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.neighborhood;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.junit.Test;
+
+/** <p>Tests {@link ThresholdUserNeighborhood}.</p> */
+public final class ThresholdNeighborhoodTest extends TasteTestCase {
+
+ @Test
+ public void testNeighborhood() throws Exception {
+ DataModel dataModel = getDataModel();
+
+ long[] neighborhood =
+ new ThresholdUserNeighborhood(1.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+ assertNotNull(neighborhood);
+ assertEquals(0, neighborhood.length);
+
+ long[] neighborhood2 =
+ new ThresholdUserNeighborhood(0.8, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+ assertNotNull(neighborhood2);
+ assertEquals(1, neighborhood2.length);
+ assertTrue(arrayContains(neighborhood2, 2));
+
+ long[] neighborhood3 =
+ new ThresholdUserNeighborhood(0.6, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(2);
+ assertNotNull(neighborhood3);
+ assertEquals(3, neighborhood3.length);
+ assertTrue(arrayContains(neighborhood3, 1));
+ assertTrue(arrayContains(neighborhood3, 3));
+ assertTrue(arrayContains(neighborhood3, 4));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
new file mode 100644
index 0000000..5d9f8cc
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
@@ -0,0 +1,65 @@
+/**
+ * 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.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.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.util.Collections;
+
+/**
+ * Tests {@link AllUnknownItemsCandidateItemsStrategyTest}
+ */
+public final class AllUnknownItemsCandidateItemsStrategyTest extends TasteTestCase {
+
+ @Test
+ 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());
+
+ PreferenceArray prefArrayOfUser123 = new GenericUserPreferenceArray(Collections.singletonList(
+ new GenericPreference(123L, 2L, 1.0f)));
+
+ CandidateItemsStrategy strategy = new AllUnknownItemsCandidateItemsStrategy();
+
+ EasyMock.replay(dataModel);
+
+ FastIDSet candidateItems = strategy.getCandidateItems(123L, prefArrayOfUser123, dataModel, false);
+ assertEquals(2, candidateItems.size());
+ assertTrue(candidateItems.contains(1L));
+ assertTrue(candidateItems.contains(3L));
+
+ EasyMock.verify(dataModel);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
new file mode 100644
index 0000000..3ae35b0
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.commons.lang3.mutable.MutableInt;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.recommender.IDRescorer;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.junit.Test;
+
+/** <p>Tests {@link CachingRecommender}.</p> */
+public final class CachingRecommenderTest extends TasteTestCase {
+
+ @Test
+ public void testRecommender() throws Exception {
+ MutableInt recommendCount = new MutableInt();
+ Recommender mockRecommender = new MockRecommender(recommendCount);
+
+ Recommender cachingRecommender = new CachingRecommender(mockRecommender);
+ cachingRecommender.recommend(1, 1);
+ assertEquals(1, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1);
+ assertEquals(2, recommendCount.intValue());
+ cachingRecommender.recommend(1, 1);
+ assertEquals(2, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1);
+ assertEquals(2, recommendCount.intValue());
+ cachingRecommender.refresh(null);
+ cachingRecommender.recommend(1, 1);
+ assertEquals(3, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1);
+ assertEquals(4, recommendCount.intValue());
+ cachingRecommender.recommend(3, 1);
+ assertEquals(5, recommendCount.intValue());
+
+ // Results from this recommend() method can be cached...
+ IDRescorer rescorer = NullRescorer.getItemInstance();
+ cachingRecommender.refresh(null);
+ cachingRecommender.recommend(1, 1, rescorer);
+ assertEquals(6, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1, rescorer);
+ assertEquals(7, recommendCount.intValue());
+ cachingRecommender.recommend(1, 1, rescorer);
+ assertEquals(7, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1, rescorer);
+ assertEquals(7, recommendCount.intValue());
+
+ // until you switch Rescorers
+ cachingRecommender.recommend(1, 1, null);
+ assertEquals(8, recommendCount.intValue());
+ cachingRecommender.recommend(2, 1, null);
+ assertEquals(9, recommendCount.intValue());
+
+ cachingRecommender.refresh(null);
+ cachingRecommender.estimatePreference(1, 1);
+ assertEquals(10, recommendCount.intValue());
+ cachingRecommender.estimatePreference(1, 2);
+ assertEquals(11, recommendCount.intValue());
+ cachingRecommender.estimatePreference(1, 2);
+ assertEquals(11, recommendCount.intValue());
+ }
+
+}