public double calculateSimilarity(ISimilarityMethod predictionMethod, User thisUser, User candidateUser) { double similarity = 0; if (!similarityNNDic.ContainsKey(predictionMethod)) { similarityNNDic.Add(predictionMethod, new Dictionary <User, Dictionary <User, double> >()); } if (!similarityNNDic[predictionMethod].ContainsKey(thisUser)) { similarityNNDic[predictionMethod].Add(thisUser, new Dictionary <User, double>()); } if (similarityNNDic[predictionMethod][thisUser].ContainsKey(candidateUser)) { return(similarityNNDic[predictionMethod][thisUser][candidateUser]); } List <string> thisUserList = thisUser.GetRatedItems(); List <string> commonItemsList = candidateUser.GetRatedItems().Intersect(thisUserList).ToList(); if (commonItemsList.Count > commonItemsThreshold) { similarity = predictionMethod.calculateSimilarity(thisUser, candidateUser, commonItemsList); } similarityNNDic[predictionMethod][thisUser].Add(candidateUser, similarity); return(similarity); }
public CollaborativeFilteringModel(Users users, Items items, SimilarityEngine similarityEngine, ISimilarityMethod predictionMethod) { this.similarityEngine = similarityEngine; this.users = users; this.items = items; this.predictionMethod = predictionMethod; }
private List <string> GetTopItemsBasedNN(ISimilarityMethod similarityMethod, string sUserId, int cRecommendations) { Dictionary <string, double> itemScore = new Dictionary <string, double>(); int k = 20; //number of NN //Select an item only if one of the neighbors has rated it User currentUser = testUsers.getUserById(sUserId); var NNList = trainUsers.Where(user => !user.Equals(currentUser)); var NNListDic = NNList.ToDictionary(user => user, user => similarityEngine.calculateSimilarity(similarityMethod, currentUser, user)); var NNListOrderedDic = NNListDic.OrderByDescending(user => user.Value); var NNTopK = NNListOrderedDic.Take(k); //For each item that rated by one of the neighbors, calculate the normalized rating score foreach (var user in NNTopK) { double weight = user.Value; var itemList = user.Key.GetRatedItems(); foreach (var item in itemList) { if (!itemScore.ContainsKey(item)) { itemScore.Add(item, weight); } else { itemScore[item] += weight; } } } var orderedItemScore = itemScore.OrderByDescending(item => item.Value); return(orderedItemScore.Select(item => item.Key).Take(cRecommendations).ToList());; }
public List <KeyValuePair <User, double> > calculateSimilarity(ISimilarityMethod predictionMethod, User thisUser, List <User> candidateUsers, bool revertSimilarities = false, bool isStereotype = false) { if (predictionMethod == null || thisUser == null) { throw new ArgumentNullException("IPredictionMethod predictionMethod, User thisUser must both be not null!"); } if (!isStereotype) { if (!similarityDic.ContainsKey(predictionMethod)) { similarityDic.Add(predictionMethod, new Dictionary <User, List <KeyValuePair <User, double> > >()); } if (similarityDic[predictionMethod].ContainsKey(thisUser)) { return(similarityDic[predictionMethod][thisUser]); } } logger.debug("calcualting similarity for user " + "[" + thisUser.GetId() + "]"); Stopwatch timer = Stopwatch.StartNew(); UsersSimilarity similarUsers = new UsersSimilarity(MAX_SIMILAR_USERS); var thisUserList = thisUser.GetRatedItems(); var similarUsersCount = 0; foreach (var thatUser in candidateUsers) { if (thatUser != null && !thisUser.Equals(thatUser)) { List <string> thatUserList = thatUser.GetRatedItems(); List <string> commonItemsList = thatUserList.Intersect(thisUserList).ToList(); //check if both users rated at least one common item if (commonItemsList.Count >= commonItemsThreshold && thatUserList.Count > 0 && thisUserList.Count > 0) { var similarity = predictionMethod.calculateSimilarity(thisUser, thatUser, commonItemsList); if (revertSimilarities == true) { similarity *= -1; } if (similarity > 0) //in some cases the users rate their common item the same as their average then we can get here zero { similarUsers.add(thatUser, similarity); similarUsersCount++; } } } } timer.Stop(); logger.debug("Similarity calculation time for user" + " [" + thisUser.GetId() + "] " + timer.Elapsed); if (!isStereotype) { similarityDic[predictionMethod].Add(thisUser, similarUsers.AsList()); //Eyal return descending sorted list here } return(similarUsers.AsList()); }
public List <KeyValuePair <User, double> > calculateSimilarity(ISimilarityMethod predictionMethod, User thisUser, List <string> candidateUsersIds) { if (!similarityDic.ContainsKey(predictionMethod)) { similarityDic.Add(predictionMethod, new Dictionary <User, List <KeyValuePair <User, double> > >()); } List <User> candidateUsers = candidateUsersIds.Select(userId => users.getUserById(userId)).Where(user => user != null).ToList(); return(calculateSimilarity(predictionMethod, thisUser, candidateUsers)); }
public StereotypesModel(SimilarityEngine similarityEngine, ISimilarityMethod similarityMethod, Users users, Items items, int cStereotypes) { this.randomGenerator = new RandomGenerator(); this.similarityEngine = similarityEngine; this.similarityMethod = similarityMethod; this.CENTROIDS_SIMILARITY_THRESHOLD = 0.99; // double.Parse(ConfigurationManager.AppSettings["CentroidsSimilarityThreshold"]); this.MAX_ITERATION = 20; // int.Parse(ConfigurationManager.AppSettings["maxNumIterationStereotype"]); this.minimumRatingThreshold = 50; // int.Parse(ConfigurationManager.AppSettings["minimumRatingThreshold"]); this.users = users; this.items = items; this.cStereotypes = cStereotypes; similarityDic = new Dictionary <User, User>(); }