有谁能告诉我mahout的RecommenderIRStatsEvaluator是如何工作的?更具体地说,它是如何随机分割训练和测试数据以及结果与哪些数据进行比较的?基于我的不足,您需要某种理想/预期的结果,您需要将其与推荐算法的实际结果进行比较,以找出TP或FP 从而计算精度或召回率。但看起来mahout提供的精确/召回得分没有理想/结果。
答案 0 :(得分:9)
使用您在evaluate
类的RecommenderIRStatsEvaluator
方法中提供的相关阈值,将数据拆分为训练和测试集。如果此值为null
,则有计算它的方法(computeThreshold
)。将数据拆分为训练和测试的类是GenericRelevantItemsDataSplitter
。如果您查看代码,您可以看到,首先根据值按降序对每个用户的首选项进行排序,而只将具有大于relevanceThreshold
的值的那些首选项视为相关。另请注意,最多at
被放入此集合中。
@Override
public FastIDSet getRelevantItemsIDs(long userID,
int at,
double relevanceThreshold,
DataModel dataModel) throws TasteException {
PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
FastIDSet relevantItemIDs = new FastIDSet(at);
prefs.sortByValueReversed();
for (int i = 0; i < prefs.length() && relevantItemIDs.size() < at; i++) {
if (prefs.getValue(i) >= relevanceThreshold) {
relevantItemIDs.add(prefs.getItemID(i));
}
}
return relevantItemIDs;
}
如何计算精度和召回率,您可以在RecommenderIRStatsEvaluator.evaluate
方法中看到。简而言之就是这样:
首先,一次只评估一个用户。他的偏好值被分为相关(如上所述)和其他。相关的用作测试集,另一个用作所有其他用户的培训。然后为该用户生成top-at
个推荐。接下来,该方法会查看作为测试集的一些项目是否出现在建议中,以及有多少:
int intersectionSize = 0;
List<RecommendedItem> recommendedItems = recommender.recommend(userID, at, rescorer);
for (RecommendedItem recommendedItem : recommendedItems) {
if (relevantItemIDs.contains(recommendedItem.getItemID())) {
intersectionSize++;
}
}
精度比计算如下:
(double) intersectionSize / (double) numRecommendedItems
numRecommendedItems
通常是at
,如果推荐人至少提出at
推荐,那么就更小。
类似地,召回计算如下:
(double) intersectionSize / (double) numRelevantItems
其中numRelevantItems
是此用户的测试集中的项目数。
最终的精确度和召回率是所有用户的所有精度和召回的宏观平均值。
希望这能回答你的问题。
编辑:继续提问,在评估推荐系统的IR统计信息(精确度和召回率)时非常棘手,特别是如果每个用户的用户偏好数量较少。在此book中,您可以找到非常有用的见解。它说
通常假设不喜欢的物品不会 即使他们被推荐也很喜欢,即他们对用户来说是无趣或无用的。然而,这可能不是真的,因为一组不喜欢的项目可能包含一些用户未选择的有趣项目。例如,用户可能不喜欢某个项目,因为他不知道它的存在,但是在推荐该项目之后,用户可以决定选择它。在使用IR统计数据的任何情况下,FP的数量都被高估了。