mahout-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Johan Fredholm <johan.fredh...@gmail.com>
Subject Re: Mahout and DAO connection
Date Fri, 27 Nov 2009 01:19:04 GMT
Ok, sorry for being unclear.
I wrote at the end there in mail 1 "Running recommendations from
Account (User) doesn't return any
recommendations at all.". That's the userbased recommender. It didn't
throw any exceptions like the item-based recommender, but it also
didn't (and doesn't) return anything. I did flip the values in the
DataModel for the item-based recommender like you suggested, and it
now works. The DataModel for the user-based recommender is unchanged.
So in total for the user-based recommender the code now is:

The DataModel.
--------------------

public class WorkDataModel implements DataModel {

	org.apache.mahout.cf.taste.model.DataModel delegate;

	public WorkDataModel(ArrangementDAO arrangementDAO,
			ReviewDAO reviewDAO, List<Arrangement> arrangements) {
		super();
		this.arrangementDAO = arrangementDAO;
		this.reviewDAO = reviewDAO;
		this.arrangements = arrangements;
		refresh();

		FastByIDMap<PreferenceArray> users = readUsers();
		delegate = new GenericDataModel(users);
	}

	private FastByIDMap<PreferenceArray> readUsers() {
		FastByIDMap<Collection<Preference>> userIDPrefMap = new
FastByIDMap<Collection<Preference>>();

		for (Review r : reviews) {

			Collection<Preference> userPrefs =
userIDPrefMap.get(r.getReviewer().getId());
			if (userPrefs == null) {
				userPrefs = new ArrayList<Preference>(2);
				userIDPrefMap.put(r.getReviewer().getId(), userPrefs);
			}
			userPrefs.add(new GenericPreference(
					r.getReviewer().getId(),
					r.getArrangement().getId(),
					r.getValue()));
		}

		return GenericDataModel.toDataMap(userIDPrefMap, true);
	}


	@Override
	public LongPrimitiveIterator getUserIDs() throws TasteException {
		LongPrimitiveIterator userIDs = delegate.getUserIDs();
		return userIDs;
	}

	@Override
	public PreferenceArray getPreferencesFromUser(long id) throws TasteException {
		PreferenceArray preferencesFromUser = delegate.getPreferencesFromUser(id);
		return preferencesFromUser;
	}

	@Override
	public FastIDSet getItemIDsFromUser(long userID) throws TasteException {
		FastIDSet itemIDsFromUser = delegate.getItemIDsFromUser(userID);
		return itemIDsFromUser;
	}

	@Override
	public LongPrimitiveIterator getItemIDs() throws TasteException {
		LongPrimitiveIterator itemIDs = delegate.getItemIDs();
		return itemIDs;
	}

	@Override
	public PreferenceArray getPreferencesForItem(long itemID)
			throws TasteException {
		PreferenceArray preferencesForItem = delegate.getPreferencesForItem(itemID);
		return preferencesForItem;
	}

	@Override
	public Float getPreferenceValue(long userID, long itemID)
			throws TasteException {
		Float preferenceValue = delegate.getPreferenceValue(userID, itemID);
		return preferenceValue;
	}

	@Override
	public int getNumItems() throws TasteException {
		int numItems = delegate.getNumItems();
		return numItems;
	}

	@Override
	public int getNumUsers() throws TasteException {
		int numUsers = delegate.getNumUsers();
		return numUsers;
	}

	@Override
	public int getNumUsersWithPreferenceFor(long... itemIDs)
			throws TasteException {
		int numUsersWithPreferenceFor =
delegate.getNumUsersWithPreferenceFor(itemIDs);
		return numUsersWithPreferenceFor;
	}

	@Override
	public void setPreference(long userID, long itemID, float value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void removePreference(long userID, long itemID) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void refresh(Collection<Refreshable> alreadyRefreshed) {
		// do nothing
	}

	private ReviewDAO reviewDAO;

	private ArrangementDAO arrangementDAO;

	private List<Arrangement> arrangements;

	private List<Review> reviews;

	public void refresh() {

		if (arrangements == null) {
			arrangements = arrangementDAO.getAll();
		}
		reviews = reviewDAO.getAll();
	}

}
--------------
I have debugged it and the WorkDataModel seems to return valid data.
The call and the test code is in my last mail. I removed the
AveragingPreferenceInferrer, but it didnt change that I get no results
back.
I hope that's clearer.

Thank you!
Johan




On Fri, Nov 27, 2009 at 1:57 AM, Sean Owen <srowen@gmail.com> wrote:
> I'm not clear what you mean. There are user-based and item-based
> recommenders. Both recommend items to users. You had expressed
> interest in recommending users to items. That could be done with a
> user-based or item-based recommender, by flipping user and item IDs.
>
> Which one(s) are and aren't working exactly? You show a user-based
> recommender below, but can't tell whether you mean this works or
> doesn't.
>
> Also I am not sure what's going on in WorkDataModel. Have you
> 'flipped' user and item IDs there or no?
>
> Last you say you are trying to recommend items to users, and that's an
> issue, but I thought you had that working.
>
> Back up a bit and clarify what the situation is.
>
> (PS I wouldn't use a preference inferrer unless you know for sure it's
> beneficial. It usually isn't.)
>
> On Fri, Nov 27, 2009 at 12:51 AM, Johan Fredholm
> <johan.fredholm@gmail.com> wrote:
>> Thanks for the help.
>> I got the recommender based on items to work, but I cant seem to get
>> the recommender based on users to work.
>> I don't get any errors, I just don't get any results.
>>
>> My call>
>> -----------------
>> WorkDataModel model = new WorkDataModel(accountDAO, arrangementDAO,
>> reviewDAO, arrangements);
>> UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(model);
>> userSimilarity.setPreferenceInferrer(new AveragingPreferenceInferrer(model));
>> NearestNUserNeighborhood  neighborhood =  new NearestNUserNeighborhood
>> (3, userSimilarity, model);
>> GenericUserBasedRecommender recommender = new
>> GenericUserBasedRecommender(model, neighborhood, userSimilarity);
>> List<RecommendedItem> recommendations =
>> recommender.recommend(account.getId(), amount);
>> ------------------
>>
>> It looks like WorkDataModel returns everything correctly.
>> This is my test:
>>
>> ------------------
>> List<Arrangement> allReady = arrangementDAO.getAllReady();
>>
>> Account ac1 = accountDAO.get(22L);
>> Account ac2 = accountDAO.get(21L);
>> Account ac3 = accountDAO.get(23L);
>>
>> int i = 0;
>> Arrangement aSearch = null;
>>
>> for (Arrangement a : allReady) {
>>
>>        if (i < 8) {
>>                reviewDAO.save(new Review(a, ac1, 4F, Reviewtype.HUMAN));
>>        }
>>        if (i > 3) {
>>                reviewDAO.save(new Review(a, ac2, 2F, Reviewtype.HUMAN));
>>        }
>>        if (i > 6 && i < 16) {
>>                reviewDAO.save(new Review(a, ac3, 5F, Reviewtype.HUMAN));
>>        }
>>
>>        if (i == 5) {
>>                aSearch = a;
>>        }
>>
>>        if (i > 15) {
>>                break;
>>        }
>>
>>        i++;
>> }
>>
>> List<Arrangement> recommendations =
>> arrangementService.getRecommendations(ac1, allReady, 10);
>> -------------------
>>
>> I'm not really sure what I am sending in there, I'm just trying to mix
>> it up a bit :-)
>> I have tried to get recommendations from for all three of the accounts
>> (users), but I don't get anything.
>> Do I need more preferences, or is something else wrong?? The
>> preferences are not overlapping, so shouldn't I get some kind of
>> result back?
>>
>> Thanks!
>> Johan
>>
>>
>> On Thu, Nov 26, 2009 at 12:02 PM, Sean Owen <srowen@gmail.com> wrote:
>>> Yes everything looks fine here, but with one key issue.
>>> It seems you are trying to recommender "users" to "items" in the
>>> second case. That is not what an item-based recommender does -- it
>>> still recommenders items to users.
>>>
>>> To do what you want, you need to transpose user and item IDs in your
>>> DataModel, then use any algorithm you like. It's a two-line change to
>>> the line where you make a GenericPreference. Maybe create a flag in
>>> the constructor that controls this so you can reuse the model in both
>>> cases.
>>>
>>> It does mean you need a separate model, yes.
>>>
>>> PS I think your model-building will use a lot of memory at peak --
>>> that map of Collection<Preference> will be a lot bigger than the final
>>> data set. You can instead build PreferenceArray directly, note.
>>>
>>> On Thu, Nov 26, 2009 at 9:38 AM, Johan Fredholm
>>> <johan.fredholm@gmail.com> wrote:
>>>> Hi,
>>>> I have been trying to configure Mahout for using hibernate. I haven't
>>>> been able to find any examples of such a configuration. Its probably
>>>> the wrong way to do it but I cant even get this simple model to work.
>>>> It would be great if you could tell me what I'm doing wrong here, and
>>>> maybe some pointers on how it should be done.
>>>>
>>>
>>
>

Mime
View raw message