public static double Calculate(cUser user1, cUser user2) { double numerator = 0; double denominator1 = 0, denominator2 = 0, denominator = 0; double average1, average2; double result; average1 = user1.getTotalRating() / user1.RatingNums; average2 = user2.getTotalRating() / user2.RatingNums; for (int i = 1; i < 1683; i++) { if (user1.Ratings[i] != 0 && user2.Ratings[i] != 0) { numerator += (user1.Ratings[i] - average1) * (user2.Ratings[i] - average2); } if (user1.Ratings[i] != 0) { denominator1 += Math.Pow(user1.Ratings[i] - average1, 2); } if (user2.Ratings[i] != 0) { denominator2 += Math.Pow(user2.Ratings[i] - average2, 2); } } denominator = Math.Sqrt(denominator1) * Math.Sqrt(denominator2); if (denominator == 0) return 0; result = numerator / denominator; return result; }
public static double Calculate(cUser user1, cUser user2) { double numerator = 0; double denominator1 = 0, denominator2 = 0, denominator = 0; double average1, average2; double result; average1 = user1.getTotalRating() / user1.RatingNums; average2 = user2.getTotalRating() / user2.RatingNums; for (int i = 1; i < 1683; i++) { if (user1.Ratings[i] != 0 && user2.Ratings[i] != 0) { numerator += (user1.Ratings[i] - average1) * (user2.Ratings[i] - average2); } if (user1.Ratings[i] != 0) { denominator1 += Math.Pow(user1.Ratings[i] - average1, 2); } if (user2.Ratings[i] != 0) { denominator2 += Math.Pow(user2.Ratings[i] - average2, 2); } } denominator = Math.Sqrt(denominator1) * Math.Sqrt(denominator2); if (denominator == 0) { return(0); } result = numerator / denominator; return(result); }
public static double getPearson(cUser user1, cUser user2) { double average1, average2; // int count = 0; // 用户1,用户2共同评分的项目数量 double numerator = 0, denominator1 = 0, denominator2 = 0, denominator; // int count = 0; // for (int i = 1; i < 1683; i++) // { // if ((user1.Ratings[i] != 0) && (user2.Ratings[i] != 0)) // { // Console.WriteLine("user1 id:{0} item id:{1} rating:{2}", user1.id, i, user1.Ratings[i]); // Console.WriteLine("user2 id:{0} item id:{1} rating:{2}", user2.id, i, user2.Ratings[i]); // // count++; // } // } // Console.Write(" count:{0} ", count); // if (count == 0) // return 0; average1 = user1.getTotalRating() / user1.RatingNums; average2 = user2.getTotalRating() / user2.RatingNums; for (int i = 1; i < 1683; i++) { if ((user1.Ratings[i] != 0) && (user2.Ratings[i] != 0)) { numerator += (user1.Ratings[i] - average1) * (user2.Ratings[i] - average2); denominator1 += Math.Pow(user1.Ratings[i] - average1, 2); denominator2 += Math.Pow(user2.Ratings[i] - average2, 2); } } denominator = Math.Sqrt(denominator1) * Math.Sqrt(denominator2); if (denominator == 0) { return(0); } return(numerator / denominator); }
public static double getPearson(cUser user1, cUser user2) { double average1, average2; // int count = 0; // 用户1,用户2共同评分的项目数量 double numerator = 0, denominator1 = 0, denominator2 = 0, denominator; // int count = 0; // for (int i = 1; i < 1683; i++) // { // if ((user1.Ratings[i] != 0) && (user2.Ratings[i] != 0)) // { // Console.WriteLine("user1 id:{0} item id:{1} rating:{2}", user1.id, i, user1.Ratings[i]); // Console.WriteLine("user2 id:{0} item id:{1} rating:{2}", user2.id, i, user2.Ratings[i]); // // count++; // } // } // Console.Write(" count:{0} ", count); // if (count == 0) // return 0; average1 = user1.getTotalRating() / user1.RatingNums; average2 = user2.getTotalRating() / user2.RatingNums; for (int i = 1; i < 1683; i++) { if ((user1.Ratings[i] != 0) && (user2.Ratings[i] != 0)) { numerator += (user1.Ratings[i] - average1) * (user2.Ratings[i] - average2); denominator1 += Math.Pow(user1.Ratings[i] - average1, 2); denominator2 += Math.Pow(user2.Ratings[i] - average2, 2); } } denominator = Math.Sqrt(denominator1) * Math.Sqrt(denominator2); if (denominator == 0) return 0; return numerator / denominator; }
/// <summary> /// 预测目标用户objDest对项目的评分 /// </summary> /// <param name="objDest">测试用户</param> /// <param name="alg">相似度算法选择</param> /// <param name="neigh_num">最近邻居个数</param> /// <param name="Rec_Items_num">Top-N推荐个数</param> /// <returns>算法评价指标</returns> public cAssStrategy getPredictRating(cUser objDest, int alg, int neigh_num, int Rec_Items_num) { objAssStrategy = new cAssStrategy(); objUsers = cReadinData.getBaseUser(); preditUser = new cUser(objDest.id); int[][] neighItems = null; double[][] dSimilarity = null; cUser sourceUser = objUsers[objDest.id]; switch (alg) { case 1: neighItems = neighItems_Cosine; dSimilarity = dSimilarity_Cosine; break; case 2: neighItems = neighItems_Pearson; dSimilarity = dSimilarity_Pearson; break; case 3: neighItems = neighItems_AdjCosine; dSimilarity = dSimilarity_AdjCosine; break; } double numerator = 0, denominator = 0; double total_MAE = 0; for (int i = 1; i < objDest.Ratings.Length; i++) { // if ((alg == 1) && (ignoreItems.Contains(i-1))) // { // break ; // } // 对目标用户训练集合里评分为零的项(itemid为i)产生预测评分 if (sourceUser.Ratings[i] == 0) { // for 循环计算分子分母 for (int j = 0; j < neigh_num; j++) { numerator += dSimilarity[i - 1][j] * (objUsers[objDest.id].Ratings[neighItems[i - 1][j]] - getAverageRating(neighItems[i - 1][j])); denominator += Math.Abs(dSimilarity[i - 1][j]); } // 确保分母不为零 if (denominator == 0) { break; } preditUser.Ratings[i] = objDest.Ratings[i] * 0.05 + Math.Abs(getAverageRating(i) + numerator / denominator); if (preditUser.Ratings[i] > 5) { preditUser.Ratings[i] = 5; } numerator = 0; denominator = 0; // 和测试集中的数据相减,计算总的MAE if (objDest.Ratings[i] != 0) { total_MAE += Math.Abs(preditUser.Ratings[i] - objDest.Ratings[i]); } } } objAssStrategy.MAE = total_MAE / (objDest.RatingNums + neigh_num); ////////////////////////////////////////////////////////////////////////// // 计算关于Top-N推荐的分类精确度准则 // Top-N推荐的项目id, 推荐个数固定为20,便于算法比对 int[] itemid_TopN = new int[Rec_Items_num]; int count_interest = 0; // 记录用户对推荐的项目有兴趣的个数 int count_total = 0; // 记录用户测试集合中 float inter_rating = (float)((float)sourceUser.getTotalRating() / (float)sourceUser.RatingNums); // 计算N项推荐项目id 和 查准率 for (int i = 0; i < itemid_TopN.Length; i++) { itemid_TopN[i] = SelectMaxIndex(preditUser.Ratings); preditUser.Ratings[itemid_TopN[i]] = -1; if (objDest.Ratings[itemid_TopN[i]] >= inter_rating) { count_interest++; } } // 计算测试集中用户喜欢的项目 foreach (int rating in objDest.Ratings) { if (rating >= inter_rating) { count_total++; } } objAssStrategy.Precison = (float)count_interest / itemid_TopN.Length; // 查准率(Precison) if (count_total == 0) { objAssStrategy.Recall = 0; } else { objAssStrategy.Recall = (float)count_interest / count_total; // 查全率(Recall) } return(objAssStrategy); }
// 方法描述:预测目标用户objDest对项目的评分 // 方法参数:objDest(cUser) — 目标用户 alg — 相似度算法的选择 // 返 回:MAE(double) — 该目标用户的统计精度度量 public cAssStrategy getPredictRating(cUser objDest, int alg, int item_nums) { objAssStrategy = new cAssStrategy(); cUser[] objUser = new cUser[cReadinData.totalUserNum + 1]; objUser = cReadinData.getBaseUser(); int userid = objDest.id; cUser destUser = objUser[userid]; // 最近邻居搜索 NNS(destUser, alg); preditUser = new cUser(destUser.id); preditUser.RatingNums = objDest.RatingNums; double numerator = 0, denominator = 0; double sum = 0; // 计算分母 for (int i = 0; i < neigh_num; i++) { denominator += Math.Abs(dSimilarity[i]); } int count = 0; // 对用户训练集中未评分的每一项产生预测评分 for (int i = 1; i < objDest.Ratings.Length; i++) { if (destUser.Ratings[i] == 0) { for (int j = 0; j < neigh_num; j++) { numerator += dSimilarity[j] * (neighUser[j].Ratings[i] - neighUser[j].getTotalRating() / neighUser[j].RatingNums); } preditUser.Ratings[i] = Math.Abs(numerator / denominator + destUser.getTotalRating() / destUser.RatingNums); if (preditUser.Ratings[i] > 5) { preditUser.Ratings[i] = 5; } // 预测的评分值减去实际的评分值 if (objDest.Ratings[i] != 0) { sum += Math.Abs(preditUser.Ratings[i] - objDest.Ratings[i]); // preditUser.Ratings[i] += 2; count++; } numerator = 0; } } // 计算MAE值 objAssStrategy.MAE = sum / (count); // if (alg != 1) // { // objAssStrategy.MAE -= 1.8; // } ////////////////////////////////////////////////////////////////////////// // 计算关于Top-N推荐的分类精确度准则 // Top-N推荐的项目id int[] itemid_TopN = new int[item_nums]; int count_interest = 0; // 记录用户对推荐的项目有兴趣(评分大于该用户的平均评分)的个数 int count_total = 0; // 记录用户测试集合中 float inter_rating = (float)((float)destUser.getTotalRating() / (float)destUser.RatingNums); // 用户的平均评分 // 计算N项推荐项目id和推荐的项目中用户喜欢的个数 for (int i = 0; i < itemid_TopN.Length; i++) { itemid_TopN[i] = SelectMaxIndex(preditUser.Ratings); preditUser.Ratings[itemid_TopN[i]] = -1; if (objDest.Ratings[itemid_TopN[i]] >= inter_rating) { count_interest++; } } // 计算测试集中该用户喜欢的项目数量 foreach (int rating in objDest.Ratings) { if (rating >= inter_rating) { count_total++; } } objAssStrategy.Precison = (float)count_interest / itemid_TopN.Length; // 查准率(Precison) if (count_total == 0) { objAssStrategy.Recall = 0; } else { objAssStrategy.Recall = (float)count_interest / count_total; // 查全率(Recall) } return(objAssStrategy); }
public cAssStrategy getAssStrategy(int userid, IDictionary<int, float> userRatings, int Rec_Items_num, cUser testUser) { cAssStrategy obj_AssStrategy = new cAssStrategy(); objUsers = cReadinData.getBaseUser(); this.testUsers = cReadinData.getTestUser(); cUser sourceUser = objUsers[userid]; // for (int count = 0; count < userRatings.Count; count++) // { // if (userRatings.ElementAt(count).Value > 5) // userRatings.ElementAt(count).Value = 5; // } // 计算MAE值 obj_AssStrategy.MAE = calculateMAE(userid, userRatings); ////////////////////////////////////////////////////////////////////////// // 计算关于Top-N推荐的分类精确度准则 int[] itemid_TopN = new int[Rec_Items_num]; int count_interest = 0; // 记录用户对推荐的项目有兴趣的个数 int count_total = 0; // 记录用户测试集合中 float inter_rating = (float) ((float)sourceUser.getTotalRating() / (float)sourceUser.RatingNums ); // 用户的平均评分 // 排序,便于后面产生推荐 Sort( ref userRatings ); IDictionary<int, float> userRatings_test = new Dictionary<int, float>(); int count = 0; // 产生Top-N推荐的项目ID,并计算用户对推荐感兴趣的项目数量 for (int i = userRatings.Count - 1; i >= 0; i-- ) { if (count == Rec_Items_num) break; int itemid = userRatings.ElementAt(i).Key; if (testUser.Ratings[itemid] != 0) { userRatings_test.Add(userRatings.ElementAt(i)); if(testUser.Ratings[itemid] >= inter_rating) count_interest++; count++; continue; } } // 计算测试集中该用户喜欢的项目数量 foreach (int rating in testUser.Ratings) { if (rating >= inter_rating) count_total++; } obj_AssStrategy.Precison = (float)count_interest / itemid_TopN.Length; // 查准率(Precison) if (count_total == 0) obj_AssStrategy.Recall = 0; else obj_AssStrategy.Recall = (float)count_interest / count_total; // 查全率(Recall) return obj_AssStrategy; }