public static double CosineScore(SuggestorUser user, SuggestorUser otherUser) { // TF-IDF Dictionary<string, SuggestorCollectionLine> mutualLines = new Dictionary<string, SuggestorCollectionLine>(); mutualLines = user.CollectionLines.Keys.Intersect(otherUser.CollectionLines.Keys).ToDictionary(t => t, t => user.CollectionLines[t]); double cosScore = 0; double termProductSum = 0; foreach (string lineId in mutualLines.Keys) { termProductSum += user.CollectionLines[lineId].Weight * otherUser.CollectionLines[lineId].Weight; } double vectorNormalizingMultiplication = (GetSize(user) * GetSize(otherUser)); if (vectorNormalizingMultiplication == 0) return 0; cosScore = termProductSum / vectorNormalizingMultiplication; return cosScore; }
/* private Dictionary<SuggestorCollection, double> FindClosestInvoices(Dictionary<string, SuggestorCollection> collections, SuggestorCollection compareCollection, int n) { // TODO: Disgusting code Dictionary<SuggestorCollection, double> topInvoices = new Dictionary<SuggestorCollection, double>(); List<SuggestorCollection> compareInvoices = collections.Values.ToList(); compareInvoices.Remove(compareCollection); // Calculate all weights // TODO: Cache this. Per instance? foreach (SuggestorCollection invoice in compareInvoices) { topInvoices.Add(invoice, SuggestorCollectionFunctions.CosineScore(invoice, compareCollection)); } List<KeyValuePair<SuggestorCollection, double>> topValues = topInvoices.ToList(); topValues.Sort((firstPair, nextPair) => { return firstPair.Value.CompareTo(nextPair.Value); }); topValues.Reverse(); Dictionary<SuggestorCollection, double> returnInvoices = new Dictionary<SuggestorCollection, double>(); for (int i = 0; i < n; i++) { if (topValues[i].Value != 0) returnInvoices.Add(topValues[i].Key, topValues[i].Value); } return returnInvoices; } public Dictionary<string, double> GetRecommendedItems(SuggestorCollection compareInvoice) { if (compareInvoice.GetCollectionLines().Count == 0) return null; Dictionary<string, double> itemAggregation = new Dictionary<string, double>(); Dictionary<SuggestorCollection, double> topInvoices = FindClosestInvoices(compareInvoice, 10); foreach (SuggestorCollection invoice in topInvoices.Keys) { foreach (string itemNo in invoice.GetCollectionLines().Keys) { if (compareInvoice.GetCollectionLines().ContainsKey(itemNo)) continue; // Ignore items that are already in basket if (!(itemAggregation.ContainsKey(itemNo))) itemAggregation.Add(itemNo, 1); itemAggregation[itemNo]++; //itemAggregation[itemNo] += topInvoices[invoice] * 1.0; } } List<KeyValuePair<string, double>> itemAggregationList = itemAggregation.ToList(); // Sort dictionary by value itemAggregationList.Sort((firstPair, nextPair) => { return firstPair.Value.CompareTo(nextPair.Value); }); itemAggregationList.Reverse(); itemAggregation = itemAggregationList.ToDictionary(pair => pair.Key, pair => pair.Value); return itemAggregation; }*/ public override Dictionary<SuggestorUser, double> SuggestNUsers(List<SuggestorUser> users, SuggestorUser user, int n) { throw new NotImplementedException(); }
public Dictionary<SuggestorUser, double> SuggestUsers(List<SuggestorUser> usersToCompareTo, SuggestorUser user, int n) { return recommenderEngine.SuggestNUsers(usersToCompareTo, user, n); }
public override Dictionary<SuggestorUser, double> SuggestNUsers(List<SuggestorUser> users, SuggestorUser compareUser, int n) { // TODO: Disgusting code Dictionary<SuggestorUser, double> topUsers = new Dictionary<SuggestorUser, double>(); List<SuggestorUser> compareUsers = users.ToList(); compareUsers.Remove(compareUser); // TODO: Cache this. Per instance? foreach (SuggestorUser user in compareUsers) { // Find cosine similarity between users lines and other users lines topUsers.Add(user, SuggestorCollectionFunctions.CosineScore(user, compareUser)); } List<KeyValuePair<SuggestorUser, double>> topValues = topUsers.ToList(); topValues.Sort((firstPair, nextPair) => { return firstPair.Value.CompareTo(nextPair.Value); }); topValues.Reverse(); Dictionary<SuggestorUser, double> returnUsers = new Dictionary<SuggestorUser, double>(); foreach (KeyValuePair<SuggestorUser, double> pair in topValues.Take(n)) { //if (topValues[i].Value != 0) //returnUsers.Add(topValues[i].Key, topValues[i].Value); returnUsers.Add(pair.Key, pair.Value); } return returnUsers; }
public static double GetSize(SuggestorUser user) { double squaredSum = 0; foreach (SuggestorCollectionLine line in user.CollectionLines.Values) { squaredSum += Math.Pow(line.Weight, 2); } return Math.Sqrt(squaredSum); }
public abstract Dictionary<SuggestorUser, double> SuggestNUsers(List<SuggestorUser> users, SuggestorUser user, int n);