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

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

The newest version!
/**
 * 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.BiMap; import com.google.common.collect.HashBiMap; import net.librec.common.LibrecException; import net.librec.math.algorithm.Randoms; import net.librec.math.structure.SequentialSparseVector; import net.librec.math.structure.Vector; import net.librec.recommender.MatrixRecommender; import net.librec.util.Lists; import net.librec.util.ZeroSetter; import java.util.Random; /** * This class implementing user-oriented Restricted Boltzmann Machines for * Collaborative Filtering *

* The origin paper: *

* Salakhutdinov, R., Mnih, A. Hinton, G, Restricted BoltzmanMachines for * Collaborative Filtering, To appear inProceedings of the 24thInternational * Conference onMachine Learning 2007. * http://www.cs.toronto.edu/~rsalakhu/papers/rbmcf.pdf * * @author bin wu(Email:[email protected]) */ public class RBMRecommender extends MatrixRecommender { int featureNumber; int softmax; int maxIter; int tSteps; double epsilonw; double epsilonvb; double epsilonhb; double momentum; double lamtaw; double lamtab; double[][][] weights; double[][] visbiases; double[] hidbiases; double[][][] cDpos; double[][][] cDneg; double[][][] cDinc; double[] poshidact; double[] neghidact; char[] poshidstates; char[] neghidstates; double[] hidbiasinc; char[] curposhidstates; double[][] posvisact; double[][] negvisact; double[][] visbiasinc; double[][] negvisprobs; int[] negvissoftmax; int[] moviecount; String predictionType; BiMap ratingToIndex = HashBiMap.create(); BiMap indexToRating = HashBiMap.create(); public RBMRecommender() { } protected void setup() throws LibrecException { super.setup(); softmax = ratingScale.size(); for (int i=0; i Randoms.random()) { poshidstates[h] = 1; poshidact[h] += 1.0; } else { poshidstates[h] = 0; } } for (int h = 0; h < featureNumber; h++) { curposhidstates[h] = poshidstates[h]; } int stepT = 0; do { boolean finalTStep = (stepT + 1 >= tSteps); for (Vector.VectorEntry ve : userVec) { int m = ve.index(); for (int h = 0; h < featureNumber; h++) { if (curposhidstates[h] == 1) { for (int r = 0; r < softmax; r++) negvisprobs[m][r] += weights[m][r][h]; } } for (int r = 0; r < softmax; r++) negvisprobs[m][r] = 1. / (1 + Math.exp(-negvisprobs[m][r] - visbiases[m][r])); double tsum = 0; for (int r = 0; r < softmax; r++) { tsum += negvisprobs[m][r]; } if (tsum != 0) { for (int r = 0; r < softmax; r++) { negvisprobs[m][r] /= tsum; } } double randval = Randoms.random(); for (int ratingIndex=0; ratingIndex Randoms.random()) { neghidstates[h] = 1; if (finalTStep) neghidact[h] += 1.0; } else { neghidstates[h] = 0; } } if (!finalTStep) { for (int h = 0; h < featureNumber; h++) curposhidstates[h] = neghidstates[h]; ZeroSetter.zero(negvisprobs, numItems, softmax); } } while (++stepT < tSteps); for (Vector.VectorEntry ve : userVec) { int m = ve.index(); int r = ratingToIndex.get(ve.get()); for (int h = 0; h < featureNumber; h++) { if (poshidstates[h] == 1) { cDpos[m][r][h] += 1.0; } cDneg[m][negvissoftmax[m]][h] += (double) neghidstates[h]; } } update(u, num); } } } private void update(int user, int num) { int bSize = 100; if (((user + 1) % bSize) == 0 || (user + 1) == numUsers) { int numcases = user % bSize; numcases++; for (int m = 0; m < numItems; m++) { if (moviecount[m] == 0) continue; for (int h = 0; h < featureNumber; h++) { for (int r = 0; r < softmax; r++) { double CDp = cDpos[m][r][h]; double CDn = cDneg[m][r][h]; if (CDp != 0.0 || CDn != 0.0) { CDp /= ((double) moviecount[m]); CDn /= ((double) moviecount[m]); cDinc[m][r][h] = momentum * cDinc[m][r][h] + epsilonw * ((CDp - CDn) - lamtaw * weights[m][r][h]); weights[m][r][h] += cDinc[m][r][h]; } } } for (int r = 0; r < softmax; r++) { if (posvisact[m][r] != 0.0 || negvisact[m][r] != 0.0) { posvisact[m][r] /= ((double) moviecount[m]); negvisact[m][r] /= ((double) moviecount[m]); visbiasinc[m][r] = momentum * visbiasinc[m][r] + epsilonvb * (posvisact[m][r] - negvisact[m][r] - lamtab * visbiases[m][r]); visbiases[m][r] += visbiasinc[m][r]; } } } for (int h = 0; h < featureNumber; h++) { if (poshidact[h] != 0.0 || neghidact[h] != 0.0) { poshidact[h] /= ((double) (numcases)); neghidact[h] /= ((double) (numcases)); hidbiasinc[h] = momentum * hidbiasinc[h] + epsilonhb * (poshidact[h] - neghidact[h] - lamtab * hidbiases[h]); hidbiases[h] += hidbiasinc[h]; } } Zero(); } } private void Zero() { cDpos = new double[numItems][softmax][featureNumber]; cDneg = new double[numItems][softmax][featureNumber]; poshidact = new double[featureNumber]; neghidact = new double[featureNumber]; posvisact = new double[numItems][softmax]; negvisact = new double[numItems][softmax]; moviecount = new int[numItems]; } protected double predict(int u, int m) throws LibrecException { double[] scoreProbs = new double[softmax]; double[] factorProbs = new double[featureNumber]; SequentialSparseVector userVec = trainMatrix.row(u); double[] sumW = new double[featureNumber]; for (Vector.VectorEntry ve : userVec) { int item = ve.index(); int rateIdx = ratingToIndex.get(ve.get()); for (int h = 0; h < featureNumber; h++) { sumW[h] += weights[item][rateIdx][h]; } } for (int h = 0; h < featureNumber; h++) { factorProbs[h] = 1.0 / (1.0 + Math.exp(0 - sumW[h] - hidbiases[h])); } for (int h = 0; h < featureNumber; h++) { for (int r = 0; r < softmax; r++) { scoreProbs[r] += factorProbs[h] * weights[m][r][h]; } } double probSum = 0.0; for (int r = 0; r < softmax; r++) { scoreProbs[r] = 1.0 / (1.0 + Math.exp(0 - scoreProbs[r] - visbiases[m][r])); probSum += scoreProbs[r]; } for (int r=0; r max_value) { max_index = r; } } predict = indexToRating.get(max_index); } else if (predictionType.equals("mean")) { double mean = 0.0; for (int r = 0; r < softmax; r++) { mean += scoreProbs[r] * indexToRating.get(r); } predict = mean; } return predict; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy