All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.librec.recommender.cf.rating.BPoissMFRecommender Maven / Gradle / Ivy

/**
 * Copyright (C) 2016 LibRec
 * 

* This file is part of LibRec. * LibRec 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. *

* LibRec 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 LibRec. If not, see . */ package net.librec.recommender.cf.rating; import com.google.common.collect.Table; import net.librec.common.LibrecException; import net.librec.math.algorithm.Gamma; import net.librec.math.algorithm.Randoms; import net.librec.math.structure.DenseMatrix; import net.librec.math.structure.DenseVector; import net.librec.math.structure.MatrixEntry; import net.librec.recommender.MatrixFactorizationRecommender; import java.util.Map; /** * Prem Gopalan, et al. Scalable Recommendation with Poisson Factorization.
* * @author Haidong Zhang */ public class BPoissMFRecommender extends MatrixFactorizationRecommender { // The parameters of users private GammaDenseMatrix userTheta; private GammaDenseVector userThetaRate; // The parameters of items private GammaDenseMatrix itemBeta; private GammaDenseVector itemBetaRate; // The parameters of topics; private Table> zTopic; @Override protected void setup() throws LibrecException { super.setup(); userThetaRate = new GammaDenseVector(numFactors); itemBetaRate = new GammaDenseVector(numFactors); userTheta = new GammaDenseMatrix(numUsers, numFactors); itemBeta = new GammaDenseMatrix(numItems, numFactors); userThetaRate.shapePrior = conf.getDouble("rec.recommender.user.rateShapePrior", 0.1); userThetaRate.ratePrior = conf.getDouble("rec.recommender.user.rateRatePrior", 0.1); userThetaRate.init2(numFactors); userThetaRate.computeExpectations(); itemBetaRate.shapePrior = conf.getDouble("rec.recommender.item.rateShapePrior", 0.1); itemBetaRate.ratePrior = conf.getDouble("rec.recommender.item.rateRatePrior", 0.1); itemBetaRate.init2(numFactors); itemBetaRate.computeExpectations(); userTheta.shapePrior = conf.getDouble("rec.recommender.user.shapePrior", 0.1); userTheta.ratePrior = conf.getDouble("rec.recommender.user.ratePrior", 0.1); userTheta.init(); itemBeta.shapePrior = conf.getDouble("rec.recommender.item.shapePrior", 0.1); itemBeta.ratePrior = conf.getDouble("rec.recommender.item.ratePrior", 0.1); itemBeta.init(); } protected DenseVector getPhi(DenseMatrix Theta, int indexTheta, DenseMatrix Beta, int indexBeta, int number) throws LibrecException { //get_phi(_htheta, n, _hbeta, m, phi); DenseVector phi = new DenseVector(number); phi.setAll(0.0); assert (Theta.numColumns == Beta.numColumns); for (int i = 0; i < Theta.numColumns; i++) { phi.add(Math.log(Beta.get(indexBeta, i)) + Theta.get(indexTheta, i)); } phi = phi.scale(1.0 / phi.sum()); for (int i = 0; i < Theta.numColumns; i++) { phi.set(i, Math.log(phi.get(i))); } return phi; } @Override protected void trainModel() throws LibrecException { DenseVector phi; double[] loglikelihood = new double[numIterations]; for (int iter = 1; iter <= numIterations; iter++) { for (MatrixEntry matrixEntry : trainMatrix) { int user_id = matrixEntry.row(); int item_id = matrixEntry.column(); double rating = matrixEntry.get(); phi = getPhi(userTheta.logValue, user_id, itemBeta.value, item_id, numFactors); if (rating > 1) { phi.scale(rating); } } } } @Override protected double predict(int userIdx, int itemIdx) throws LibrecException { return DenseMatrix.rowMult(userTheta.value, userIdx, itemBeta.value, itemIdx); } public class GammaDenseVector { protected int size; protected double shapePrior, ratePrior; protected DenseVector shape, rate; protected DenseVector value, logValue; public GammaDenseVector(int _size) { size = _size; shape = new DenseVector(size); rate = new DenseVector(size); value = new DenseVector(size); logValue = new DenseVector(size); } public void init() { for (int i = 0; i < size; i++) { shape.set(i, shapePrior + 0.01 * Randoms.uniform(0.0, 1.0)); rate.set(i, ratePrior + 0.1 * Randoms.uniform(0.0, 1.0)); } } public void init2(double v) { for (int i = 0; i < size; i++) { shape.set(i, shapePrior + 0.01 * Randoms.uniform(0.0, 1.0)); rate.set(i, ratePrior + v); } } public void computeExpectations() { double a = 0.0, b = 0.0; for (int i = 0; i < size; i++) { if (shape.get(i) <= 0.0) { a = 1e-30; } if (rate.get(i) <= 0.0) { b = 1e-30; } 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) { 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++) { if (shape.get(i, j) <= 0) { a = 1e-30; } if (rate.get(i, j) <= 0) { b = 1e-30; } 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) { numRows = _numRows; numColumns = _numColumns; shape = new DenseMatrix(numRows, numColumns); rate = new DenseVector(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++) { if (shape.get(i, j) <= 0) { a = 1e-30; } if (rate.get(j) <= 0) { b = 1e-30; } value.set(i, j, a / b); logValue.set(i, j, Gamma.digamma(a) - Math.log(b)); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy