package processing.hashtag.social;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import common.DoubleMapComparator;
public class SocialRecencyRecommender {
private HashMap<String, HashMap<Integer, ArrayList<Long>>> userTagTimes;
private HashMap<String, ArrayList<String>> network;
private List<String> users;
/**
* Constructor
* @param userTagTimes the map of users to the tags to the timestamp list.
* @param network the underlying user network.
* @param users list of userids.
* */
public SocialRecencyRecommender(HashMap<String, HashMap<Integer, ArrayList<Long>>> userTagTimes,
HashMap<String, ArrayList<String>> network, List<String> users){
this.userTagTimes = userTagTimes;
this.network = network;
this.users = users;
}
/**
* Get the weighted map of the tags for a given userid and timestamp.
* @param userId integer user id of the user for which we want to get the recommendation.
* @param timestamp corresponding to which we want to get the recommendation.
* @return {@link Map} A map of tag to the weight of the tag for given users and timestamp.
**/
public Map<Integer, Double> getRankedTagListSocialRecency(int userId, long timestamp, boolean sort) {
HashMap<Integer, ArrayList<Long>> tagTimestampMapAllFriend = getAllFriendTagTimestampsMapSocialRecency(userId);
HashMap<Integer, Long> mostRecentTimestampMap = getMostRecentTagTimestampSocialRecency(timestamp,
tagTimestampMapAllFriend);
Long maxValue = getMaxValue(mostRecentTimestampMap);
HashMap<Integer, Double> resultMap = getNormalisedTagWeightSocialRecency(mostRecentTimestampMap, maxValue);
if (sort) {
Map<Integer, Double> sortedResultMap = new TreeMap<Integer, Double>(new DoubleMapComparator(resultMap));
sortedResultMap.putAll(resultMap);
return sortedResultMap;
} else {
return resultMap;
}
}
/**
* Merge all the tag timestamps for a users in a single Hashmap.
* @param userId user id of user for whom we want to get the tag timestamp map for all her friend.
* @return {@link HashMap} of tags and timestamp list of their usage.
* */
private HashMap<Integer, ArrayList<Long>> getAllFriendTagTimestampsMapSocialRecency(int userId) {
HashMap<Integer, ArrayList<Long>> tagTimestampMapAllFriend = new HashMap<Integer, ArrayList<Long>>();
String user = this.users.get(userId);
List<String> friendList = network.get(user);
if (friendList != null) {
for (String friend : friendList) {
HashMap<Integer, ArrayList<Long>> tagTimestmapMapSingleFriend = userTagTimes.get(friend);
if (tagTimestmapMapSingleFriend != null) {
for (Integer tag : tagTimestmapMapSingleFriend.keySet()) {
if (!tagTimestampMapAllFriend.containsKey(tag)) {
tagTimestampMapAllFriend.put(tag, new ArrayList<Long>());
} else {
tagTimestampMapAllFriend.get(tag).addAll(tagTimestmapMapSingleFriend.get(tag));
}
}
}
}
}
sortHashMapListSocialRecency(tagTimestampMapAllFriend);
return tagTimestampMapAllFriend;
}
/**
* From the list of tag and their timestamp, get the Hashmap of tag mapped to it most recent timestamp
* since the occurence of the given timestamp.
* @param timestamp the timestamp when the given
* @param tagTimestampMapAllFriend get the tag to timestamps map for all the friend of a user.
* @return {@link HashMap} of tag to the most recent timestamp
**/
private HashMap<Integer, Long> getMostRecentTagTimestampSocialRecency(long timestamp,
HashMap<Integer, ArrayList<Long>> tagTimestampMapAllFriend) {
HashMap<Integer, Long> mostRecentTimestampMap = new HashMap<Integer, Long>();
for (Integer tag : tagTimestampMapAllFriend.keySet()) {
ArrayList<Long> tagTimestampList = tagTimestampMapAllFriend.get(tag);
for (Long tagTimestamp : tagTimestampMapAllFriend.get(tag)) {
if (tagTimestamp > timestamp) {
mostRecentTimestampMap.put(tag, tagTimestamp - timestamp);
break;
} else {
continue;
}
}
}
return mostRecentTimestampMap;
}
/**
* Sort the {@link ArrayList} in the value part of the {@link HashMap}
* @param tagTimestampMapAllFriend a map containing the tag and timestamps list.
* @return {@link Void}
***/
private void sortHashMapListSocialRecency(HashMap<Integer, ArrayList<Long>> tagTimestampMapAllFriend) {
for (Integer tag : tagTimestampMapAllFriend.keySet()) {
Collections.sort(tagTimestampMapAllFriend.get(tag));
}
}
/**
* Get the normalised values of the corresponding to the maximum value provided as the parameter.
* @param mostRecentTimestampMap most recent timestamp value when a hashtag is used corresponding to the given timestamp.
* @param maxValue maxValue of the recent timestamp.
* @return {@link HashMap} A hashmap which contains the normalised weights of the tags.
* **/
private HashMap<Integer, Double> getNormalisedTagWeightSocialRecency(HashMap<Integer, Long> mostRecentTimestampMap,
Long maxValue) {
HashMap<Integer, Double> resultMap = new HashMap<Integer, Double>();
for (Integer tag : mostRecentTimestampMap.keySet()) {
Double weight = (double) maxValue - mostRecentTimestampMap.get(tag);
resultMap.put(tag, weight);
}
return resultMap;
}
/**
* Get the maximum value among all the values in a HashMap of comparable values.
* @param mostRecentTimestampMap {@link HashMap} the hashmap with each value corresponding
* the timestamp when the hashmap was last used.
* @return the maximum value among all the Long values in value list.
* */
private Long getMaxValue(HashMap<Integer, Long> mostRecentTimestampMap) {
Long maxValue = new Long(0);
for (Integer tag : mostRecentTimestampMap.keySet()) {
if (maxValue < mostRecentTimestampMap.get(tag)) {
maxValue = mostRecentTimestampMap.get(tag);
} else {
continue;
}
}
return maxValue;
}
}