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 Calculate(cUser objUser1, cUser objUser2) { double dotProduct = CalcDotProduct(objUser1, objUser2); double length1 = CalcLength(objUser1); double length2 = CalcLength(objUser2); double cosine = dotProduct / (length1 * length2); return cosine; }
// 计算向量余弦值 public static double Calculate(cUser objUser1, cUser objUser2) { double dotProduct = CalcDotProduct(objUser1, objUser2); double length1 = CalcLength(objUser1); double length2 = CalcLength(objUser2); double cosine = dotProduct / (length1 * length2); return(cosine); }
// 计算向量长度(vector length) private static double CalcLength(cUser objUser) { double length = 0; for (int i = 1; i < 1683; i++) { length += Math.Pow(objUser.Ratings[i], 2); } return Math.Sqrt(length); }
/// <summary> /// 读入训练数据 /// </summary> /// <param name="iTrainFileNumber">数据集的选择</param> private void readTrainData(int iTrainFileNumber) { string sLine = ""; StreamReader rs = null; try { rs = new StreamReader(sTrainFileName[iTrainFileNumber], Encoding.Default); } catch (Exception e) { MessageBox.Show("未找到数据文件", "ERROR"); return; } int user, item, rating; int countUser = 0, prev = 0, countRating = 0; while (sLine != null) { sLine = rs.ReadLine(); if (sLine == null) { objUser[countUser].RatingNums = countRating; break; } string sUser = sLine.Substring(0, sLine.IndexOf('\t')); string temp = sLine.Substring(sUser.Length + 1); string sItem = temp.Substring(0, temp.IndexOf('\t')); temp = sLine.Substring(sUser.Length + sItem.Length + 2, 1); user = int.Parse(sUser); // 新用户 if (prev != user) { prev = user; if (countUser != 0) { objUser[countUser].RatingNums = countRating; } countRating = 0; objUser[++countUser] = new cUser(user); } item = int.Parse(sItem); rating = int.Parse(temp); countRating++; objUser[countUser].Ratings[item] = rating; } // Console.WriteLine("Total User num:{0}", this.objUser.Length); }
// 计算向量长度(vector length) private static double CalcLength(cUser objUser) { double length = 0; for (int i = 1; i < 1683; i++) { length += Math.Pow(objUser.Ratings[i], 2); } return(Math.Sqrt(length)); }
// 计算向量点积(dot product)/内积(inner product) private static double CalcDotProduct(cUser objUser1, cUser objUser2) { double dotProduct = 0; for (int i = 1; i < 1683; i++) { if ((objUser1.Ratings[i] != 0) && (objUser2.Ratings[i] != 0)) dotProduct += objUser1.Ratings[i] * objUser2.Ratings[i]; } return dotProduct; }
public static cAssStrategy getAssStrategy(cUser test_User, int Top_N) { cAssStrategy obj_AssStrategy = new cAssStrategy(); TestUserLoveItems_id = new ArrayList(); TestUserDratItems_id = new ArrayList(); TestUserUnRatingItems_id = new ArrayList(); bool[] isLoved_Test = test_User.discretizeRating(); // 获得推荐项目中用户喜欢的项目数目 float count_interest = 0; int itemid; for (int i = 0; (i < Top_N) && (i < recItems.Length - 1); i++) { itemid = recItems[i + 1].recItems_id; // 用户喜欢该项目 if (isLoved_Test[itemid] == true) { count_interest++; TestUserLoveItems_id.Add(i + 1); } // 用户不喜欢该项目(即对其评分不为零) else if (test_User.Ratings[itemid] != 0) { TestUserDratItems_id.Add(i + 1); } // 用户测试集未对该项目进行评分 else { TestUserUnRatingItems_id.Add(i + 1); } } // 如果推荐列表的长度小于Top_N值 if (recItems.Length < Top_N) { Top_N = recItems.Length; } // 计算查准率 obj_AssStrategy.Precison = (float)(count_interest / (float)Top_N); // 计算查全率 // 测试集中用户喜欢的项目数量 int count_total = test_User.love_items_num; obj_AssStrategy.Recall = (float)(count_interest / (float)count_total); return(obj_AssStrategy); }
// 计算向量点积(dot product)/内积(inner product) private static double CalcDotProduct(cUser objUser1, cUser objUser2) { double dotProduct = 0; for (int i = 1; i < 1683; i++) { if ((objUser1.Ratings[i] != 0) && (objUser2.Ratings[i] != 0)) { dotProduct += objUser1.Ratings[i] * objUser2.Ratings[i]; } } return(dotProduct); }
public static cAssStrategy getAssStrategy(cUser test_User, int Top_N ) { cAssStrategy obj_AssStrategy = new cAssStrategy(); TestUserLoveItems_id = new ArrayList(); TestUserDratItems_id = new ArrayList(); TestUserUnRatingItems_id = new ArrayList(); bool[] isLoved_Test = test_User.discretizeRating(); // 获得推荐项目中用户喜欢的项目数目 float count_interest = 0; int itemid; for (int i = 0; (i < Top_N) && (i < recItems.Length - 1); i++) { itemid = recItems[i+1].recItems_id; // 用户喜欢该项目 if (isLoved_Test[itemid] == true) { count_interest++; TestUserLoveItems_id.Add(i + 1); } // 用户不喜欢该项目(即对其评分不为零) else if (test_User.Ratings[itemid] != 0) { TestUserDratItems_id.Add(i + 1); } // 用户测试集未对该项目进行评分 else { TestUserUnRatingItems_id.Add(i + 1); } } // 如果推荐列表的长度小于Top_N值 if (recItems.Length < Top_N) { Top_N = recItems.Length; } // 计算查准率 obj_AssStrategy.Precison = (float) (count_interest / (float)Top_N); // 计算查全率 // 测试集中用户喜欢的项目数量 int count_total = test_User.love_items_num; obj_AssStrategy.Recall = (float)(count_interest / (float)count_total); return obj_AssStrategy; }
// 最近邻居搜索 private void NNS(cUser objDest, int sim_alg) { cUser[] objUser = new cUser[cReadinData.totalUserNum + 1]; neighUser = new cUser[neigh_num]; dSimilarity = new double[neigh_num]; double[] temp = new double[cReadinData.totalUserNum]; objUser = cReadinData.getBaseUser(); int[] index = new int[neigh_num]; // 相似度算法选择 // 1. 余弦相似度 // 2. Pearson相似度 // 3. 修正的余弦相似度 for (int count = 1; count <= cReadinData.totalUserNum; count++) { if (count == objDest.id) { temp[count - 1] = -1; continue; } if (sim_alg == 1) { temp[count - 1] = Cosine.Calculate(objDest, objUser[count]); } else if (sim_alg == 2) { temp[count - 1] = Pearson.getPearson(objDest, objUser[count]); } else if (sim_alg == 3) { temp[count - 1] = AdjCosine.Calculate(objDest, objUser[count]); } } for (int i = 0; i < neigh_num; i++) { index[i] = SelectMaxIndex(temp); dSimilarity[i] = temp[index[i]]; temp[index[i]] = -1; neighUser[i] = objUser[index[i] + 1]; // Console.WriteLine("id: {0} sim:{1} Rating:{2}",neighUser[i].id, dSimilarity[i], neighUser[i].RatingNums); } }
/// <summary> /// 读入测试数据 /// </summary> /// <param name="iFileNumber">数据集的选择</param> private void readTestData(int iFileNumber) { testUser = new cUser[test_usernum[iFileNumber] + 1]; string sLine = ""; StreamReader rs = new StreamReader(testfileName[iFileNumber], Encoding.Default); int user, item, rating; int countUser = 0, prev = 0, countRating = 0; while (sLine != null) { sLine = rs.ReadLine(); if (sLine == null) { testUser[countUser].RatingNums = countRating; break; } string sUser = sLine.Substring(0, sLine.IndexOf('\t')); string temp = sLine.Substring(sUser.Length + 1); string sItem = temp.Substring(0, temp.IndexOf('\t')); temp = sLine.Substring(sUser.Length + sItem.Length + 2, 1); user = int.Parse(sUser); // 新用户 if (prev != user) { prev = user; if (countUser != 0) { testUser[countUser].RatingNums = countRating; } countRating = 0; testUser[++countUser] = new cUser(user); } item = int.Parse(sItem); rating = int.Parse(temp); countRating++; testUser[countUser].Ratings[item] = rating; } }
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); }
/// <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); }
/// <summary> /// 读入训练数据 /// </summary> /// <param name="iTrainFileNumber">数据集的选择</param> private void readTrainData(int iTrainFileNumber) { string sLine = ""; StreamReader rs = null; try { rs = new StreamReader(sTrainFileName[iTrainFileNumber], Encoding.Default); } catch (Exception e) { MessageBox.Show("未找到数据文件","ERROR"); return; } int user, item, rating; int countUser = 0, prev = 0, countRating = 0; while (sLine != null) { sLine = rs.ReadLine(); if (sLine == null) { objUser[countUser].RatingNums = countRating; break; } string sUser = sLine.Substring(0, sLine.IndexOf('\t')); string temp = sLine.Substring(sUser.Length + 1); string sItem = temp.Substring(0, temp.IndexOf('\t')); temp = sLine.Substring(sUser.Length + sItem.Length + 2, 1); user = int.Parse(sUser); // 新用户 if (prev != user) { prev = user; if (countUser != 0) { objUser[countUser].RatingNums = countRating; } countRating = 0; objUser[++countUser] = new cUser(user); } item = int.Parse(sItem); rating = int.Parse(temp); countRating++; objUser[countUser].Ratings[item] = rating; } // Console.WriteLine("Total User num:{0}", this.objUser.Length); }
// 方法描述:预测目标用户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; }