/*
TagRecommender:
A framework to implement and evaluate algorithms for the recommendation
of tags.
Copyright (C) 2013 Dominik Kowald
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package common;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang3.StringEscapeUtils;
import com.google.common.primitives.Ints;
import file.BookmarkReader;
public class Utilities {
private final static String REV_START = "<rev xml:space=\"preserve\">";
private final static String REV_END = "</rev>";
public static boolean isEntityEvaluated(BookmarkReader reader, int id, Integer minBookmarks, Integer maxBookmarks,
boolean resource) {
if (reader == null || id == -1) {
return true;
}
List<Integer> entityCounts = (resource ? reader.getResourceCounts() : reader.getUserCounts());
if (id < entityCounts.size()) {
int count = entityCounts.get(id);
if (minBookmarks != null) {
if (count < minBookmarks.intValue()) {
return false;
}
} else if (maxBookmarks != null) {
if (count > maxBookmarks.intValue()) {
return false;
}
}
return true;
}
return false;
}
public static List<Map<Integer, Integer>> getUserMaps(List<Bookmark> userLines) {
List<Map<Integer, Integer>> userMaps = new ArrayList<Map<Integer, Integer>>();
for (Bookmark data : userLines) {
int userID = data.getUserID();
if (userID >= userMaps.size()) {
userMaps.add(Utilities.mergeListWithMap(data.getTags(), new LinkedHashMap<Integer, Integer>()));
} else {
Utilities.mergeListWithMap(data.getTags(), userMaps.get(userID));
}
}
return userMaps;
}
public static List<Map<Integer, Integer>> getResMaps(List<Bookmark> userLines) {
List<Map<Integer, Integer>> resMaps = new ArrayList<Map<Integer, Integer>>();
for (Bookmark data : userLines) {
int resID = data.getResourceID();
if (resID >= resMaps.size()) {
resMaps.add(Utilities.mergeListWithMap(data.getTags(), new LinkedHashMap<Integer, Integer>()));
} else {
Utilities.mergeListWithMap(data.getTags(), resMaps.get(resID));
}
}
return resMaps;
}
public static List<Map<Integer, Integer>> getUserTopics(List<Bookmark> userLines) {
List<Map<Integer, Integer>> userMaps = new ArrayList<Map<Integer, Integer>>();
for (Bookmark data : userLines) {
int userID = data.getUserID();
if (userID >= userMaps.size()) {
userMaps.add(Utilities.mergeListWithMap(data.getCategories(), new LinkedHashMap<Integer, Integer>()));
} else {
Utilities.mergeListWithMap(data.getCategories(), userMaps.get(userID));
}
}
return userMaps;
}
public static List<Map<Integer, Integer>> getResTopics(List<Bookmark> userLines) {
List<Map<Integer, Integer>> resMaps = new ArrayList<Map<Integer, Integer>>();
for (Bookmark data : userLines) {
int resID = data.getResourceID();
if (resID >= resMaps.size()) {
resMaps.add(Utilities.mergeListWithMap(data.getCategories(), new LinkedHashMap<Integer, Integer>()));
} else {
Utilities.mergeListWithMap(data.getCategories(), resMaps.get(resID));
}
}
return resMaps;
}
public static List<Map<Integer, Double>> getUniqueTopicMaps(List<Bookmark> userLines, boolean resource) {
List<Map<Integer, Double>> resMaps = new ArrayList<Map<Integer, Double>>();
for (Bookmark data : userLines) {
int resID = resource ? data.getResourceID() : data.getUserID();
Map<Integer, Double> rMap = null;
if (resID >= resMaps.size()) {
rMap = new LinkedHashMap<Integer, Double>();
resMaps.add(rMap);
} /*
* else { rMap = resMaps.get(resID); }
*/
if (rMap != null) {
for (int cat : data.getCategories()) {
rMap.put(cat, 1.0);
}
}
}
return resMaps;
}
// returns for each tag the list of resources this tag was used for
public static List<Map<Integer, Double>> getResourceMapsForTags(List<Bookmark> userLines) {
List<Map<Integer, Double>> tagMaps = new ArrayList<Map<Integer, Double>>();
for (Bookmark data : userLines) {
for (int tagID : data.getTags()) {
Map<Integer, Double> tagMap = null;
if (tagID >= tagMaps.size()) {
tagMap = new LinkedHashMap<Integer, Double>();
tagMaps.add(tagMap);
} else {
tagMap = tagMaps.get(tagID);
}
if (tagMap != null) {
Double count = tagMap.get(data.getResourceID());
tagMap.put(data.getResourceID(), count == null ? 1.0 : count.doubleValue() + 1.0);
}
}
}
return tagMaps;
}
public static List<int[]> createRandomBaseline(int from, int to, int count) {
List<int[]> baseline = new ArrayList<int[]>();
for (int i = 0; i < count; i++) {
baseline.add(Ints.toArray(getRandomIndices(from, to)));
}
return baseline;
}
public static List<Integer> getRandomIndices(int from, int to) {
List<Integer> indices = new ArrayList<Integer>();
for (int j = from; j <= to; j++) {
indices.add(j);
}
Collections.shuffle(indices);
return indices;
}
public static boolean writeStringToFile(String filename, String stringToWrite) {
try {
FileWriter writer = new FileWriter(new File(filename));
BufferedWriter bw = new BufferedWriter(writer);
bw.write(stringToWrite);
bw.flush();
bw.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static List<String> readFileToStringList(String filename) {
List<String> returnList = new ArrayList<String>();
try {
// FileReader reader = new FileReader(new File(filename));
InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(filename)), "UTF8");
BufferedReader br = new BufferedReader(reader);
String line = "";
while ((line = br.readLine()) != null) {
returnList.add(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return returnList;
}
public static Map<Integer, Double> getRelativeMapFromList(List<Integer> from) {
Map<Integer, Double> to = new LinkedHashMap<Integer, Double>();
for (Integer value : from) {
Double count = to.get(value);
to.put(value, (count != null ? count + 1.0 : 1.0));
}
for (Map.Entry<Integer, Double> entry : to.entrySet()) {
entry.setValue(entry.getValue() / (double) from.size());
}
return to;
}
public static Map<Integer, Integer> mergeListWithMap(List<Integer> from, Map<Integer, Integer> to) {
for (Integer value : from) {
Integer count = to.get(value);
to.put(value, (count != null ? count + 1 : 1));
}
return to;
}
public static Map<Integer, Double> mergeProbMaps(BookmarkReader reader, Map<Integer, Double> from,
Map<Integer, Double> to, double lambda) {
Map<Integer, Double> resultMap = new LinkedHashMap<Integer, Double>();
for (int i = 0; i < reader.getTags().size(); i++) {
Double fromVal = from.get(i);
if (fromVal == null) {
fromVal = 0.0;
}
Double toVal = to.get(i);
if (toVal == null) {
toVal = 0.0;
}
if (fromVal > 0.0 || toVal > 0.0) {
resultMap.put(i, lambda * fromVal + (1.0 - lambda) * toVal);
}
}
return resultMap;
/*
* for (Map.Entry<Integer, Double> entry : from.entrySet()) { Double
* prob = to.get(entry.getKey()); if (prob == null) { prob = 0.0;
* System.out.println("Merge maps: value not found"); }
* to.put(entry.getKey(), lambda * entry.getValue() + (1.0 - lambda) *
* prob); } return to;
*/
}
public static String getWikiContent(String xmlString) {
int startIndex = xmlString.indexOf(REV_START);
int endIndex = xmlString.indexOf(REV_END);
if (startIndex != -1 && endIndex != -1) {
return StringEscapeUtils.unescapeHtml4(xmlString.substring(startIndex + REV_START.length(), endIndex));
}
return null;
}
public static List<String> getTagNames(List<Integer> tagIDs, BookmarkReader reader) {
List<String> tagNames = new ArrayList<String>();
for (int id : tagIDs) {
tagNames.add(reader.getTags().get(id));
}
return tagNames;
}
public static Set<Integer> getUsersByResource(List<Bookmark> userLines, int resID) {
Set<Integer> userList = new HashSet<Integer>();
for (Bookmark data : userLines) {
if (data.getResourceID() == resID) {
userList.add(data.getUserID());
}
}
return userList;
}
public static List<Set<Integer>> getUserResourceLists(List<Bookmark> userLines) {
List<Set<Integer>> userLists = new ArrayList<Set<Integer>>();
for (Bookmark data : userLines) {
int userID = data.getUserID();
Set<Integer> resList = null;
if (userID >= userLists.size()) {
resList = new HashSet<Integer>();
userLists.add(resList);
} else {
resList = userLists.get(userID);
}
resList.add(data.getResourceID());
}
return userLists;
}
public static List<Map<Integer, Double>> getRelativeTagMaps(List<Bookmark> userLines, boolean resource) {
List<Map<Integer, Integer>> maps = (resource ? getResMaps(userLines) : getUserMaps(userLines));
List<Map<Integer, Double>> relMaps = new ArrayList<Map<Integer, Double>>();
for (Map<Integer, Integer> m : maps) {
double count = getMapCount(m);
Map<Integer, Double> relM = new LinkedHashMap<Integer, Double>();
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
relM.put(entry.getKey(), (double) entry.getValue().intValue() / count);
}
relMaps.add(relM);
}
return relMaps;
}
public static List<Map<Integer, Double>> getDoubleTagMaps(List<Bookmark> userLines, boolean resource) {
List<Map<Integer, Integer>> maps = (resource ? getResMaps(userLines) : getUserMaps(userLines));
List<Map<Integer, Double>> relMaps = new ArrayList<Map<Integer, Double>>();
for (Map<Integer, Integer> m : maps) {
Map<Integer, Double> relM = new LinkedHashMap<Integer, Double>();
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
relM.put(entry.getKey(), entry.getValue().doubleValue());
}
relMaps.add(relM);
}
return relMaps;
}
public static List<Map<Integer, Double>> getRelativeTopicMaps(List<Bookmark> userLines, boolean resource) {
List<Map<Integer, Integer>> maps = (resource ? getResTopics(userLines) : getUserTopics(userLines));
List<Map<Integer, Double>> relMaps = new ArrayList<Map<Integer, Double>>();
for (Map<Integer, Integer> m : maps) {
double count = getMapCount(m);
Map<Integer, Double> relM = new LinkedHashMap<Integer, Double>();
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
relM.put(entry.getKey(), (double) entry.getValue().intValue() / count);
}
relMaps.add(relM);
}
return relMaps;
}
public static List<Map<Integer, Double>> getNormalizedMaps(List<Bookmark> userLines, boolean resource) {
List<Map<Integer, Integer>> maps = (resource ? getResMaps(userLines) : getUserMaps(userLines));
List<Map<Integer, Double>> relMaps = new ArrayList<Map<Integer, Double>>();
for (Map<Integer, Integer> m : maps) {
double denom = getMapDenom(m);
Map<Integer, Double> relM = new LinkedHashMap<Integer, Double>();
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
relM.put(entry.getKey(), Math.exp((double) entry.getValue().intValue()) / denom);
}
relMaps.add(relM);
}
return relMaps;
}
public static List<List<Bookmark>> getBookmarks(List<Bookmark> lines, boolean resource) {
List<List<Bookmark>> bookmarks = new ArrayList<List<Bookmark>>();
for (Bookmark data : lines) {
int id = (resource ? data.getResourceID() : data.getUserID());
List<Bookmark> b = null;
if (id >= bookmarks.size()) {
b = new ArrayList<Bookmark>();
bookmarks.add(b);
} else {
b = bookmarks.get(id);
}
b.add(data);
}
return bookmarks;
}
public static List<Map<Integer, Double>> getUsedEntities(List<Bookmark> lines, boolean resource,
List<Map<Integer, Double>> valueMaps) {
List<Map<Integer, Double>> entities = new ArrayList<Map<Integer, Double>>();
for (Bookmark data : lines) {
int id = (resource ? data.getResourceID() : data.getUserID());
int entityID = (resource ? data.getUserID() : data.getResourceID());
Map<Integer, Double> values = null;
if (valueMaps != null && id < valueMaps.size()) {
values = valueMaps.get(id);
}
Map<Integer, Double> e = null;
if (id >= entities.size()) {
e = new LinkedHashMap<Integer, Double>();
entities.add(e);
} else {
e = entities.get(id);
}
double val = 1.0;
if (values != null) {
val = 0.0;
for (int t : data.getTags()) {
Double v = values.get(t);
if (v != null) {
val += v.doubleValue();
}
}
}
Double oldVal = e.get(entityID);
e.put(entityID, oldVal != null ? oldVal.doubleValue() + val : val);
}
return entities;
}
// returns a Map<TagId, frequency> for all lines in userLines
public static Map<Integer, Integer> getTags(List<Bookmark> userLines) {
Map<Integer, Integer> resTags = new LinkedHashMap<Integer, Integer>();
for (Bookmark data : userLines) {
for (Integer tag : data.getTags()) {
int count = resTags.containsKey(tag) ? resTags.get(tag) : 0;
resTags.put(tag, count + 1);
}
}
return resTags;
}
public static double getMapCount(Map<Integer, Integer> map) {
double sum = 0.0;
if (map != null) {
for (Integer val : map.values()) {
sum += (double) val;
}
}
return sum;
}
public static double getMapDenom(Map<Integer, Integer> map) {
double sum = 0.0;
if (map != null) {
for (Integer val : map.values()) {
sum += Math.exp((double) val);
}
}
return sum;
}
public static double getSmoothedTagValue(double userVal, double userTagCount, double resVal, double resTagCount,
double pt) {
userVal = Math.log(userTagCount + 1.0) / Math.log(2.0) * userVal
+ Math.log(resTagCount + 1.0) / Math.log(2.0) * pt;
resVal = Math.log(resTagCount + 1.0) / Math.log(2.0) * resVal
+ Math.log(userTagCount + 1.0) / Math.log(2.0) * pt;
return userVal * resVal / pt;
}
public static double getJaccardSim(Map<Integer, Integer> targetMap, Map<Integer, Integer> nMap) {
Set<Integer> unionSet = new HashSet<Integer>(targetMap.keySet());
Set<Integer> intersectSet = new HashSet<Integer>(targetMap.keySet());
unionSet.addAll(nMap.keySet());
intersectSet.retainAll(nMap.keySet());
if (intersectSet.size() == 0 || unionSet.size() == 0)
return 0.0;
return (double) intersectSet.size() / (double) unionSet.size();
}
public static double getJaccardSimLists(List<Integer> targetMap, List<Integer> nMap) {
Set<Integer> unionSet = new HashSet<Integer>(targetMap);
Set<Integer> intersectSet = new HashSet<Integer>(targetMap);
unionSet.addAll(nMap);
intersectSet.retainAll(nMap);
if (intersectSet.size() == 0 || unionSet.size() == 0)
return 0.0;
return (double) intersectSet.size() / (double) unionSet.size();
}
public static double getJaccardFloatSim(Map<Integer, Double> targetMap, Map<Integer, Double> nMap) {
Set<Integer> unionSet = new HashSet<Integer>(targetMap.keySet());
Set<Integer> intersectSet = new HashSet<Integer>(targetMap.keySet());
unionSet.addAll(nMap.keySet());
intersectSet.retainAll(nMap.keySet());
if (intersectSet.size() == 0 || unionSet.size() == 0)
return 0.0;
return (double) intersectSet.size() / (double) unionSet.size();
}
public static double getCosineSim(Map<Integer, Integer> targetMap, Map<Integer, Integer> nMap) {
Set<Integer> both = new HashSet<Integer>(targetMap.keySet());
both.retainAll(nMap.keySet());
double scalar = 0.0, norm1 = 0.0, norm2 = 0.0;
for (int k : both)
scalar += (targetMap.get(k) * nMap.get(k));
for (int k : targetMap.keySet())
norm1 += (targetMap.get(k) * targetMap.get(k));
for (int k : nMap.keySet())
norm2 += (nMap.get(k) * nMap.get(k));
if (Math.sqrt(norm1 * norm2) == 0.0)
return 0.0;
return scalar / Math.sqrt(norm1 * norm2);
}
public static double getCosineSimList(List<Integer> targetList, List<Integer> nList) {
Map<Integer, Integer> targetMap = getMapForList(targetList);
Map<Integer, Integer> nMap = getMapForList(nList);
Set<Integer> both = new HashSet<Integer>(targetMap.keySet());
both.retainAll(nMap.keySet());
double scalar = 0.0, norm1 = 0.0, norm2 = 0.0;
for (int k : both)
scalar += (targetMap.get(k) * nMap.get(k));
for (int k : targetMap.keySet())
norm1 += (targetMap.get(k) * targetMap.get(k));
for (int k : nMap.keySet())
norm2 += (nMap.get(k) * nMap.get(k));
if (Math.sqrt(norm1 * norm2) == 0.0)
return 0.0;
return scalar / Math.sqrt(norm1 * norm2);
}
public static double getCosineFloatSim(Map<Integer, Double> targetMap, Map<Integer, Double> nMap) {
Set<Integer> both = new HashSet<Integer>(targetMap.keySet());
both.retainAll(nMap.keySet());
double scalar = 0.0, norm1 = 0.0, norm2 = 0.0;
for (int k : both) {
/*
System.out.println(" k >> " + k);
System.out.println(" nMap >> " + nMap);
System.out.println(" targetMap >> " + targetMap);
System.out.println(" nMap.get(k) >> " + nMap.get(k));
System.out.println(" targetMap.get(k) >> " + targetMap.get(k));
*/
scalar += (targetMap.get(k) * nMap.get(k));
}
for (int k : targetMap.keySet())
norm1 += (targetMap.get(k) * targetMap.get(k));
for (int k : nMap.keySet())
norm2 += (nMap.get(k) * nMap.get(k));
if (Math.sqrt(norm1 * norm2) == 0.0)
return 0.0;
return scalar / Math.sqrt(norm1 * norm2);
}
public static double getPearsonSim(List<Bookmark> userRatings, List<Bookmark> neighborRatings) {
return PearsonSimilarityCalculator.getPearsonSim(userRatings, neighborRatings);
}
public static long getBaselineTimestamp(List<Bookmark> testLines, int refID, boolean resource) {
if (testLines != null) {
long maxTimestamp = -1;
for (Bookmark data : testLines) {
int id = resource ? data.getResourceID() : data.getUserID();
if (id == refID) {
long timestamp = Long.parseLong(data.getTimestamp());
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
}
}
}
return maxTimestamp;
}
return System.currentTimeMillis() / 1000;
}
public static long getBaselineTimestampEff(List<Bookmark> testLines, int refID) {
if (testLines != null) {
for (int i = testLines.size() - 1; i >= 0; i--) {
Bookmark data = testLines.get(i);
if (data.getUserID() == refID) {
return Long.parseLong(data.getTimestamp());
}
}
return -1;
}
return System.currentTimeMillis() / 1000;
}
public static Map<Integer, Integer> getMapForList(List<Integer> list) {
Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>();
for (Integer val : list) {
map.put(val, 1);
}
return map;
}
public static Map<Integer, Double> getAllEntities(List<Bookmark> trainList, boolean resource) {
Map<Integer, Double> allEntities = new LinkedHashMap<Integer, Double>();
for (Bookmark data : trainList) {
if (resource) {
allEntities.put(data.getResourceID(), 0.0);
} else {
allEntities.put(data.getUserID(), 0.0);
}
}
return allEntities;
}
public static Map<Integer, Double> getNeighbors(int userID, int resID, Map<Integer, Double> allNeighbors,
List<Map<Integer, Double>> userMaps, List<Bookmark> trainList, Similarity sim, boolean sorting) {
Map<Integer, Double> neighbors = new LinkedHashMap<Integer, Double>();
// List<Map<Integer, Integer>> neighborMaps = new ArrayList<Map<Integer,
// Integer>>();
Map<Integer, Double> targetMap = null;
// get all users that have tagged the resource
if (resID != -1) {
for (Bookmark data : trainList) {
if (data.getUserID() != userID) {
if (data.getResourceID() == resID) {
neighbors.put(data.getUserID(), 0.0);
}
}
}
}
// if list is empty, use all users
if (neighbors.size() == 0) {
// for (Bookmark data : trainList) {
// if (data.getUserID() != userID) {
// neighbors.put(data.getUserID(), 0.0);
// }
// }
neighbors.putAll(allNeighbors);
}
if (userID < userMaps.size()) {
targetMap = userMaps.get(userID);
} else {
return neighbors;
}
// for (int id : neighbors.keySet()) {
// neighborMaps.add(this.userMaps.get(id));
// }
// double lAverage = getLAverage(neighborMaps);
for (Map.Entry<Integer, Double> entry : neighbors.entrySet()) {
Map<Integer, Double> nMap = userMaps.get(entry.getKey());
if (userID != entry.getKey()/* && !nMap.isEmpty() */) {
Double bm25Value = (sim == Similarity.JACCARD ? Utilities.getJaccardFloatSim(targetMap, nMap)
: Utilities.getCosineFloatSim(targetMap, nMap));
// if (resID == -1) {
// bm25Value = Math.pow(bm25Value.doubleValue(), 3);
// }
// getBM25Value(neighborMaps, lAverage, targetMap,
// this.userMaps.get(entry.getKey()));
if (!bm25Value.isInfinite() && !bm25Value.isNaN()) {
entry.setValue(bm25Value);
}
}
}
if (sorting) {
// return the sorted neighbors
Map<Integer, Double> sortedNeighbors = new TreeMap<Integer, Double>(new DoubleMapComparator(neighbors));
sortedNeighbors.putAll(neighbors);
return sortedNeighbors;
} else {
return neighbors;
}
}
public static Map<Integer, Double> getSimResources(int userID, int resID, List<Integer> userResources,
Map<Integer, Double> allResources, List<Map<Integer, Double>> resMaps, List<Bookmark> trainList,
Similarity sim, boolean sorting) {
Map<Integer, Double> resources = new LinkedHashMap<Integer, Double>();
Map<Integer, Double> targetMap = null;
if (resID < resMaps.size()) {
targetMap = resMaps.get(resID);
}
if (targetMap == null || targetMap.isEmpty()) {
resources.putAll(allResources);
return resources;
}
// get all resources that have been tagged by the user
if (userID != -1) {
for (Bookmark data : trainList) {
if (data.getResourceID() != resID) {
if (data.getUserID() == userID) {
resources.put(data.getResourceID(), 0.0);
}
}
}
}
// if list is empty, use all resources
if (resources.size() == 0) {
resources.putAll(allResources);
}
for (Map.Entry<Integer, Double> entry : resources.entrySet()) {
Map<Integer, Double> rMap = resMaps.get(entry.getKey());
if ((userResources == null || !userResources.contains(entry.getKey())) && !rMap.isEmpty()
&& entry.getKey() != resID) {
double bm25Value = (sim == Similarity.JACCARD ? Utilities.getJaccardFloatSim(targetMap, rMap)
: Utilities.getCosineFloatSim(targetMap, rMap));
entry.setValue(bm25Value);
}
}
if (sorting) {
// return the sorted resources
Map<Integer, Double> sortedResources = new TreeMap<Integer, Double>(new DoubleMapComparator(resources));
sortedResources.putAll(resources);
return sortedResources;
} else {
return resources;
}
}
public static Map<Integer, Double> getSimResourcesForUser(int userID, Map<Integer, Double> allResources,
List<Map<Integer, Double>> userMaps, List<Map<Integer, Double>> resMaps, List<Integer> userResources,
Similarity sim, boolean sorting) {
Map<Integer, Double> resources = new LinkedHashMap<Integer, Double>();
Map<Integer, Double> targetMap = null;
if (userID < userMaps.size()) {
targetMap = userMaps.get(userID);
}
if (targetMap == null || targetMap.isEmpty()) {
return resources;
}
resources.putAll(allResources);
for (Map.Entry<Integer, Double> entry : resources.entrySet()) {
Map<Integer, Double> rMap = resMaps.get(entry.getKey());
if (!rMap.isEmpty() && !userResources.contains(entry.getKey())) {
double bm25Value = (sim == Similarity.JACCARD ? Utilities.getJaccardFloatSim(targetMap, rMap)
: Utilities.getCosineFloatSim(targetMap, rMap));
entry.setValue(bm25Value);
}
}
// return the sorted resources
if (sorting) {
Map<Integer, Double> sortedResources = new TreeMap<Integer, Double>(new DoubleMapComparator(resources));
sortedResources.putAll(resources);
return sortedResources;
} else {
return resources;
}
}
public static Map<Integer, Double> getSimUsersForResource(int resID, Map<Integer, Double> allUsers,
List<Map<Integer, Double>> userMaps, List<Map<Integer, Double>> resMaps, List<Integer> resourceUsers,
Similarity sim, boolean sorting) {
Map<Integer, Double> users = new LinkedHashMap<Integer, Double>();
Map<Integer, Double> targetMap = null;
if (resID < resMaps.size()) {
targetMap = resMaps.get(resID);
}
if (targetMap == null || targetMap.isEmpty()) {
return users;
}
users.putAll(allUsers);
for (Map.Entry<Integer, Double> entry : users.entrySet()) {
Map<Integer, Double> uMap = userMaps.get(entry.getKey());
if (!uMap.isEmpty() && !resourceUsers.contains(entry.getKey())) {
double simValue = (sim == Similarity.JACCARD ? Utilities.getJaccardFloatSim(targetMap, uMap)
: Utilities.getCosineFloatSim(targetMap, uMap));
entry.setValue(simValue);
}
}
// return the sorted users
if (sorting) {
Map<Integer, Double> sortedUsers = new TreeMap<Integer, Double>(new DoubleMapComparator(users));
sortedUsers.putAll(users);
return sortedUsers;
} else {
return users;
}
}
}