public List<ItemVO<Integer, Integer>> getAvailableItemsForTenant(final Integer tenantId, final Integer itemTypeId) { Set<ItemVO<Integer, Integer>> result = new HashSet<ItemVO<Integer, Integer>>(); for (RatingVO<Integer, Integer> rating : ratings) { if (!tenantId.equals(rating.getItem().getTenant())) continue; if (!itemTypeId.equals(rating.getItem().getType())) continue; if (result.contains(rating.getItem())) continue; result.add(rating.getItem()); } return new ArrayList<ItemVO<Integer, Integer>>(result); }
public boolean didUserRateItem(final Integer userId, final ItemVO<Integer, Integer> item, final Integer actionTypeId) { if (actionTypeId != this.actionTypeId) return false; for (RatingVO<Integer, Integer> rating : ratings) { if (!rating.getUser().equals(userId)) continue; if (!rating.getItem().equals(item)) continue; return true; } return false; }
public List<RatingVO<Integer, Integer>> getLatestRatingsForTenant(final Integer tenantId, final Integer itemTypeId, final Integer itemId, final Integer userId, final Date since) { List<RatingVO<Integer, Integer>> result = new LinkedList<RatingVO<Integer, Integer>>(); for (RatingVO<Integer, Integer> rating : ratings) { if (!rating.getItem().getTenant().equals(tenantId)) continue; if (!rating.getItem().getType().equals(itemTypeId)) continue; if (itemId != null && !rating.getItem().getItem().equals(itemId)) continue; if (userId != null && !rating.getUser().equals(userId)) continue; if (since != null && !rating.getLastActionTime().after(since)) continue; result.add(rating); } return result; }
public DeviationCalculationResult calculate(int userId, List<RatingVO<Integer, Integer>> ratings, Date oldRatingsBeforeThisDate) { if ((ratings == null) || ratings.isEmpty()) throw new IllegalArgumentException("Can't calculate deviations for null or empyty ratings list."); int tenantId = ratings.get(0).getItem().getTenant(); int itemTypeId = ratings.get(0).getItem().getType(); DeviationCalculationResult result = childStrategy.calculate(userId, ratings, oldRatingsBeforeThisDate); List<Deviation> deviations = result.getDeviations(); deviationDAO.insertDeviations(deviations); return new DeviationCalculationResult(deviations, deviations.size(), deviations.size()); } }
@Override protected Map<Integer, RatingVO<Integer, Integer>> getAverageItemRatings(final Integer tenantId, final Integer itemTypeId) { final List<RatingVO<Integer, Integer>> averageItemRatings = getLatestActionDao() .getAverageRatingsForItem(tenantId, itemTypeId); final Map<Integer, RatingVO<Integer, Integer>> averageItemRatingsPerItem = new HashMap<Integer, RatingVO<Integer, Integer>>( averageItemRatings.size()); for (final RatingVO<Integer, Integer> rating : averageItemRatings) averageItemRatingsPerItem.put(rating.getItem().getItem(), rating); return averageItemRatingsPerItem; } }
public List<RatingVO<Integer, Integer>> getAverageRatingsForUser(final Integer tenantId, final Integer itemTypeId) { Map<Integer, Double> sum = new HashMap<Integer, Double>(); Map<Integer, Integer> count = new HashMap<Integer, Integer>(); for (RatingVO<Integer, Integer> rating : ratings) { if (!tenantId.equals(rating.getItem().getTenant())) continue; if (!itemTypeId.equals(rating.getItem().getType())) continue; Integer key = rating.getUser(); if (!sum.containsKey(key)) { sum.put(key, 0.0); count.put(key, 0); } sum.put(key, sum.get(key) + rating.getRatingValue()); count.put(key, count.get(key) + 1); } List<RatingVO<Integer, Integer>> result = new ArrayList<RatingVO<Integer, Integer>>( sum.size()); for (Integer key : sum.keySet()) { RatingVO<Integer, Integer> rating = new RatingVO<Integer, Integer>(null, sum.get(key) / count.get(key), count.get(key), null, key, null); result.add(rating); } return result; }
public List<RatingVO<Integer, Integer>> getAverageRatingsForItem(final Integer tenantId, final Integer itemTypeId) { Map<Integer, Double> sum = new HashMap<Integer, Double>(); Map<Integer, Integer> count = new HashMap<Integer, Integer>(); for (RatingVO<Integer, Integer> rating : ratings) { if (!tenantId.equals(rating.getItem().getTenant())) continue; if (!itemTypeId.equals(rating.getItem().getType())) continue; Integer key = rating.getItem().getItem(); if (!sum.containsKey(key)) { sum.put(key, 0.0); count.put(key, 0); } sum.put(key, sum.get(key) + rating.getRatingValue()); count.put(key, count.get(key) + 1); } List<RatingVO<Integer, Integer>> result = new ArrayList<RatingVO<Integer, Integer>>( sum.size()); for (Integer key : sum.keySet()) { RatingVO<Integer, Integer> rating = new RatingVO<Integer, Integer>( new ItemVO<Integer, Integer>(tenantId, key, itemTypeId), sum.get(key) / count.get(key), count.get(key), null, null, null); result.add(rating); } return result; }
@Override protected double getAverage2(final RatedTogether<Integer, Integer> ratedTogether, final Map<Integer, RatingVO<Integer, Integer>> averageRatings) { return averageRatings.get(ratedTogether.getRating2().getItem().getItem()).getRatingValue(); }
@Override protected double getAverage1(final RatedTogether<Integer, Integer> ratedTogether, final Map<Integer, RatingVO<Integer, Integer>> averageRatings) { return averageRatings.get(ratedTogether.getRating1().getItem().getItem()).getRatingValue(); }
/** * Creates a mapping of item IDs for which the user has rated to the ratings of the user * * @param userId The user to create the mapping for. * @return The mapping itemId -> RatingVO. */ private Map<Integer, RatingVO<Integer, Integer>> getRatingsOfUserMap(final Integer userId) { final List<RatingVO<Integer, Integer>> ratingsOfUser = actionDao .getLatestRatingsForTenant(sample.getTenantId(), sample.getItemTo().getType(), null, userId, null); final Map<Integer, RatingVO<Integer, Integer>> ratingsOfUserMap = new HashMap<Integer, RatingVO<Integer, Integer>>(); for (final RatingVO<Integer, Integer> rating : ratingsOfUser) { if (ratingsOfUserMap.containsKey(rating.getItem().getItem())) { if (logger.isWarnEnabled()) logger.warn("The user should have only voted once for the same item."); continue; } ratingsOfUserMap.put(rating.getItem().getItem(), rating); } return ratingsOfUserMap; } }
if (!rating.getItem().getTenant().equals(tenantId)) continue; if (!rating.getItem().getType().equals(itemTypeId)) continue; if (!rating.getItem().getItem().equals(item1Id) && !rating.getItem().getItem().equals(item2Id)) continue; if (rating.getItem().getItem().equals(item1Id)) { rating1 = rating; } else if (rating.getItem().getItem().equals(item2Id)) { rating2 = rating; rating1 = new RatingVO<Integer, Integer>(rating1.getItem(), rating1.getRatingValue(), rating1.getCount(), null, rating1.getUser(), null); rating2 = new RatingVO<Integer, Integer>(rating2.getItem(), rating2.getRatingValue(), rating2.getCount(), null, rating2.getUser(), null);
private double plainRecommendations(final RatingVO<Integer, Integer> rating, final List<Deviation> deviations) { double numerator = 0.0; long denominator = 0L; int itemId = rating.getItem().getItem(); for (Deviation deviation : deviations) { if (deviation.getItem2Id() == itemId) continue; numerator += deviation.getDeviation() * rating.getRatingValue(); denominator++; } return numerator / denominator; } }
continue; int item1 = rating1.getItem().getItem(); int item2 = rating2.getItem().getItem(); int item1TypeId = rating1.getItem().getType(); int item2TypeId = rating2.getItem().getType(); boolean swapped = false; deviation = new Deviation(rating1.getItem().getTenant(), item1, item1TypeId, item2, item2TypeId, 0.0, 0L); deviations.put(hashOfItems, deviation);
private double weightedRecommendations(final RatingVO<Integer, Integer> rating, final List<Deviation> deviations) { double numerator = 0.0; long denominator = 0L; int itemId = rating.getItem().getItem(); for (Deviation deviation : deviations) { if (deviation.getItem2Id() == itemId) continue; numerator += (deviation.getDeviation() * rating.getRatingValue()) * deviation.getDenominator(); denominator += deviation.getDenominator(); } return numerator / denominator; }
@SuppressWarnings({"UnusedDeclaration"}) public void personalizedRecommendations(TenantVO tenant, SlopeOneIntegerConfiguration config, SlopeOneStats stats, Date execution, Set<TenantItem> changedItemIds, boolean weighted, final ExecutionControl control) { List<Integer> userIds = actionDAO.getUsers(config.getTenant(), config.getItemTypes(), execution); final int TOTAL_STEPS = userIds.size(); int currentStep = 0; for (int userId : userIds) { if (control != null) control.updateProgress( String.format("Calculating personalized recommendations %d/%d", currentStep++, TOTAL_STEPS)); List<RatingVO<Integer, Integer>> ratings = actionDAO.getRatings( config.getTenant(), config.getItemTypes(), userId); for (RatingVO<Integer, Integer> rating : ratings) { int itemId = rating.getItem().getItem(); int itemTypeId = rating.getItem().getType(); if (!changedItemIds.contains(new TenantItem(itemId, itemTypeId))) continue; List<Deviation> deviations = deviationDAO.getDeviationsOrdered(config.getTenant(), itemTypeId, itemId, config.getMinRatedCount(), config.getMaxRecsPerItem()); double recommendation = weighted ? weightedRecommendations(rating, deviations) : plainRecommendations(rating, deviations); if (logger.isDebugEnabled()) logger.debug("created recommendation " + recommendation); // TODO write to database } } }
@Override public RatingVO<Integer, String> convertRatingVO(Integer tenantId, RatingVO<Integer, Integer> rating) { if (rating == null) { return null; } return new RatingVO<Integer, String>( convertItemVO(tenantId, rating.getItem()), rating.getRatingValue(), rating.getCount(), rating.getLastActionTime(), rating.getUser(), rating.getSessionId()); }
@Override public RatingVO<Integer, Integer> convertTypedRatingVO(Integer tenantId, RatingVO<Integer, String> typedRating) { if (typedRating == null) { return null; } return new RatingVO<Integer, Integer>( convertTypedItemVO(tenantId, typedRating.getItem()), typedRating.getRatingValue(), typedRating.getCount(), typedRating.getLastActionTime(), typedRating.getUser(), typedRating.getSessionId()); }