package happy.research.cf;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* The implementation of (weighted) slope one by Guibing Guo on June 7th, 2013.
* <br/>
* This is a compact model-based approach, hence we should use k-fold cross validation.
* <br/>
*/
public class SlopeOne_mt extends DefaultCF_mt
{
public SlopeOne_mt()
{
methodId = "SlopeOne";
}
protected void train(Map<String, Map<String, Double>> diffMatrix, Map<String, Map<String, Integer>> freqMatrix)
{
// first iterate through users
for (Map<String, Rating> itemRatings : userRatingsMap.values())
{
// then iterate through user data
for (Entry<String, Rating> e1 : itemRatings.entrySet())
{
String i1 = e1.getKey();
double r1 = e1.getValue().getRating();
if (!diffMatrix.containsKey(i1))
{
diffMatrix.put(i1, new HashMap<String, Double>());
freqMatrix.put(i1, new HashMap<String, Integer>());
}
for (Entry<String, Rating> e2 : itemRatings.entrySet())
{
String i2 = e2.getKey();
double r2 = e2.getValue().getRating();
int cnt = 0;
if (freqMatrix.get(i1).containsKey(i2)) cnt = freqMatrix.get(i1).get(i2);
double diff = 0.0;
if (diffMatrix.get(i1).containsKey(i2)) diff = diffMatrix.get(i1).get(i2);
double new_diff = r1 - r2;
freqMatrix.get(i1).put(i2, cnt + 1);
diffMatrix.get(i1).put(i2, diff + new_diff);
}
}
}
for (String i : diffMatrix.keySet())
{
for (String j : diffMatrix.get(i).keySet())
{
double diff = diffMatrix.get(i).get(j);
int count = freqMatrix.get(i).get(j);
diffMatrix.get(i).put(j, diff / count);
}
}
}
@Override
protected Performance runMultiThreads() throws Exception
{
/* {item - item deviation matrix} */
Map<String, Map<String, Double>> devMatrix = new HashMap<>();
/* {item - item frequency matrix} */
Map<String, Map<String, Integer>> freqMatrix = new HashMap<>();
train(devMatrix, freqMatrix);
for (int i = 0; i < ratingArrays.length; i++)
{
threads[i] = new Thread(new SlopeOne_t(i, devMatrix, freqMatrix));
threads[i].start();
}
for (Thread tr : threads)
tr.join();
return pf;
}
}