package processing.hashtag.social; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import cc.mallet.util.FileUtils; import common.DoubleMapComparator; public class SocialLinkWeightCalculator { private HashMap<String, HashMap<Integer, ArrayList<Long>>> userTagTimes; private HashMap<String, ArrayList<String>> network; private List<String> users; private HashMap<String, HashMap<String, ArrayList<Long>>> mapUserMentionTimestamps; private HashMap<String, HashMap<String, ArrayList<Long>>> mapUserRetweetTimestamps; private HashMap<String, HashMap<String, ArrayList<Long>>> mapUserReplyTimestamps; public SocialLinkWeightCalculator(HashMap<String, HashMap<Integer, ArrayList<Long>>> userTagTimes, HashMap<String, ArrayList<String>> network, List<String> users, String mentionFilename, String retweetFilename, String replyFilename) { this.userTagTimes = userTagTimes; this.network = network; this.users = users; populateUserRelationMap(mentionFilename, retweetFilename, replyFilename); } /** * Get a ranked weight of tag and their score. * * @param userId * the userId of the user for whom we want to get the * recommendation. * @param timestamp * the long value of timestamp for which you want to get the * recommendation. * @param whether * the returned map should be in the sorted order of values. **/ public Map<Integer, Double> getRankedTagListSocialLinkWeight(int userId, long timestamp, boolean sort) { String user = this.users.get(userId); List<String> friendList = network.get(user); HashMap<Integer, Double> tagRank = new HashMap<Integer, Double>(); Map<Integer, Double> sortedResultMap = new HashMap<Integer, Double>(); if (friendList == null) { System.out.println("friendlist is null >> "); sortedResultMap = new TreeMap<Integer, Double>(new DoubleMapComparator(tagRank)); sortedResultMap.putAll(tagRank); } else { System.out.println("friendlist not null >> "); tagRank = getTagWeightMap(user, friendList, timestamp); tagRank = getNormalizedTagWeightMap(tagRank); sortedResultMap = new TreeMap<Integer, Double>(new DoubleMapComparator(tagRank)); sortedResultMap.putAll(tagRank); } System.out.println("sorted Result Map >> " + sortedResultMap); return sortedResultMap; } /** * Get normalised tag weight map. * * @param * @return {@link HashMap} of noramlised values of the tag weights. **/ private HashMap<Integer, Double> getNormalizedTagWeightMap(HashMap<Integer, Double> tagRank) { double denom = 0.0; if (tagRank != null) { for (Map.Entry<Integer, Double> entry : tagRank.entrySet()) { if (entry != null) { double actVal = Math.log(entry.getValue()); denom += Math.exp(actVal); entry.setValue(actVal); } } for (Map.Entry<Integer, Double> entry : tagRank.entrySet()) { if (entry != null) { double actVal = Math.exp(entry.getValue()); entry.setValue(actVal / denom); } } } return tagRank; } /** * Get the tag weight. * * @param friendList * {@link List} of friends for a given user. * @param tagRank * the ran **/ private HashMap<Integer, Double> getTagWeightMap(String user, List<String> friendList, long timestamp) { HashMap<Integer, Double> tagRank = new HashMap<Integer, Double>(); for (String friend : friendList) { HashMap<Integer, ArrayList<Long>> tagTimestampMap = userTagTimes.get(friend); if (tagTimestampMap != null) { for (Integer tag : tagTimestampMap.keySet()) { ArrayList<Long> timestampList = tagTimestampMap.get(tag); // if the hashtag is used by the friend before the current // usage then we add the weight of the hashtag to the usage. for (Long timestampLong : timestampList) { if (tagRank.containsKey(tag)) { tagRank.put(tag, tagRank.get(tag) + getTagWeight(user, friend, "hybrid")); ; } else { tagRank.put(tag, getTagWeight(user, friend, "hybrid")); } break; // once the hashtag used is detected we add the weight equal to the retweet value. } } } } return tagRank; } /** * Get the tag weight based on the userId, friend and weightType. * * @param userId * @param friend * @param weightType * @return {@link Double} the weight which id independent of the tag and * just depend on the relation strength between 2 users. */ private double getTagWeight(String userId, String friend, String weightType) { double weight = 0; if ("retweet".equals(weightType)) { if (mapUserRetweetTimestamps.get(userId) != null) { System.out.println("user timestamp not null >> "); if (mapUserRetweetTimestamps.get(userId).get(friend) != null) { weight = mapUserRetweetTimestamps.get(userId).get(friend).size(); System.out.println("weight not zero >> " + weight); } else { weight = 0; } } } else if ("mention".equals(weightType)) { if (mapUserMentionTimestamps.get(userId) != null) { if (mapUserMentionTimestamps.get(userId).get(friend) != null) { weight = mapUserMentionTimestamps.get(userId).get(friend).size(); System.out.println("weight not zero >> " + weight); } else { weight = 0; } } } else if ("reply".equals(weightType)) { if (mapUserReplyTimestamps.get(userId) != null) { if (mapUserReplyTimestamps.get(userId).get(friend) != null) { weight = mapUserReplyTimestamps.get(userId).get(friend).size(); } else { weight = 0; } } } else if ("hybrid".equals(weightType)) { if (mapUserReplyTimestamps.get(userId) != null) { if (mapUserReplyTimestamps.get(userId).get(friend) != null) { weight += mapUserReplyTimestamps.get(userId).size(); } } if (mapUserMentionTimestamps.get(userId) != null) { if (mapUserMentionTimestamps.get(userId).get(friend) != null) { weight += mapUserMentionTimestamps.get(userId).size(); } } if (mapUserRetweetTimestamps.get(userId) != null) { if (mapUserRetweetTimestamps.get(userId).get(friend) != null) { weight += mapUserRetweetTimestamps.get(userId).size(); } } } return weight; } /** * Populate mention list for users. * * @param mentionFilename * the filename of the mention list of users **/ private void populateUserMentionMap(String mentionFilename) { mapUserMentionTimestamps = new HashMap<String, HashMap<String, ArrayList<Long>>>(); ArrayList<RelationItem> relations = getRelationItemList(mentionFilename); String initUsername = ""; String targetUsername = ""; for (RelationItem item : relations) { initUsername = item.getInitUser(); targetUsername = item.getTargetUser(); if (!mapUserMentionTimestamps.containsKey(initUsername)) { mapUserMentionTimestamps.put(initUsername, new HashMap<String, ArrayList<Long>>()); } if (!mapUserMentionTimestamps.get(initUsername).containsKey(targetUsername)) { mapUserMentionTimestamps.get(initUsername).put(targetUsername, new ArrayList<Long>()); } mapUserMentionTimestamps.get(initUsername).get(targetUsername).add(item.getCreatedAt().getTime()); } } /** * Populate retweet list of users. * * @param retweetFilename * the filename of the retweet list of users */ private void populateUserRetweetMap(String retweetFilename) { mapUserRetweetTimestamps = new HashMap<String, HashMap<String, ArrayList<Long>>>(); ArrayList<RelationItem> relations = getRelationItemList(retweetFilename); String initUsername = ""; String targetUsername = ""; for (RelationItem item : relations) { initUsername = item.getInitUser(); targetUsername = item.getTargetUser(); if (!mapUserRetweetTimestamps.containsKey(initUsername)) { mapUserRetweetTimestamps.put(initUsername, new HashMap<String, ArrayList<Long>>()); } if (!mapUserRetweetTimestamps.get(initUsername).containsKey(targetUsername)) { mapUserRetweetTimestamps.get(initUsername).put(targetUsername, new ArrayList<Long>()); } mapUserRetweetTimestamps.get(initUsername).get(targetUsername).add(item.getCreatedAt().getTime()); } } /** * Populate reply list of users. * * @param replyFilename * the filename of the reply list of users */ private void populateUserReplyMap(String replyFilename) { mapUserReplyTimestamps = new HashMap<String, HashMap<String, ArrayList<Long>>>(); ArrayList<RelationItem> relations = getRelationItemList(replyFilename); String initUsername = ""; String targetUsername = ""; for (RelationItem item : relations) { initUsername = item.getInitUser(); targetUsername = item.getTargetUser(); if (!mapUserReplyTimestamps.containsKey(initUsername)) { mapUserReplyTimestamps.put(initUsername, new HashMap<String, ArrayList<Long>>()); } if (!mapUserReplyTimestamps.get(initUsername).containsKey(targetUsername)) { mapUserReplyTimestamps.get(initUsername).put(targetUsername, new ArrayList<Long>()); } mapUserReplyTimestamps.get(initUsername).get(targetUsername).add(item.getCreatedAt().getTime()); } } /** * Populate all the list. * * @param mentionFilename * @param retweetFilename * @param replyFilename * the filename * @return void */ private void populateUserRelationMap(String mentionFilename, String retweetFilename, String replyFilename) { populateUserMentionMap(mentionFilename); populateUserRetweetMap(retweetFilename); populateUserReplyMap(replyFilename); } /** * Get relation item list from the filename. * * @param filename * @return return the list of {@link RelationItem} **/ private ArrayList<RelationItem> getRelationItemList(String filename) { ArrayList<RelationItem> relationItems = new ArrayList<RelationItem>(); DateFormat formater = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss"); File file = new File(filename); try { String[] lines = FileUtils.readFile(file); for (String line : lines) { String[] tokens = line.split("\t"); RelationItem relationItem = new RelationItem(); try { relationItem.setId(Integer.parseInt(tokens[0])); } catch (NumberFormatException exc) { System.out.println("error parsing relation id > " + tokens[0]); } try { relationItem.setInitUser(tokens[1]); } catch (NumberFormatException exc) { System.out.println("error parsing init user > " + tokens[1]); } try { relationItem.setTargetUser(tokens[2]); } catch (NumberFormatException exc) { System.out.println("error parsing target user > " + tokens[2]); } try { relationItem.setTweetId(Long.parseLong(tokens[3])); } catch (NumberFormatException exc) { System.out.println("error parsing tweet id> " + tokens[3]); } try { relationItem.setCreatedAt(formater.parse(tokens[4])); } catch (ParseException e) { e.printStackTrace(); } relationItems.add(relationItem); } } catch (IOException e) { e.printStackTrace(); } return relationItems; } }