谁能告诉我 mahout 的 RecommenderIRStatsEvaluator 是如何工作的?更具体地说,它如何随机分割训练和测试数据以及结果与哪些数据进行比较?根据我的理解,您需要某种理想/预期结果,您需要将其与推荐算法的实际结果进行比较,以找出 TP 或 FP,从而计算精度或召回率。但看起来 mahout 提供的精确度/召回率分数没有理想/结果。
1 回答
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 统计数据(精度和召回率)时非常棘手,特别是如果每个用户的用户偏好数量很少。在本书中,您可以找到非常有用的见解。它说
通常假设不喜欢的项目即使被推荐也不会被喜欢,即它们对用户来说是无趣的或无用的。然而,这可能不是真的,因为不喜欢的项目集可能包含一些用户没有选择的有趣项目。例如,用户可能不喜欢某个项目,因为他不知道它的存在,但是在推荐暴露了该项目之后,用户可以决定选择它。在任何情况下,当使用 IR 统计时,FP 的数量都被高估了。