Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssociationRuleRecommender time complexity reduced(by Mr No2) #149

Merged
merged 1 commit into from
Jun 6, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@
*/
package net.librec.recommender.ext;

import com.google.common.cache.LoadingCache;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import net.librec.common.LibrecException;
import net.librec.math.structure.SparseVector;
import net.librec.math.structure.VectorEntry;
import net.librec.math.structure.*;
import net.librec.recommender.AbstractRecommender;

import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
* Choonho Kim and Juntae Kim, <strong>A Recommendation Algorithm Using Multi-Level Association Rules</strong>, WI 2003.
* <p>
Expand All @@ -42,42 +37,52 @@ public class AssociationRuleRecommender extends AbstractRecommender {
/**
* confidence matrix of association rules
*/
private Table<Integer, Integer, Double> associationTable;
private SparseMatrix associations;

/**
* user-vector cache, item-vector cache
*/
protected LoadingCache<Integer, SparseVector> userCache;
private DenseMatrix userItemRates;

/**
* Guava cache configuration
*/
protected static String cacheSpec;
// /**
// * user-vector cache, item-vector cache
// */
// protected LoadingCache<Integer, SparseVector> userCache;

// /**
// * Guava cache configuration
// */
// protected static String cacheSpec;

/**
* setup
*
* @throws LibrecException if error occurs
* @throws LibrecException
* if error occurs
*/
@Override
protected void setup() throws LibrecException {
super.setup();
cacheSpec = conf.get("guava.cache.spec", "maximumSize=200,expireAfterAccess=2m");
// cacheSpec = conf.get("guava.cache.spec",
// "maximumSize=200,expireAfterAccess=2m");

associationTable = HashBasedTable.create(numItems, numItems);
userCache = trainMatrix.rowCache(cacheSpec);
userItemRates = new DenseMatrix(trainMatrix.numRows, trainMatrix.numColumns);
for (MatrixEntry entry : trainMatrix) {
userItemRates.set(entry.row(), entry.column(), entry.get());
}
// userCache = trainMatrix.rowCache(cacheSpec);
}

@Override
protected void trainModel() throws LibrecException {
// simple rule: X => Y, given that each user vector is regarded as a transaction
// simple rule: X => Y, given that each user vector is regarded as a
// transaction
Table<Integer, Integer, Double> associationTable = HashBasedTable.create(numItems, numItems);
for (int itemIdx = 0; itemIdx < numItems; itemIdx++) {
// all transactions for item itemIdx
SparseVector userRatingsVector = trainMatrix.column(itemIdx);
int userCount = userRatingsVector.size();

for (int assoItemIdx = 0; assoItemIdx < numItems; assoItemIdx++) {
// compute confidence where containing item assoItemIdx among userRatingsVector
// compute confidence where containing item assoItemIdx among
// userRatingsVector
int count = 0;
for (VectorEntry vectorEntry : userRatingsVector) {
int userIdx = vectorEntry.index();
Expand All @@ -92,30 +97,29 @@ protected void trainModel() throws LibrecException {
}
}
}
associations = new SparseMatrix(numItems, numItems, associationTable);
}

/**
* predict a specific rating for user userIdx on item itemIdx.
*
* @param userIdx user index
* @param itemIdx item index
* @param userIdx
* user index
* @param itemIdx
* item index
* @return predictive rating for user userIdx on item itemIdx
* @throws LibrecException if error occurs
* @throws LibrecException
* if error occurs
*/
@Override
protected double predict(int userIdx, int itemIdx) throws LibrecException {
SparseVector itemRatingsVector = null;
try {
itemRatingsVector = userCache.get(userIdx);
} catch (ExecutionException e) {
e.printStackTrace();
}

double predictRatings = 0;
for (Map.Entry<Integer, Double> mapEntry : associationTable.column(itemIdx).entrySet()) {
int assoItemIdx = mapEntry.getKey();
double support = mapEntry.getValue();
predictRatings += itemRatingsVector.get(assoItemIdx) * support;
for (VectorEntry mapEntry : associations.column(itemIdx)) {
int assoItemIdx = mapEntry.index();
double support = mapEntry.get();
double value = userItemRates.get(userIdx, assoItemIdx);
predictRatings += value * support;
}

return predictRatings;
Expand Down