net.librec.recommender.cf.ranking.BNPPFRecommeder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of librec-core Show documentation
Show all versions of librec-core Show documentation
A repackaged librec-core fork
The newest version!
package net.librec.recommender.cf.ranking;
import net.librec.common.LibrecException;
import net.librec.math.algorithm.Gamma;
import net.librec.math.algorithm.Randoms;
import net.librec.math.structure.*;
import net.librec.recommender.MatrixFactorizationRecommender;
/**
* Gopalan, P., Ruiz, F. J., Ranganath, R., & Blei, D. M.
* Bayesian Nonparametric Poisson Factorization for Recommendation Systems, ICAIS 2014
*
* @author Yatong Sun
*/
public class BNPPFRecommeder extends MatrixFactorizationRecommender {
/** user Gamma shape */
private double alpha;
/** user Gamma rate */
private double c;
/** item Gamma shape */
private double a;
/** item Gamma rate */
private double b;
/** variational sticks */
private DenseMatrix v;
private DenseMatrix pi;
private DenseMatrix logpi;
private GammaDenseMatrixGR beta;
private GammaDenseVector s;
private DenseVector eBetaSum;
private DenseVector eThetaSum;
private DenseMatrix zUsers;
private DenseMatrix zItems;
private DenseVector userBudget;
double d_scalar;
@Override
protected void setup() throws LibrecException {
super.setup();
alpha = conf.getDouble("rec.alpha", 0.3);
c = conf.getDouble("rec.c", 0.3);
a = conf.getDouble("rec.a", 0.3);
b = conf.getDouble("rec.b", 0.3);
//_beta.initialize();
beta = new GammaDenseMatrixGR(numItems, numFactors, a, b);
beta.init();
//_s.initialize();
s = new GammaDenseVector(numUsers, alpha, c);
s.init();
//initialize_sticks();
v = new DenseMatrix(numUsers, numFactors);
v.init(0.001);
//compute_pi();
pi = new DenseMatrix(numUsers, numFactors);
logpi = new DenseMatrix(numUsers, numFactors);
for (int u=0; u 0) {
lw += Math.log(1-v.get(u, k-1));
}
logpi.set(u, k, Math.log(v_value) + lw);
double pi_value = Math.exp(v_value);
pi.set(u, k, pi_value);
userFactors.set(u, k, pi_value * s.value.get(u));
}
}
eBetaSum = new VectorBasedDenseVector(numFactors);
eThetaSum = new VectorBasedDenseVector(numFactors);
zUsers = new DenseMatrix(numUsers, numFactors);
zItems = new DenseMatrix(numItems, numFactors);
userBudget = new VectorBasedDenseVector(numUsers);
for (int u=0; u1) {
phi.times(y);
}
zUsers.set(u, zUsers.row(u).plus(phi));
zItems.set(itemIdx, zItems.row(itemIdx).plus(phi));
}
}
updateSticks();
update_sticks_scalar();
updateItems();
}
itemFactors = new DenseMatrix(beta.value);
}
private void computeExpectations() {
s.computeExpectations();
beta.computeExpectations();
}
private void commputeSums() {
computeEThetaSum();
computeEBetaSum();
}
private void computeEThetaSum() {
for (int k=0; k 0) {
pi.set(u, k, pi.get(u, k-1) / v.get(u, k-1) * (1-v.get(u, k-1)) * v_value);
} else {
pi.set(u, k, v_value);
}
logpi.set(u, k, Math.log(pi.get(u, k)));
userFactors.set(u, k, pi.get(u, k) * s.value.get(u));
}
}
}
private double[] sum_of_prod_in_range(int u, int K) {
double sum = 0.0;
double p = convert_oldpi_to_new(u, K-1);
for (int k=K; k .0 && s1 <= 1.0 && s2 > .0 && s2 <= 1.0) {
if (s1 < s2)
return s1 + 1e-30;
else
return s2 + 1e-30;
}
if (s1 > .0 && s1 <= 1.0)
return s1;
if (s2 > .0 && s2 <= 1.0)
return s2;
// TODO
if (Math.abs(s1 - .0) < 1e-30)
return 1e-30;
if (Math.abs(s1 - 1.0) < 1e-30)
return 1 - 1e-30;
if (Math.abs(s2 - .0) < 1e-30)
return 1e-30;
if (Math.abs(s2 - 1.0) < 1e-30)
return 1 - 1e-30;
return s1;
}
private void update_sticks_scalar() {
for (int u=0; u= 0 && bv >= 0);
if (av <= 0) {
a = 1e-30;
} else {
a = av;
}
if (bv <= 0) {
b = 1e-30;
} else {
b = bv;
}
value.set(i, a / b);
logValue.set(i, Gamma.digamma(a) - Math.log(b));
}
}
}
public class GammaDenseMatrix {
protected int numRows, numColumns;
protected double shapePrior;
protected double ratePrior;
protected DenseMatrix shape;
protected DenseMatrix rate;
protected DenseMatrix value;
protected DenseMatrix logValue;
public GammaDenseMatrix(int _numRows, int _numColumns, double shapeP, double rateP) {
shapePrior = shapeP;
ratePrior = rateP;
numRows = _numRows;
numColumns = _numColumns;
shape = new DenseMatrix(numRows, numColumns);
rate = new DenseMatrix(numRows, numColumns);
value = new DenseMatrix(numRows, numColumns);
logValue = new DenseMatrix(numRows, numColumns);
}
public void init() {
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
shape.set(i, j, shapePrior + 0.01 * Randoms.uniform(0.0, 1.0));
if (i == 0) {
rate.set(0, j, ratePrior + 0.1 * Randoms.uniform(0.0, 1.0));
} else {
rate.set(i, j, rate.get(0, j));
}
}
}
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
value.set(i, j, shape.get(i, j) / rate.get(i, j));
logValue.set(i, j, Gamma.digamma(shape.get(i, j)) - Math.log(rate.get(i, j)));
}
}
}
public void computeExpectations() {
double a = 0.0, b = 0.0;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
double av = shape.get(i, j);
double bv = rate.get(i, j);
// assert (av >= 0 && bv >= 0);
if (av <= 0) {
a = 1e-30;
} else {
a = av;
}
if (bv <= 0) {
b = 1e-30;
} else {
b = bv;
}
value.set(i, j, a / b);
logValue.set(i, j, Gamma.digamma(a) - Math.log(b));
}
}
}
}
public class GammaDenseMatrixGR {
protected int numRows, numColumns;
protected double shapePrior;
protected double ratePrior;
protected DenseMatrix shape;
protected DenseVector rate;
protected DenseMatrix value;
protected DenseMatrix logValue;
public GammaDenseMatrixGR(int _numRows, int _numColumns, double shapeP, double rateP) {
shapePrior = shapeP;
ratePrior = rateP;
numRows = _numRows;
numColumns = _numColumns;
shape = new DenseMatrix(numRows, numColumns);
rate = new VectorBasedDenseVector(numColumns);
value = new DenseMatrix(numRows, numColumns);
logValue = new DenseMatrix(numRows, numColumns);
}
public void init() {
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
shape.set(i, j, shapePrior + 0.01 * Randoms.uniform(0.0, 1.0));
}
}
for (int j = 0; j < numColumns; j++) {
rate.set(j, ratePrior + 0.1 * Randoms.uniform(0.0, 1.0));
}
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
value.set(i, j, shape.get(i, j) / rate.get(j));
logValue.set(i, j, Gamma.digamma(shape.get(i, j)) - Math.log(rate.get(j)));
}
}
}
public void computeExpectations() {
double a = 0.0, b = 0.0;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
double av = shape.get(i, j);
double bv = rate.get(j);
// assert (av >= 0 && bv >= 0);
if (av <= 0) {
a = 1e-30;
} else {
a = av;
}
if (bv <= 0) {
b = 1e-30;
} else {
b = bv;
}
value.set(i, j, a / b);
logValue.set(i, j, Gamma.digamma(a) - Math.log(b));
}
}
}
}
}