@Override public double userSimilarity(long userID1, long userID2) throws TasteException { FastIDSet prefs1 = dataModel.getItemIDsFromUser(userID1); FastIDSet prefs2 = dataModel.getItemIDsFromUser(userID2); int prefs1Size = prefs1.size(); int prefs2Size = prefs2.size(); int intersectionSize = prefs1Size < prefs2Size ? prefs2.intersectionSize(prefs1) : prefs1.intersectionSize(prefs2); if (intersectionSize == 0) { return Double.NaN; } // int numItems = dataModel.getNumItems(); // int numItems = Math.max(prefs1Size, prefs2Size); // int numItems = prefs1Size; // double distance1 = (double) (prefs1Size - intersectionSize)/(double) 2; // double distance2 = (double) (prefs2Size - intersectionSize)/(double) 2; // double distance = (distance1 + distance2); double distance = (double) (prefs1Size - intersectionSize); double similarity = 1.0 / (1.0 + distance); ////// System.out.println( prefs1Size + ", " + prefs2Size + ", " + intersectionSize + ", " + // similarity); return similarity; }
@Override public int getNumUsersWithPreferenceFor(long itemID1, long itemID2) { FastIDSet userIDs1 = preferenceForItems.get(itemID1); if (userIDs1 == null) { return 0; } FastIDSet userIDs2 = preferenceForItems.get(itemID2); if (userIDs2 == null) { return 0; } return userIDs1.size() < userIDs2.size() ? userIDs2.intersectionSize(userIDs1) : userIDs1.intersectionSize(userIDs2); }
@Test public void testStrategy() throws TasteException { FastIDSet itemIDsFromUser123 = new FastIDSet(); itemIDsFromUser123.add(1L); FastIDSet itemIDsFromUser456 = new FastIDSet(); itemIDsFromUser456.add(1L); itemIDsFromUser456.add(2L); List<Preference> prefs = new ArrayList<Preference>(); prefs.add(new GenericPreference(123L, 1L, 1.0f)); prefs.add(new GenericPreference(456L, 1L, 1.0f)); PreferenceArray preferencesForItem1 = new GenericItemPreferenceArray(prefs); DataModel dataModel = EasyMock.createMock(DataModel.class); EasyMock.expect(dataModel.getPreferencesForItem(1L)).andReturn(preferencesForItem1); EasyMock.expect(dataModel.getItemIDsFromUser(123L)).andReturn(itemIDsFromUser123); EasyMock.expect(dataModel.getItemIDsFromUser(456L)).andReturn(itemIDsFromUser456); PreferenceArray prefArrayOfUser123 = new GenericUserPreferenceArray(Arrays.asList(new GenericPreference(123L, 1L, 1.0f))); CandidateItemsStrategy strategy = new PreferredItemsNeighborhoodCandidateItemsStrategy(); EasyMock.replay(dataModel); FastIDSet candidateItems = strategy.getCandidateItems(123L, prefArrayOfUser123, dataModel); assertEquals(1, candidateItems.size()); assertTrue(candidateItems.contains(2L)); EasyMock.verify(dataModel); }
@Override public double userSimilarity(long userID1, long userID2) throws TasteException { FastIDSet prefs1 = dataModel.getItemIDsFromUser(userID1); FastIDSet prefs2 = dataModel.getItemIDsFromUser(userID2); int prefs1Size = prefs1.size(); int prefs2Size = prefs2.size(); int intersectionSize = prefs1Size < prefs2Size ? prefs2.intersectionSize(prefs1) : prefs1.intersectionSize(prefs2); if (intersectionSize == 0) { return Double.NaN; } int numItems = dataModel.getNumItems(); double logLikelihood = twoLogLambda( intersectionSize, prefs1Size - intersectionSize, prefs2Size, numItems - prefs2Size); return 1.0 - 1.0 / (1.0 + logLikelihood); }
@Override public double userSimilarity(long userID1, long userID2) throws TasteException { DataModel dataModel = getDataModel(); FastIDSet xPrefs = dataModel.getItemIDsFromUser(userID1); FastIDSet yPrefs = dataModel.getItemIDsFromUser(userID2); int xPrefsSize = xPrefs.size(); int yPrefsSize = yPrefs.size(); if (xPrefsSize == 0 && yPrefsSize == 0) { return Double.NaN; } if (xPrefsSize == 0 || yPrefsSize == 0) { return 0.0; } double intersection = 0.0; double union = 0.0; for (LongPrimitiveIterator it_item = xPrefs.iterator(); it_item.hasNext(); ) { long itemID = (long) it_item.nextLong(); double weight = (double) getDataModel().getNumUsers() / mItemPrefNum.get(itemID); if (yPrefs.contains(itemID)) { intersection += weight; union -= weight; } union += weight; } for (LongPrimitiveIterator it_item = yPrefs.iterator(); it_item.hasNext(); ) { long itemID = (long) it_item.nextLong(); double weight = (double) getDataModel().getNumUsers() / mItemPrefNum.get(itemID); union += weight; } return Math.log(intersection) / Math.log(union); }
@Override public PreferenceArray getPreferencesForItem(long itemID) throws NoSuchItemException { FastIDSet userIDs = preferenceForItems.get(itemID); if (userIDs == null) { throw new NoSuchItemException(itemID); } PreferenceArray prefArray = new BooleanItemPreferenceArray(userIDs.size()); int i = 0; LongPrimitiveIterator it = userIDs.iterator(); while (it.hasNext()) { prefArray.setUserID(i, it.nextLong()); prefArray.setItemID(i, itemID); i++; } return prefArray; }
@Override public int getNumUsersWithPreferenceFor(long itemID) { FastIDSet userIDs1 = preferenceForItems.get(itemID); return userIDs1 == null ? 0 : userIDs1.size(); }