package happy.research.cf; import java.util.Map; import java.util.Map.Entry; public class SlopeOne_t extends Thread_t { /* item-item deviation matrix*/ protected Map<String, Map<String, Double>> devMatrix; /* item-item frequency matrix*/ protected Map<String, Map<String, Integer>> freqMatrix; public SlopeOne_t(int id, Map<String, Map<String, Double>> _diffMatrix, Map<String, Map<String, Integer>> _freqMatrix) { super(id); devMatrix = _diffMatrix; freqMatrix = _freqMatrix; } /** * predict a rating for {@code testItem} * * @param itemRatings test user's ratings * @param testItem test item * @param weighted whether use weighted or simple slope one * * @return prediction value */ public double predict(Map<String, Rating> itemRatings, String testItem, boolean weighted) { if (!devMatrix.containsKey(testItem)) return Double.NaN; // not predictable double sum = 0.0; int cnt = 0; for (String item : itemRatings.keySet()) { double rate = itemRatings.get(item).getRating(); if (!devMatrix.get(testItem).containsKey(item)) continue; int freq = freqMatrix.get(testItem).get(item); double pred = devMatrix.get(testItem).get(item) + rate; if (weighted) { sum += freq * pred; cnt += freq; } else { sum += pred; cnt++; } } return sum / cnt; } @Override protected void runCrossValidation() { for (Entry<String, Map<String, Rating>> en : threadMap.entrySet()) { String testUser = en.getKey(); Map<String, Rating> itemRatings = userRatingsMap.get(testUser); // have not rated any items if (itemRatings == null) continue; Map<String, Rating> testRatings = en.getValue(); for (String testItem : testRatings.keySet()) { double pred = predict(itemRatings, testItem, true); if (Double.isNaN(pred)) continue; Rating rating = testRatings.get(testItem); pf.addPredicts(new Prediction(rating, pred)); } } } @Override protected Map<String, Double>[] buildModel(Rating testRating) { // TODO Auto-generated method stub return null; } }