在推荐系统的皮尔逊相关用户-用户相似度矩阵中,NaN 是如何处理的?

Posted

技术标签:

【中文标题】在推荐系统的皮尔逊相关用户-用户相似度矩阵中,NaN 是如何处理的?【英文标题】:How is NaN handled in Pearson correlation user-user similarity matrix in a recommender system? 【发布时间】:2012-07-10 21:23:08 【问题描述】:

我正在从用户评分数据(特别是 MovieLens100K 数据)生成用户-用户相似度矩阵。计算相关性会导致一些 NaN 值。我在一个较小的数据集中进行了测试:

用户-项目评分矩阵

   I1 I2 I3 I4
U1 4  0  5  5  
U2 4  2  1  0  
U3 3  0  2  4  
U4 4  4  0  0  

用户-用户皮尔逊相关相似度矩阵

              U1        U2        U3       U4      U5
U1             1        -1         0      -nan  0.755929
U2            -1         1         1      -nan -0.327327
U3             0         1         1      -nan  0.654654
U4          -nan      -nan      -nan      -nan      -nan
U5      0.755929 -0.327327  0.654654      -nan         1

为了计算 pearson 相关性,仅考虑两个用户之间的关联项目。 (见Toward the Next Generation of Recommender Systems: A Survey of the State-of-the-Art and Possible Extensions, Gediminas Adomavicius, Alexander Tuzhilin

如何处理 NaN 值?

编辑 这是我在 R 中找到 pearson 相关性的代码。R 矩阵是用户项目评分矩阵。包含 1 到 5 级评分 0 表示未评分。 S 是用户-用户相关矩阵。

  for (i in 1:nrow (R))
  
    cat ("user: ", i, "\n");
    for (k in 1:nrow (R))
    
      if (i != k)
      
        corated_list <- which (((R[i,] != 0) & (R[k,] != 0)) == TRUE);
        ui <- (R[i,corated_list] - mean (R[i,corated_list]));
        uk <- (R[k,corated_list] - mean (R[k,corated_list]));
        temp <- sum (ui * uk) / sqrt (sum (ui^2) * sum (uk^2));
        S[i,k] <- ifelse (is.nan (temp), 0, temp)
      
      else
      
        S[i,k] <- 0;
      
    
  

请注意,在S[i,k] &lt;- ifelse (is.nan (temp), 0, temp) 行中,我将NaNs 替换为0。

【问题讨论】:

句柄到底是什么意思?您可以将它们设为 0。 目前我将它们设为零,但我为什么要这样做? 理论上 nan 会建议您与另一个数据点没有关系。但是,在查看您的虚拟数据时,大多数 NaN 都有某种形式的关系。您是否使用了正确的数据类型?你能贴一些代码吗 是的,我已经发布了代码。我出于某些目的将任何代码移植到 C++,但这里是原型 R 代码。 没有 R 专家,但 cor(u1,u2) 不返回你的 pearsons 吗? 【参考方案1】:

我最近为用户-用户和用户-项目矩阵开发了一个 Java 推荐系统。首先,您可能已经发现。 RS很难。对于我的实现,我使用了很棒的 Apache Common Math Library,您使用的是 R,它在计算 Pearson 的方式上可能相对相似。

您的问题是:我如何处理 NaN 值,然后编辑说您说 NaN 是 = 0。

我的回答是这样的:

您不应该真正将 NaN 值处理为 0,因为您的意思是用户或用户/项目之间绝对没有相关性。 可能是这种情况,但可能并非总是如此。忽略这一点影响您的建议。

首先你应该问自己,“为什么我得到 NaN 值”?以下是 NaN 的 Wiki 页面中的一些原因,详细说明了您可能获得 NaN 值的原因:

可以返回NaN的操作有3种:

    以 NaN 作为至少一个操作数的操作。

    不确定的形式 分割 0/0 和 ±∞/±∞ 乘法 0×±∞ 和 ±∞×0 加法 ∞ + (−∞)、(−∞) + ∞ 和等效减法 该标准具有权力的替代功能: 标准 pow 函数和整数指数 pown 函数将 00、1∞ 和 ∞0 定义为 1。 powr 函数将所有三种不确定形式定义为无效操作,因此返回 NaN。

    具有复杂结果的实际操作,例如: 负数的平方根。 负数的对数 小于 -1 或大于 +1 的数的反正弦或余弦。

您应该调试您的应用程序并逐步完成每个步骤,以查看上述哪个原因是有问题的原因。

其次,了解 Pearsons 相关可以用多种不同的方式表示,您需要考虑是跨样本还是总体计算它,然后找到合适的计算方法,即针对总体:

cor(X, Y) = Σ[(xi - E(X))(yi - E(Y))] / [(n - 1)s(X)s(Y)]

其中 E(X) 是 X 的平均值, E(Y) 是 Y 值的平均值,并且 s(X), s(Y) 是标准差,并且 标准差通常是方差的正平方根,并且 方差 = sum((x_i - mean)^2) / (n - 1)

其中mean是平均值,并且 n 是样本观测的数量。

这可能是您的 NaN 出现的地方,即除以 0 表示未评级。如果可以的话,我建议不要使用 0 的值来表示未评级,而是使用 null。我会这样做有两个原因: 1. 0 可能是用 NaN 弄乱你的结果的原因,并且 2. 可读性/可理解性。你的 Scale 是 1 - 5,所以 0 不应该是特征,会混淆事物。所以尽可能避免这种情况。

第三,从推荐人的角度,从推荐的角度思考问题。如果您有 2 个用户并且他们只有 1 个共同评分,请在较小的数据集中为 I1 说 U1 和 U4。那一项共同点真的足以提供建议吗?答案是——当然不是。那么我也可以建议你设置一个最低的 ratingInCommon 阈值,以确保推荐的质量更好。您可以为此阈值设置的最小值为 2,但请考虑将其设置得更高一些。如果您阅读了 MovieLens 的研究,那么他们将其设置为 5-10 之间(不记得我的头顶)。您设置得越高,您获得的覆盖率就越低,但您将获得“更好”(错误分数越低)的建议。您可能已经阅读了学术文献,那么您可能已经掌握了这一点,但我想我还是会提到它。

关于以上几点。查看 U4 并与其他用户进行比较。请注意 U4 如何与任何用户没有超过 1 项的共同点。现在希望您会注意到 NaN 仅出现在 U4 中。如果您遵循了这个答案,那么您现在希望看到您获得 NaN 的原因是因为您实际上可以只用一个共同的项目来计算 Pearson 的 :)。

关于上面的示例数据集,最后一点让我有点困扰的是 1 和 -1 的相关性数量。想一想这些用户偏好的实际含义,然后根据实际评级检查它们。例如。查看 U1 和 U2 评级。对于项目 1,它们具有很强的正相关性 1(都将其评为 4)然后对于项目 3,它们具有很强的负相关性(U1 将其评为 5,U3 将其评为 1),这两个用户之间的 Pearson 相关性似乎很奇怪 - 1(即他们的偏好完全相反)。显然情况并非如此,Pearson 分数确实应该略高于或略低于 0。这个问题链接回关于在量表上使用 0 以及仅比较少量项目的点。

现在,有一些策略可以“填写”用户未评分的项目。我不打算深入他们,你需要阅读它,但本质上它就像使用该项目的平均分数或该用户的平均评分。这两种方法都有其缺点,我个人真的不喜欢其中任何一种。我的建议是仅在用户有 5 个或更多共同项目时计算用户之间的 Pearson 相关性,并忽略评分为 0(或更好 - 空)评分的项目。

所以总结一下。

    NaN 不等于 0,因此不要将其设置为 0。 您的量表中的 0 最好表示为 null 仅当两个用户之间的共同项目数大于 1(最好大于 5/10)时,才应计算 Pearson 相关性。 仅计算两个用户共同评分项目的 Pearson 相关性,不要将其他用户未评分的项目包括在分数中。

希望对您有所帮助,祝您好运。

【讨论】:

以上是关于在推荐系统的皮尔逊相关用户-用户相似度矩阵中,NaN 是如何处理的?的主要内容,如果未能解决你的问题,请参考以下文章

一文带你了解推荐系统常用模型及框架

协同过滤推荐算法

推荐系统_基本知识点-牢记

求问:余弦相似度和皮尔逊相关系数的区别

推荐系统⚠️手把手带你学推荐系统 1⚠️ 简介

胡扯推荐算法(协同)及其dome实现