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()); + } + +}
