001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package org.conqat.lib.commons.datamining;
018
019import java.util.HashSet;
020import java.util.List;
021import java.util.Set;
022
023import org.conqat.lib.commons.assertion.CCSMAssert;
024import org.conqat.lib.commons.collections.CollectionUtils;
025import org.conqat.lib.commons.collections.CounterSet;
026import org.conqat.lib.commons.collections.UnmodifiableSet;
027
028/**
029 * Trivial recommender that always returns the top n used items from the
030 * training data, independent of the query. The confidence is set to a fixed
031 * value of .5 for all recommendations.
032 */
033public class TopNRecommender<T> implements IRecommender<T> {
034
035        /** The fixed set of recommendations */
036        private final Set<Recommendation<T>> recommendations = new HashSet<Recommendation<T>>();
037
038        /**
039         * Constructs a new {@link TopNRecommender} using the given rating data
040         * base. There have to be at least numRecommendations entries in the data
041         * base.
042         */
043        public TopNRecommender(RecommenderRatingDatabase<T> ratingDatabase, int numRecommendations) {
044
045                CounterSet<T> occurences = new CounterSet<T>();
046                for (IRecommenderUser user : ratingDatabase.getUsers()) {
047                        occurences.incAll(ratingDatabase.getLikedItems(user));
048                }
049
050                CCSMAssert.isTrue(occurences.getKeys().size() >= numRecommendations,
051                                "There have to be at least numRecommendation distinct items");
052
053                List<T> topItems = occurences.getKeysByValueDescending();
054
055                for (int i = 0; i < numRecommendations; i++) {
056                        // We give each recommendation a fixed 'dummy' confidence of .5
057                        recommendations.add(new Recommendation<T>(topItems.get(i), .5d));
058                }
059        }
060
061        /** {@inheritDoc} */
062        @Override
063        public UnmodifiableSet<Recommendation<T>> recommend(IRecommenderUser user) {
064                return CollectionUtils.asUnmodifiable(recommendations);
065        }
066}