List of usage examples for org.apache.commons.math3.linear RealVector getEntry
public abstract double getEntry(int index) throws OutOfRangeException;
From source file:org.lenskit.mf.funksvd.FunkSVDItemScorer.java
@Override protected double computeScore(double bias, @Nonnull RealVector user, @Nonnull RealVector item) { if (domain == null) { return super.computeScore(bias, user, item); } else {/*from ww w.j ava 2 s . co m*/ double result = bias; int n = user.getDimension(); for (int i = 0; i < n; i++) { result = domain.clampValue(result + user.getEntry(i) * item.getEntry(i)); } return result; } }
From source file:org.lenskit.mf.funksvd.FunkSVDModelBuilder.java
/** * Do a single feature iteration.// www . j a v a2 s . c o m * * * * @param estimates The estimates. * @param ratings The ratings to train on. * @param userFeatureVector The user column vector for the current feature. * @param itemFeatureVector The item column vector for the current feature. * @param trail The sum of the remaining user-item-feature values. * @return The RMSE of the feature iteration. */ protected double doFeatureIteration(TrainingEstimator estimates, List<RatingMatrixEntry> ratings, RealVector userFeatureVector, RealVector itemFeatureVector, double trail) { // We'll create a fresh updater for each feature iteration // Not much overhead, and prevents needing another parameter FunkSVDUpdater updater = rule.createUpdater(); for (RatingMatrixEntry r : ratings) { final int uidx = r.getUserIndex(); final int iidx = r.getItemIndex(); updater.prepare(0, r.getValue(), estimates.get(r), userFeatureVector.getEntry(uidx), itemFeatureVector.getEntry(iidx), trail); // Step 3: Update feature values userFeatureVector.addToEntry(uidx, updater.getUserFeatureUpdate()); itemFeatureVector.addToEntry(iidx, updater.getItemFeatureUpdate()); } return updater.getRMSE(); }
From source file:org.lenskit.mf.funksvd.FunkSVDModelProvider.java
/** * Do a single feature iteration.//from w ww . ja v a 2 s .co m * * * * @param estimates The estimates. * @param ratings The ratings to train on. * @param userFeatureVector The user column vector for the current feature. * @param itemFeatureVector The item column vector for the current feature. * @param trail The sum of the remaining user-item-feature values. * @return The RMSE of the feature iteration. */ protected double doFeatureIteration(TrainingEstimator estimates, List<RatingMatrixEntry> ratings, RealVector userFeatureVector, RealVector itemFeatureVector, double trail) { // We'll create a fresh updater for each feature iteration // Not much overhead, and prevents needing another parameter FunkSVDTrainingUpdater updater = rule.createUpdater(); double acc_ud = 0; double acc_id = 0; for (RatingMatrixEntry r : ratings) { final int uidx = r.getUserIndex(); final int iidx = r.getItemIndex(); updater.prepare(0, r.getValue(), estimates.get(r), userFeatureVector.getEntry(uidx), itemFeatureVector.getEntry(iidx), trail); // Step 3: Update feature values double ud = updater.getUserFeatureUpdate(); acc_ud += ud * ud; userFeatureVector.addToEntry(uidx, ud); double id = updater.getItemFeatureUpdate(); acc_id += id * id; itemFeatureVector.addToEntry(iidx, id); } logger.trace("finished iteration with |du|={}, |di|={}", Math.sqrt(acc_ud), Math.sqrt(acc_id)); return updater.getRMSE(); }
From source file:org.lenskit.mf.funksvd.TrainingEstimator.java
/** * Update the current estimates with trained values for a new feature. * @param ufvs The user feature values./* ww w . j a v a 2 s . c o m*/ * @param ifvs The item feature values. */ public void update(RealVector ufvs, RealVector ifvs) { for (RatingMatrixEntry r : ratings) { int idx = r.getIndex(); double est = estimates[idx]; est += ufvs.getEntry(r.getUserIndex()) * ifvs.getEntry(r.getItemIndex()); if (domain != null) { est = domain.clampValue(est); } estimates[idx] = est; } }
From source file:org.lenskit.mf.svd.DomainClampingKernel.java
@Override public double apply(double bias, @Nonnull RealVector user, @Nonnull RealVector item) { final int n = user.getDimension(); Preconditions.checkArgument(item.getDimension() == n, "vectors have different lengths"); double result = bias; for (int i = 0; i < n; i++) { result = domain.clampValue(result + user.getEntry(i) * item.getEntry(i)); }/*from w ww . j ava 2 s . co m*/ return result; }
From source file:org.lenskit.pf.HPFModelProvider.java
@Override public HPFModel get() { final int userNum = ratings.getUserIndex().size(); final int itemNum = ratings.getItemIndex().size(); final int featureCount = hyperParameters.getFeatureCount(); final double a = hyperParameters.getUserWeightShpPrior(); final double aPrime = hyperParameters.getUserActivityShpPrior(); final double bPrime = hyperParameters.getUserActivityPriorMean(); final double c = hyperParameters.getItemWeightShpPrior(); final double cPrime = hyperParameters.getItemActivityShpPrior(); final double dPrime = hyperParameters.getItemActivityPriorMean(); final double kappaShpU = aPrime + featureCount * a; final double tauShpI = cPrime + featureCount * c; RealMatrix gammaShp = MatrixUtils.createRealMatrix(userNum, featureCount); RealMatrix gammaRte = MatrixUtils.createRealMatrix(userNum, featureCount); RealVector kappaShp = MatrixUtils.createRealVector(new double[userNum]); RealVector kappaRte = MatrixUtils.createRealVector(new double[userNum]); RealMatrix lambdaShp = MatrixUtils.createRealMatrix(itemNum, featureCount); RealMatrix lambdaRte = MatrixUtils.createRealMatrix(itemNum, featureCount); RealVector tauShp = MatrixUtils.createRealVector(new double[itemNum]); RealVector tauRte = MatrixUtils.createRealVector(new double[itemNum]); RealMatrix gammaShpNext = MatrixUtils.createRealMatrix(userNum, featureCount); RealMatrix lambdaShpNext = MatrixUtils.createRealMatrix(itemNum, featureCount); gammaShpNext = gammaShpNext.scalarAdd(a); lambdaShpNext = lambdaShpNext.scalarAdd(c); RealVector phiUI = MatrixUtils.createRealVector(new double[featureCount]); initialize(gammaShp, gammaRte, kappaRte, kappaShp, lambdaShp, lambdaRte, tauRte, tauShp); logger.info("initialization finished"); final List<RatingMatrixEntry> train = ratings.getTrainRatings(); final List<RatingMatrixEntry> validation = ratings.getValidationRatings(); double avgPLLPre = Double.MAX_VALUE; double avgPLLCurr = 0.0; double diffPLL = 1.0; int iterCount = 1; while (iterCount < maxIterCount && diffPLL > threshold) { // update phi Iterator<RatingMatrixEntry> allUIPairs = train.iterator(); while (allUIPairs.hasNext()) { RatingMatrixEntry entry = allUIPairs.next(); int item = entry.getItemIndex(); int user = entry.getUserIndex(); double ratingUI = entry.getValue(); if (ratingUI <= 0) { continue; }//from ww w . j a v a 2s. c om for (int k = 0; k < featureCount; k++) { double gammaShpUK = gammaShp.getEntry(user, k); double gammaRteUK = gammaRte.getEntry(user, k); double lambdaShpIK = lambdaShp.getEntry(item, k); double lambdaRteIK = lambdaRte.getEntry(item, k); double phiUIK = Gamma.digamma(gammaShpUK) - Math.log(gammaRteUK) + Gamma.digamma(lambdaShpIK) - Math.log(lambdaRteIK); phiUI.setEntry(k, phiUIK); } logNormalize(phiUI); if (ratingUI > 1) { phiUI.mapMultiplyToSelf(ratingUI); } for (int k = 0; k < featureCount; k++) { double value = phiUI.getEntry(k); gammaShpNext.addToEntry(user, k, value); lambdaShpNext.addToEntry(item, k, value); } } logger.info("iteration {} first phrase update finished", iterCount); RealVector gammaRteSecondTerm = MatrixUtils.createRealVector(new double[featureCount]); for (int k = 0; k < featureCount; k++) { double gammaRteUK = 0.0; for (int item = 0; item < itemNum; item++) { gammaRteUK += lambdaShp.getEntry(item, k) / lambdaRte.getEntry(item, k); } gammaRteSecondTerm.setEntry(k, gammaRteUK); } // update user parameters double kappaRteFirstTerm = aPrime / bPrime; for (int user = 0; user < userNum; user++) { double gammaRteUKFirstTerm = kappaShp.getEntry(user) / kappaRte.getEntry(user); double kappaRteU = 0.0; for (int k = 0; k < featureCount; k++) { double gammaShpUK = gammaShpNext.getEntry(user, k); gammaShp.setEntry(user, k, gammaShpUK); gammaShpNext.setEntry(user, k, a); double gammaRteUK = gammaRteSecondTerm.getEntry(k); gammaRteUK += gammaRteUKFirstTerm; gammaRte.setEntry(user, k, gammaRteUK); kappaRteU += gammaShpUK / gammaRteUK; } kappaRteU += kappaRteFirstTerm; kappaRte.setEntry(user, kappaRteU); } logger.info("iteration {} second phrase update finished", iterCount); RealVector lambdaRteSecondTerm = MatrixUtils.createRealVector(new double[featureCount]); for (int k = 0; k < featureCount; k++) { double lambdaRteIK = 0.0; for (int user = 0; user < userNum; user++) { lambdaRteIK += gammaShp.getEntry(user, k) / gammaRte.getEntry(user, k); } lambdaRteSecondTerm.setEntry(k, lambdaRteIK); } // update item parameters double tauRteFirstTerm = cPrime / dPrime; for (int item = 0; item < itemNum; item++) { double lambdaRteFirstTerm = tauShp.getEntry(item) / tauRte.getEntry(item); double tauRteI = 0.0; for (int k = 0; k < featureCount; k++) { double lambdaShpIK = lambdaShpNext.getEntry(item, k); lambdaShp.setEntry(item, k, lambdaShpIK); lambdaShpNext.setEntry(item, k, c); double lambdaRteIK = lambdaRteSecondTerm.getEntry(k); // plus first term lambdaRteIK += lambdaRteFirstTerm; lambdaRte.setEntry(item, k, lambdaRteIK); // update tauRteI second term tauRteI += lambdaShpIK / lambdaRteIK; } tauRteI += tauRteFirstTerm; tauRte.setEntry(item, tauRteI); } logger.info("iteration {} third phrase update finished", iterCount); // compute average predictive log likelihood of validation data per {@code iterationfrequency} iterations if (iterCount == 1) { for (int user = 0; user < userNum; user++) { kappaShp.setEntry(user, kappaShpU); } for (int item = 0; item < itemNum; item++) { tauShp.setEntry(item, tauShpI); } } if ((iterCount % iterationFrequency) == 0) { Iterator<RatingMatrixEntry> valIter = validation.iterator(); avgPLLCurr = 0.0; while (valIter.hasNext()) { RatingMatrixEntry ratingEntry = valIter.next(); int user = ratingEntry.getUserIndex(); int item = ratingEntry.getItemIndex(); double rating = ratingEntry.getValue(); double eThetaBeta = 0.0; for (int k = 0; k < featureCount; k++) { double eThetaUK = gammaShp.getEntry(user, k) / gammaRte.getEntry(user, k); double eBetaIK = lambdaShp.getEntry(item, k) / lambdaRte.getEntry(item, k); eThetaBeta += eThetaUK * eBetaIK; } double pLL = 0.0; if (isProbPredition) { pLL = (rating == 0) ? (-eThetaBeta) : Math.log(1 - Math.exp(-eThetaBeta)); } else { pLL = rating * Math.log(eThetaBeta) - eThetaBeta - Gamma.logGamma(rating + 1); } avgPLLCurr += pLL; } avgPLLCurr = avgPLLCurr / validation.size(); diffPLL = Math.abs((avgPLLCurr - avgPLLPre) / avgPLLPre); avgPLLPre = avgPLLCurr; logger.info("iteration {} with current average predictive log likelihood {} and the change is {}", iterCount, avgPLLCurr, diffPLL); } iterCount++; } // construct feature matrix used by HPFModel RealMatrix eTheta = MatrixUtils.createRealMatrix(userNum, featureCount); RealMatrix eBeta = MatrixUtils.createRealMatrix(itemNum, featureCount); for (int user = 0; user < userNum; user++) { RealVector gammaShpU = gammaShp.getRowVector(user); RealVector gammaRteU = gammaRte.getRowVector(user); RealVector eThetaU = gammaShpU.ebeDivide(gammaRteU); eTheta.setRowVector(user, eThetaU); logger.info("Training user {} features finished", user); } for (int item = 0; item < itemNum; item++) { RealVector lambdaShpI = lambdaShp.getRowVector(item); RealVector lambdaRteI = lambdaRte.getRowVector(item); RealVector eBetaI = lambdaShpI.ebeDivide(lambdaRteI); eBeta.setRowVector(item, eBetaI); logger.info("Training item {} features finished", item); } KeyIndex uidx = ratings.getUserIndex(); KeyIndex iidx = ratings.getItemIndex(); return new HPFModel(eTheta, eBeta, uidx, iidx); }
From source file:org.lenskit.pf.HPFModelProvider.java
public void logNormalize(RealVector phi) { final int size = phi.getDimension(); if (size == 1) { phi.setEntry(0, 1.0);// ww w . jav a 2 s .c o m } if (size > 1) { double logsum = phi.getEntry(0); for (int i = 1; i < size; i++) { double phiK = phi.getEntry(i); if (phiK < logsum) { logsum = logsum + Math.log(1 + Math.exp(phiK - logsum)); } else { logsum = phiK + Math.log(1 + Math.exp(logsum - phiK)); } } for (int k = 0; k < size; k++) { double phiK = phi.getEntry(k); double normalized = Math.exp(phiK - logsum); phi.setEntry(k, normalized); } } }
From source file:org.lenskit.pf.PMFModel.java
public static ModelEntry computeUserUpdate(List<RatingMatrixEntry> ratings, PMFModel preUserModel, PMFModel preItemModel, PFHyperParameters hyperParameters) { final int featureCount = hyperParameters.getFeatureCount(); RealVector phiUI = MatrixUtils.createRealVector(new double[featureCount]); final int user = ratings.get(0).getUserIndex(); final double userWeightShpPrior = hyperParameters.getUserWeightShpPrior(); final double userActivityShpPrior = hyperParameters.getUserActivityShpPrior(); final double userActivityPriorMean = hyperParameters.getUserActivityPriorMean(); ModelEntry modelEntry = new ModelEntry(user, featureCount, userWeightShpPrior, userActivityShpPrior, userActivityPriorMean);/*from w ww . j av a2s .c om*/ Iterator<RatingMatrixEntry> userRatings = ratings.iterator(); while (userRatings.hasNext()) { RatingMatrixEntry entry = userRatings.next(); int item = entry.getItemIndex(); double rating = entry.getValue(); if (rating <= 0) { continue; } updatePhi(phiUI, user, item, rating, featureCount, preUserModel, preItemModel); for (int k = 0; k < featureCount; k++) { double value = phiUI.getEntry(k) + modelEntry.getWeightShpEntry(k); modelEntry.setWeightShpEntry(k, value); } } // update user weight rate and user activity rate double meanUserActivity = preUserModel.getActivityShp(user) / preUserModel.getActivityRte(user); for (int k = 0; k < featureCount; k++) { double userWeightRteK = meanUserActivity + preItemModel.getSumOfMeanWeight().get(k); modelEntry.setWeightRteEntry(k, userWeightRteK); double userActivityRte = modelEntry.getActivityRte() + modelEntry.getWeightShpEntry(k) / userWeightRteK; modelEntry.setActivityRte(userActivityRte); } return modelEntry; }
From source file:org.lenskit.pf.PMFModel.java
public static ModelEntry computeItemUpdate(List<RatingMatrixEntry> ratings, PMFModel preUserModel, PMFModel preItemModel, PMFModel currUserModel, PFHyperParameters hyperParameters) { final int featureCount = hyperParameters.getFeatureCount(); RealVector phiUI = MatrixUtils.createRealVector(new double[featureCount]); final int item = ratings.get(0).getItemIndex(); final double itemWeightShpPrior = hyperParameters.getItemWeightShpPrior(); final double itemActivityShpPrior = hyperParameters.getItemActivityShpPrior(); final double itemActivityPriorMean = hyperParameters.getItemActivityPriorMean(); ModelEntry modelEntry = new ModelEntry(item, featureCount, itemWeightShpPrior, itemActivityShpPrior, itemActivityPriorMean);//from www .j a v a2s. c o m Iterator<RatingMatrixEntry> itemRatings = ratings.iterator(); while (itemRatings.hasNext()) { RatingMatrixEntry entry = itemRatings.next(); int user = entry.getUserIndex(); double rating = entry.getValue(); if (rating <= 0) { continue; } updatePhi(phiUI, user, item, rating, featureCount, preUserModel, preItemModel); for (int k = 0; k < featureCount; k++) { double value = phiUI.getEntry(k) + modelEntry.getWeightShpEntry(k); modelEntry.setWeightShpEntry(k, value); } } // update item weight rate and item activity rate double meanItemActivity = preItemModel.getActivityShp(item) / preItemModel.getActivityRte(item); for (int k = 0; k < featureCount; k++) { double itemWeightRteK = meanItemActivity + currUserModel.getSumOfMeanWeight().get(k); modelEntry.setWeightRteEntry(k, itemWeightRteK); double itemActivityRte = modelEntry.getActivityRte() + modelEntry.getWeightShpEntry(k) / itemWeightRteK; modelEntry.setActivityRte(itemActivityRte); } return modelEntry; }
From source file:org.lenskit.pf.PMFModel.java
private static void logNormalize(RealVector phi) { final int size = phi.getDimension(); if (size == 1) { phi.setEntry(0, 1.0);//from w w w . j a v a2s . c o m } if (size > 1) { double logsum = phi.getEntry(0); for (int k = 1; k < size; k++) { double phiK = phi.getEntry(k); if (phiK < logsum) { logsum = logsum + Math.log(1 + Math.exp(phiK - logsum)); } else { logsum = phiK + Math.log(1 + Math.exp(logsum - phiK)); } } for (int k = 0; k < size; k++) { double phiK = phi.getEntry(k); double normalized = Math.exp(phiK - logsum); phi.setEntry(k, normalized); } } }