// Copyright (C) 2011 Zeno Gantner, Chris Newell
//
// This file is part of MyMediaLite.
//
// MyMediaLite is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MyMediaLite is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MyMediaLite. If not, see <http://www.gnu.org/licenses/>.
package org.mymedialite.itemrec;
/**
* Weighted BPR-MF with frequency-adjusted sampling.
*
* Literature:
* Zeno Gantner, Lucas Drumond, Christoph Freudenthaler, Lars Schmidt-Thieme:
* Bayesian Personalized Ranking for Non-Uniformly Sampled Items.
* KDD Cup Workshop 2011
*
* @version 2.03
*/
public class WeightedBPRMF extends BPRMF {
// TODO offer this data structure from Feedback
/**
* array of user IDs of positive user-item pairs.
*/
protected int[] users;
/**
* array of item IDs of positive user-item pairs.
*/
protected int[] items;
/**
* Default constructor.
*/
public WeightedBPRMF() { }
/**
*/
public void train() {
// Deactivate until supported
withReplacement = false;
// Deactivate until false is supported
uniformUserSampling = true;
// prepare helper data structures for training
users = new int[feedback.size()];
items = new int[feedback.size()];
int index = 0;
for (int user_id : feedback.userMatrix().nonEmptyRowIDs())
for (int item_id : feedback.userMatrix().get(user_id)) {
users[index] = user_id;
items[index] = item_id;
index++;
}
// Suppress using user_neg_items in BPRMF
fastSamplingMemoryLimit = 0;
super.train();
}
/**
*
*/
protected void sampleTriple(SampleTriple t) {
// ample user from positive user-item pairs
int index = random.nextInt(items.length - 1);
t.u = users[index];
t.i = items[index];
// Sample negative item
do
t.j = items[random.nextInt(items.length - 1)];
while (feedback.userMatrix().get(t.u, t.j));
}
/**
*
*/
public String toString() {
return
this.getClass().getName()
+ " numFactors=" + numFactors
+ " biasReg=" + biasReg
+ " regU=" + regU
+ " regI=" + regI
+ " regJ=" + regJ
+ " numIter=" + numIter
+ " learnRate=" + learnRate
+ " boldDriver=" + boldDriver
+ " initMean=" + initMean
+ " initStdev=" + initStDev ;
}
private class SampleTriple {
int u; // user_id
int i; // item_id positive item
int j; // item_id negative item
}
}